From 7a0f1907af8c5c3f55f95d2e8d0d631aca0c1ed7 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Tue, 8 Dec 2020 14:02:09 +1100 Subject: [PATCH 01/61] WIP transition to cgltf. --- .gitmodules | 3 + CMakeLists.txt | 1 + Cesium3DTiles/CMakeLists.txt | 2 +- .../Cesium3DTiles/TileContentLoadResult.h | 4 +- Cesium3DTiles/src/GltfContent.cpp | 31 ++-- CesiumGltf/CMakeLists.txt | 26 ++++ CesiumGltf/include/CesiumGltf/CgltfMapping.h | 63 ++++++++ CesiumGltf/include/CesiumGltf/GltfAccessor.h | 15 ++ CesiumGltf/include/CesiumGltf/GltfAnimation.h | 15 ++ CesiumGltf/include/CesiumGltf/GltfBuffer.h | 26 ++++ .../include/CesiumGltf/GltfBufferView.h | 15 ++ .../include/CesiumGltf/GltfCollection.h | 134 ++++++++++++++++++ CesiumGltf/include/CesiumGltf/GltfImage.h | 15 ++ CesiumGltf/include/CesiumGltf/GltfMaterial.h | 15 ++ CesiumGltf/include/CesiumGltf/GltfMesh.h | 15 ++ CesiumGltf/include/CesiumGltf/GltfModel.h | 50 +++++++ CesiumGltf/include/CesiumGltf/GltfNode.h | 15 ++ CesiumGltf/include/CesiumGltf/GltfSampler.h | 15 ++ CesiumGltf/include/CesiumGltf/GltfScene.h | 15 ++ CesiumGltf/include/CesiumGltf/GltfTexture.h | 15 ++ CesiumGltf/src/GltfAccessor.cpp | 13 ++ CesiumGltf/src/GltfBuffer.cpp | 42 ++++++ CesiumGltf/src/GltfMesh.cpp | 13 ++ CesiumGltf/src/GltfModel.cpp | 78 ++++++++++ CesiumGltf/src/cgltf.cpp | 3 + CesiumGltf/test/TestGltfModel.cpp | 17 +++ extern/cgltf | 1 + 27 files changed, 642 insertions(+), 15 deletions(-) create mode 100644 CesiumGltf/CMakeLists.txt create mode 100644 CesiumGltf/include/CesiumGltf/CgltfMapping.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfAccessor.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfAnimation.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfBuffer.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfBufferView.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfCollection.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfImage.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfMaterial.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfMesh.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfModel.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfNode.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfSampler.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfScene.h create mode 100644 CesiumGltf/include/CesiumGltf/GltfTexture.h create mode 100644 CesiumGltf/src/GltfAccessor.cpp create mode 100644 CesiumGltf/src/GltfBuffer.cpp create mode 100644 CesiumGltf/src/GltfMesh.cpp create mode 100644 CesiumGltf/src/GltfModel.cpp create mode 100644 CesiumGltf/src/cgltf.cpp create mode 100644 CesiumGltf/test/TestGltfModel.cpp create mode 160000 extern/cgltf diff --git a/.gitmodules b/.gitmodules index caba16167..54424ccd7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "extern/asyncplusplus"] path = extern/asyncplusplus url = https://github.com/Amanieu/asyncplusplus.git +[submodule "extern/cgltf"] + path = extern/cgltf + url = https://github.com/jkuhlmann/cgltf.git diff --git a/CMakeLists.txt b/CMakeLists.txt index e82bdbc01..b657fa738 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ target_link_libraries(cesium-native-tests PUBLIC Catch2::Catch2) add_subdirectory(CesiumUtility) add_subdirectory(CesiumGeometry) add_subdirectory(CesiumGeospatial) +add_subdirectory(CesiumGltf) add_subdirectory(CesiumAsync) add_subdirectory(Cesium3DTiles) diff --git a/Cesium3DTiles/CMakeLists.txt b/Cesium3DTiles/CMakeLists.txt index 92f2a3d3d..c9df27cdc 100644 --- a/Cesium3DTiles/CMakeLists.txt +++ b/Cesium3DTiles/CMakeLists.txt @@ -28,4 +28,4 @@ target_include_directories( src ) -target_link_libraries(Cesium3DTiles PUBLIC CesiumAsync CesiumGeospatial CesiumGeometry CesiumUtility uriparser draco tinyxml2) +target_link_libraries(Cesium3DTiles PUBLIC CesiumAsync CesiumGeospatial CesiumGeometry CesiumGltf CesiumUtility uriparser draco tinyxml2) diff --git a/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h b/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h index 6626ba3bb..ab0280d36 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h +++ b/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h @@ -1,9 +1,9 @@ #pragma once -#include "Cesium3DTiles/Gltf.h" #include "Cesium3DTiles/Tile.h" #include "Cesium3DTiles/TileContext.h" #include "CesiumGeometry/QuadtreeTileRectangularRange.h" +#include "CesiumGltf/GltfModel.h" namespace Cesium3DTiles { @@ -30,7 +30,7 @@ namespace Cesium3DTiles { * If it has a value but the model is blank, the tile can * be "rendered", but it is rendered as nothing. */ - std::optional model; + std::optional model; /** * @brief A new context, if any, used by the `childTiles`. diff --git a/Cesium3DTiles/src/GltfContent.cpp b/Cesium3DTiles/src/GltfContent.cpp index 036e873ae..833e425f0 100644 --- a/Cesium3DTiles/src/GltfContent.cpp +++ b/Cesium3DTiles/src/GltfContent.cpp @@ -4,6 +4,8 @@ #include "CesiumUtility/Math.h" #include +using namespace CesiumGltf; + namespace Cesium3DTiles { /*static*/ std::unique_ptr GltfContent::load( @@ -22,15 +24,17 @@ namespace Cesium3DTiles { std::string errors; std::string warnings; - tinygltf::TinyGLTF loader; - pResult->model.emplace(); - loader.LoadBinaryFromMemory(&pResult->model.value(), &errors, &warnings, data.data(), static_cast(data.size())); + try { + pResult->model = GltfModel::fromMemory(data); + } catch (std::exception& /*e*/) { + // TODO: log glTF error + } return pResult; } static int generateOverlayTextureCoordinates( - tinygltf::Model& gltf, + GltfModel& gltf, int positionAccessorIndex, const glm::dmat4x4& transform, const CesiumGeospatial::Projection& projection, @@ -42,19 +46,22 @@ namespace Cesium3DTiles { double& minimumHeight, double& maximumHeight ) { - int uvBufferId = static_cast(gltf.buffers.size()); - gltf.buffers.emplace_back(); + GltfCollection buffers = gltf.buffers(); + GltfCollection bufferViews = gltf.bufferViews(); + GltfCollection accessors = gltf.accessors(); + + size_t uvBufferId = buffers.size(); + GltfBuffer uvBuffer = buffers.emplace_back(); - int uvBufferViewId = static_cast(gltf.bufferViews.size()); - gltf.bufferViews.emplace_back(); + size_t uvBufferViewId = bufferViews.size(); + GltfBufferView uvBufferView = bufferViews.emplace_back(); - int uvAccessorId = static_cast(gltf.accessors.size()); - gltf.accessors.emplace_back(); + size_t uvAccessorId = accessors.size(); + CesiumGltf::GltfAccessor uvAccessor = accessors.emplace_back(); GltfAccessor positionAccessor(gltf, static_cast(positionAccessorIndex)); - tinygltf::Buffer& uvBuffer = gltf.buffers[static_cast(uvBufferId)]; - uvBuffer.data.resize(positionAccessor.size() * 2 * sizeof(float)); + uvBuffer.resizeData(positionAccessor.size() * 2 * sizeof(float)); tinygltf::BufferView& uvBufferView = gltf.bufferViews[static_cast(uvBufferViewId)]; uvBufferView.buffer = uvBufferId; diff --git a/CesiumGltf/CMakeLists.txt b/CesiumGltf/CMakeLists.txt new file mode 100644 index 000000000..8dc74cbab --- /dev/null +++ b/CesiumGltf/CMakeLists.txt @@ -0,0 +1,26 @@ +add_library(CesiumGltf "") + +configure_cesium_library(CesiumGltf) + +file(GLOB SOURCES include/CesiumGltf/*.h src/*.cpp src/*.h) +file(GLOB PUBLIC_INCLUDES include/CesiumGltf/*.h) + +target_sources( + CesiumGltf + PRIVATE + ${SOURCES} + PUBLIC + ${PUBLIC_INCLUDES} +) + +target_include_directories( + CesiumGltf + PUBLIC + include + PRIVATE + src + SYSTEM PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../extern/cgltf +) + +target_link_libraries(CesiumGltf PUBLIC CesiumGeometry CesiumUtility) diff --git a/CesiumGltf/include/CesiumGltf/CgltfMapping.h b/CesiumGltf/include/CesiumGltf/CgltfMapping.h new file mode 100644 index 000000000..21c2ce114 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/CgltfMapping.h @@ -0,0 +1,63 @@ +#pragma once + +#include + +struct cgltf_accessor; +struct cgltf_animation; +struct cgltf_buffer; +struct cgltf_buffer_view; +struct cgltf_image; +struct cgltf_material; +struct cgltf_mesh; +struct cgltf_node; +struct cgltf_sampler; +struct cgltf_scene; +struct cgltf_texture; + +namespace CesiumGltf { + + class GltfAccessor; + class GltfAnimation; + class GltfBuffer; + class GltfBufferView; + class GltfImage; + class GltfMaterial; + class GltfMesh; + class GltfNode; + class GltfSampler; + class GltfScene; + class GltfTexture; + + namespace Impl { + template + struct CesiumToCgltf; + + template <> struct CesiumToCgltf { using cgltf_type = cgltf_accessor; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_animation; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_buffer; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_buffer_view; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_image; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_material; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_mesh; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_node; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_sampler; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_scene; }; + template <> struct CesiumToCgltf { using cgltf_type = cgltf_texture; }; + template <> struct CesiumToCgltf { using cgltf_type = char*; }; + + template + struct CesiumGltfObjectFactory { + static T createFromCollectionElement(typename CesiumToCgltf::cgltf_type* pElements, size_t currentElement) { + return T::createFromCollectionElement(pElements, currentElement); + } + }; + + template <> + struct CesiumGltfObjectFactory { + static std::string createFromCollectionElement(char** pElements, size_t currentElement) { + return std::string(pElements[currentElement]); + } + }; + } + +} diff --git a/CesiumGltf/include/CesiumGltf/GltfAccessor.h b/CesiumGltf/include/CesiumGltf/GltfAccessor.h new file mode 100644 index 000000000..9c4217e11 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfAccessor.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_accessor; + +namespace CesiumGltf { + class GltfAccessor { + public: + static GltfAccessor createFromCollectionElement(cgltf_accessor* array, size_t arrayIndex); + + private: + GltfAccessor(cgltf_accessor* p); + + cgltf_accessor* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfAnimation.h b/CesiumGltf/include/CesiumGltf/GltfAnimation.h new file mode 100644 index 000000000..fed80d0d5 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfAnimation.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_animation; + +namespace CesiumGltf { + class GltfAnimation { + public: + static GltfAnimation createFromCollectionElement(cgltf_animation* array, size_t arrayIndex); + + private: + GltfAnimation(cgltf_animation* p); + + cgltf_animation* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfBuffer.h b/CesiumGltf/include/CesiumGltf/GltfBuffer.h new file mode 100644 index 000000000..d90e9a227 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfBuffer.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +struct cgltf_buffer; + +namespace CesiumGltf { + class GltfBuffer { + public: + static GltfBuffer createFromCollectionElement(cgltf_buffer* array, size_t arrayIndex); + + std::string getUri() const noexcept; + void setUri(const std::string& value) noexcept; + + gsl::span getData() noexcept; + gsl::span getData() const noexcept; + void setData(const gsl::span& value) noexcept; + void resizeData(size_t newSize) noexcept; + + private: + GltfBuffer(cgltf_buffer* p); + + cgltf_buffer* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfBufferView.h b/CesiumGltf/include/CesiumGltf/GltfBufferView.h new file mode 100644 index 000000000..7d2418ccd --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfBufferView.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_buffer_view; + +namespace CesiumGltf { + class GltfBufferView { + public: + static GltfBufferView createFromCollectionElement(cgltf_buffer_view* array, size_t arrayIndex); + + private: + GltfBufferView(cgltf_buffer_view* p); + + cgltf_buffer_view* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfCollection.h b/CesiumGltf/include/CesiumGltf/GltfCollection.h new file mode 100644 index 000000000..07872577f --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfCollection.h @@ -0,0 +1,134 @@ +#pragma once + +#include "CesiumGltf/CgltfMapping.h" +#include +#include + +namespace CesiumGltf { + template + class GltfCollection { + public: + class const_iterator { + public: + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = int64_t; + using pointer = T*; + using reference = const value_type&; + + const_iterator(typename Impl::CesiumToCgltf::cgltf_type* pElements, size_t numberOfElements, size_t currentElement) noexcept : + _pElements(pElements), + _numberOfElements(numberOfElements), + _currentElement(currentElement), + _temporary() + { + } + + const T& operator*() const noexcept { + this->_fill(); + return this->_temporary.value(); + } + + const T* operator->() const { + this->_fill(); + return &this->_temporary.value(); + } + + const_iterator& operator++() noexcept { + ++this->_currentElement; + this->_temporary.reset(); + return *this; + } + + const_iterator operator++(int) noexcept { + const_iterator copy = *this; + ++*this; + this->_temporary.reset(); + return copy; + } + + bool operator==(const const_iterator& rhs) const noexcept { + return + this->_currentElement == rhs._currentElement && + this->_pElements == rhs._pElements; + } + + bool operator!=(const const_iterator& rhs) const noexcept { + return !(*this == rhs); + } + + private: + void _fill() const { + if (!this->_temporary) { + assert(this->_currentElement < this->_numberOfElements); + this->_temporary = Impl::CesiumGltfObjectFactory::createFromCollectionElement(this->_pElements, this->_currentElement); + } + } + + typename Impl::CesiumToCgltf::cgltf_type* _pElements; + size_t _numberOfElements; + size_t _currentElement; + mutable std::optional _temporary; + }; + + GltfCollection(typename Impl::CesiumToCgltf::cgltf_type** ppElements, size_t* pNumberOfElements) : + _ppElements(ppElements), + _pNumberOfElements(pNumberOfElements) + { + } + + using value_type = T; + + size_t size() const noexcept { + return *this->_pNumberOfElements; + } + + const_iterator begin() noexcept { + return { + *this->_ppElements, + *this->_pNumberOfElements, + 0 + }; + } + + const_iterator end() noexcept { + return { + *this->_ppElements, + *this->_pNumberOfElements, + *this->_pNumberOfElements + }; + } + + T operator[](size_t index) const noexcept { + return Impl::CesiumGltfObjectFactory::createFromCollectionElement(*this->_ppElements, index); + } + + void push_back(const T& item) { + size_t newNumberOfElements = *this->_pNumberOfElements + 1; + *this->_ppElements = realloc(*this->_ppElements, newNumberOfElements * sizeof(Impl::CesiumToCgltf::cgltf_type)); + (*this->_ppElements)[*this->_pNumberOfElements] = item; + *this->_pNumberOfElements = newNumberOfElements; + } + + void push_back(T&& item) { + size_t newNumberOfElements = *this->_pNumberOfElements + 1; + *this->_ppElements = realloc(*this->_ppElements, newNumberOfElements * sizeof(Impl::CesiumToCgltf::cgltf_type)); + (*this->_ppElements)[*this->_pNumberOfElements] = std::move(item); + *this->_pNumberOfElements = newNumberOfElements; + } + + T emplace_back() { + size_t oldNumberOfElements = *this->_pNumberOfElements; + size_t newNumberOfElements = oldNumberOfElements + 1; + *this->_ppElements = realloc(*this->_ppElements, newNumberOfElements * sizeof(Impl::CesiumToCgltf::cgltf_type)); + (*this->_ppElements)[oldNumberOfElements] = Impl::CesiumToCgltf::cgltf_type(); + *this->_pNumberOfElements = newNumberOfElements; + return this->operator[](oldNumberOfElements); + } + + private: + typename Impl::CesiumToCgltf::cgltf_type** _ppElements; + size_t* _pNumberOfElements; + }; + +} diff --git a/CesiumGltf/include/CesiumGltf/GltfImage.h b/CesiumGltf/include/CesiumGltf/GltfImage.h new file mode 100644 index 000000000..5a10d5343 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfImage.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_image; + +namespace CesiumGltf { + class GltfImage { + public: + static GltfImage createFromCollectionElement(cgltf_image* array, size_t arrayIndex); + + private: + GltfImage(cgltf_image* p); + + cgltf_image* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfMaterial.h b/CesiumGltf/include/CesiumGltf/GltfMaterial.h new file mode 100644 index 000000000..cf61505d9 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfMaterial.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_material; + +namespace CesiumGltf { + class GltfMaterial { + public: + static GltfMaterial createFromCollectionElement(cgltf_material* array, size_t arrayIndex); + + private: + GltfMaterial(cgltf_material* p); + + cgltf_material* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfMesh.h b/CesiumGltf/include/CesiumGltf/GltfMesh.h new file mode 100644 index 000000000..80fc0c55b --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfMesh.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_mesh; + +namespace CesiumGltf { + class GltfMesh { + public: + static GltfMesh createFromCollectionElement(cgltf_mesh* array, size_t arrayIndex); + + private: + GltfMesh(cgltf_mesh* p); + + cgltf_mesh* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfModel.h b/CesiumGltf/include/CesiumGltf/GltfModel.h new file mode 100644 index 000000000..d10505ede --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfModel.h @@ -0,0 +1,50 @@ +#pragma once + +#include "CesiumGltf/GltfCollection.h" +#include "CesiumGltf/GltfAccessor.h" +#include "CesiumGltf/GltfAnimation.h" +#include "CesiumGltf/GltfBuffer.h" +#include "CesiumGltf/GltfBufferView.h" +#include "CesiumGltf/GltfImage.h" +#include "CesiumGltf/GltfMaterial.h" +#include "CesiumGltf/GltfMesh.h" +#include "CesiumGltf/GltfNode.h" +#include "CesiumGltf/GltfSampler.h" +#include "CesiumGltf/GltfScene.h" +#include "CesiumGltf/GltfTexture.h" +#include +#include +#include + +struct cgltf_data; + +namespace CesiumGltf { + class GltfModel { + public: + static GltfModel fromMemory(gsl::span pData); + + GltfCollection extensionsUsed() const noexcept; + GltfCollection extensionsRequired() const noexcept; + GltfCollection accessors() const noexcept; + GltfCollection animations() const noexcept; + // GltfAsset asset() const noexcept; + GltfCollection buffers() const noexcept; + GltfCollection bufferViews() const noexcept; + // GltfCollection cameras() const noexcept; + GltfCollection images() const noexcept; + GltfCollection materials() const noexcept; + GltfCollection meshes() const noexcept; + GltfCollection nodes() const noexcept; + GltfCollection samplers() const noexcept; + // size_t scene() const noexcept; + GltfCollection scenes() const noexcept; + // GltfCollection skins() const noexcept; + GltfCollection textures() const noexcept; + + private: + GltfModel(cgltf_data* pData); + + std::unique_ptr _pData; + }; + +} diff --git a/CesiumGltf/include/CesiumGltf/GltfNode.h b/CesiumGltf/include/CesiumGltf/GltfNode.h new file mode 100644 index 000000000..5a496b333 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfNode.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_node; + +namespace CesiumGltf { + class GltfNode { + public: + static GltfNode createFromCollectionElement(cgltf_node* array, size_t arrayIndex); + + private: + GltfNode(cgltf_node* p); + + cgltf_node* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfSampler.h b/CesiumGltf/include/CesiumGltf/GltfSampler.h new file mode 100644 index 000000000..8e224f4a7 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfSampler.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_sampler; + +namespace CesiumGltf { + class GltfSampler { + public: + static GltfSampler createFromCollectionElement(cgltf_sampler* array, size_t arrayIndex); + + private: + GltfSampler(cgltf_sampler* p); + + cgltf_sampler* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfScene.h b/CesiumGltf/include/CesiumGltf/GltfScene.h new file mode 100644 index 000000000..860d9915d --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfScene.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_scene; + +namespace CesiumGltf { + class GltfScene { + public: + static GltfScene createFromCollectionElement(cgltf_scene* array, size_t arrayIndex); + + private: + GltfScene(cgltf_scene* p); + + cgltf_scene* _p; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfTexture.h b/CesiumGltf/include/CesiumGltf/GltfTexture.h new file mode 100644 index 000000000..cc828739a --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/GltfTexture.h @@ -0,0 +1,15 @@ +#pragma once + +struct cgltf_texture; + +namespace CesiumGltf { + class GltfTexture { + public: + static GltfTexture createFromCollectionElement(cgltf_texture* array, size_t arrayIndex); + + private: + GltfTexture(cgltf_texture* p); + + cgltf_texture* _p; + }; +} diff --git a/CesiumGltf/src/GltfAccessor.cpp b/CesiumGltf/src/GltfAccessor.cpp new file mode 100644 index 000000000..710090ce2 --- /dev/null +++ b/CesiumGltf/src/GltfAccessor.cpp @@ -0,0 +1,13 @@ +#include "CesiumGltf/GltfAccessor.h" +#include + +namespace CesiumGltf { + /*static*/ GltfAccessor GltfAccessor::createFromCollectionElement(cgltf_accessor* array, size_t arrayIndex) { + return GltfAccessor(&array[arrayIndex]); + } + + GltfAccessor::GltfAccessor(cgltf_accessor* p) : + _p(p) + { + } +} diff --git a/CesiumGltf/src/GltfBuffer.cpp b/CesiumGltf/src/GltfBuffer.cpp new file mode 100644 index 000000000..2ae76aebd --- /dev/null +++ b/CesiumGltf/src/GltfBuffer.cpp @@ -0,0 +1,42 @@ +#include "CesiumGltf/GltfBuffer.h" +#include +#include + +namespace CesiumGltf { + /*static*/ GltfBuffer GltfBuffer::createFromCollectionElement(cgltf_buffer* array, size_t arrayIndex) { + return GltfBuffer(&array[arrayIndex]); + } + + GltfBuffer::GltfBuffer(cgltf_buffer* p) : + _p(p) + { + } + + std::string GltfBuffer::getUri() const noexcept { + return this->_p->uri; + } + + void GltfBuffer::setUri(const std::string& value) noexcept { + this->_p->uri = static_cast(realloc(this->_p->uri, value.size() + 1)); + value.copy(this->_p->uri, value.size(), 0); + this->_p->uri[value.size()] = '\0'; + } + + gsl::span GltfBuffer::getData() const noexcept { + return gsl::span(static_cast(this->_p->data), this->_p->size); + } + + gsl::span GltfBuffer::getData() noexcept { + return gsl::span(static_cast(this->_p->data), this->_p->size); + } + + void GltfBuffer::setData(const gsl::span& value) noexcept { + this->_p->data = realloc(this->_p->data, value.size()); + std::copy(value.begin(), value.end(), static_cast(this->_p->data)); + } + + void GltfBuffer::resizeData(size_t newSize) noexcept { + this->_p->data = realloc(this->_p->data, newSize); + } + +} diff --git a/CesiumGltf/src/GltfMesh.cpp b/CesiumGltf/src/GltfMesh.cpp new file mode 100644 index 000000000..467519b94 --- /dev/null +++ b/CesiumGltf/src/GltfMesh.cpp @@ -0,0 +1,13 @@ +#include "CesiumGltf/GltfMesh.h" +#include + +namespace CesiumGltf { + /*static*/ GltfMesh GltfMesh::createFromCollectionElement(cgltf_mesh* array, size_t arrayIndex) { + return GltfMesh(&array[arrayIndex]); + } + + GltfMesh::GltfMesh(cgltf_mesh* p) : + _p(p) + { + } +} diff --git a/CesiumGltf/src/GltfModel.cpp b/CesiumGltf/src/GltfModel.cpp new file mode 100644 index 000000000..962868293 --- /dev/null +++ b/CesiumGltf/src/GltfModel.cpp @@ -0,0 +1,78 @@ +#include "CesiumGltf/GltfModel.h" +#include "CesiumGltf/GltfMesh.h" +#include +#include + +namespace CesiumGltf { + + /*static*/ GltfModel GltfModel::fromMemory(gsl::span data) { + cgltf_options options{}; + cgltf_data* pResult = nullptr; + cgltf_result resultCode = cgltf_parse(&options, data.data(), data.size(), &pResult); + if (resultCode == cgltf_result_success) { + return GltfModel(pResult); + } else { + switch (resultCode) { + case cgltf_result_data_too_short: + throw std::runtime_error("glTF data is too short."); + case cgltf_result_unknown_format: + throw std::runtime_error("glTF is in an unknown format."); + case cgltf_result_invalid_json: + throw std::runtime_error("glTF JSON is invalid."); + case cgltf_result_invalid_gltf: + throw std::runtime_error("glTF is invalid."); + case cgltf_result_invalid_options: + throw std::runtime_error("glTF parsed with invalid options."); + case cgltf_result_file_not_found: + throw std::runtime_error("glTF file was not found."); + case cgltf_result_io_error: + throw std::runtime_error("I/O error while parsing glTF."); + case cgltf_result_out_of_memory: + throw std::runtime_error("Out of memory while parsing glTF."); + case cgltf_result_legacy_gltf: + throw std::runtime_error("glTF uses an unsupported legacy format."); + default: + throw std::runtime_error("An unknown error occurred while parsing a glTF."); + } + } + } + + // cgltf_asset asset; + + // cgltf_mesh* meshes; + // cgltf_material* materials; + // cgltf_accessor* accessors; + // cgltf_buffer_view* buffer_views; + // cgltf_buffer* buffers; + // cgltf_image* images; + // cgltf_texture* textures; + // cgltf_sampler* samplers; + // cgltf_skin* skins; + // cgltf_camera* cameras; + // cgltf_light* lights; + // cgltf_node* nodes; + // cgltf_scene* scenes; + // cgltf_scene* scene; + // cgltf_animation* animations; + + GltfCollection GltfModel::extensionsUsed() const noexcept { + return { &this->_pData->extensions_used, &this->_pData->extensions_used_count }; + } + + GltfCollection GltfModel::extensionsRequired() const noexcept { + return { &this->_pData->extensions_required, &this->_pData->extensions_required_count }; + } + + GltfCollection GltfModel::meshes() const noexcept { + return { &this->_pData->meshes, &this->_pData->meshes_count }; + } + + GltfCollection GltfModel::accessors() const noexcept { + return { &this->_pData->accessors, &this->_pData->accessors_count }; + } + + GltfModel::GltfModel(cgltf_data* pData) : + _pData(pData, cgltf_free) + { + } +} diff --git a/CesiumGltf/src/cgltf.cpp b/CesiumGltf/src/cgltf.cpp new file mode 100644 index 000000000..b0133d63b --- /dev/null +++ b/CesiumGltf/src/cgltf.cpp @@ -0,0 +1,3 @@ +#define CGLTF_IMPLEMENTATION +#pragma warning(disable:4996) +#include diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp new file mode 100644 index 000000000..ba6d41682 --- /dev/null +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -0,0 +1,17 @@ +#include "catch2/catch.hpp" +#include "CesiumGltf/GltfModel.h" + +using namespace CesiumGltf; + +TEST_CASE("GltfModel") { + std::vector v; + GltfModel model = GltfModel::fromMemory(v); + GltfCollection meshes = model.meshes(); + for (const GltfMesh& mesh : meshes) { + mesh; + } + + for (const std::string& s : model.extensionsUsed()) { + s; + } +} \ No newline at end of file diff --git a/extern/cgltf b/extern/cgltf new file mode 160000 index 000000000..c878edca3 --- /dev/null +++ b/extern/cgltf @@ -0,0 +1 @@ +Subproject commit c878edca3c025784ae103e1faadd4d1432dcd367 From 6cb6cddac0607993ae42f497a68ae3401ef40328 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Sat, 19 Dec 2020 22:26:09 +1100 Subject: [PATCH 02/61] Add simdjson. --- .gitmodules | 3 +++ CesiumGltf/CMakeLists.txt | 2 +- extern/CMakeLists.txt | 2 ++ extern/simdjson | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) create mode 160000 extern/simdjson diff --git a/.gitmodules b/.gitmodules index 54424ccd7..9e131ac74 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ [submodule "extern/cgltf"] path = extern/cgltf url = https://github.com/jkuhlmann/cgltf.git +[submodule "extern/simdjson"] + path = extern/simdjson + url = https://github.com/simdjson/simdjson.git diff --git a/CesiumGltf/CMakeLists.txt b/CesiumGltf/CMakeLists.txt index 8dc74cbab..56103ef65 100644 --- a/CesiumGltf/CMakeLists.txt +++ b/CesiumGltf/CMakeLists.txt @@ -23,4 +23,4 @@ target_include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../extern/cgltf ) -target_link_libraries(CesiumGltf PUBLIC CesiumGeometry CesiumUtility) +target_link_libraries(CesiumGltf PUBLIC CesiumGeometry CesiumUtility simdjson) diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 10ea85661..5ad8ef5cd 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -16,3 +16,5 @@ set(BUILD_TESTS OFF CACHE BOOL "Build tinyxml2 tests" FORCE) add_subdirectory(tinyxml2) add_subdirectory(asyncplusplus) + +add_subdirectory(simdjson) diff --git a/extern/simdjson b/extern/simdjson new file mode 160000 index 000000000..f785f76d9 --- /dev/null +++ b/extern/simdjson @@ -0,0 +1 @@ +Subproject commit f785f76d983d778befbed3730c3e7d0c3a6983de From 72b07bc8d2f7a7cab3ed42e1c9249223dfbaa18b Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 23 Dec 2020 21:23:53 +1100 Subject: [PATCH 03/61] WIP glTF wrapper --- CesiumGltf/CMakeLists.txt | 3 + CesiumGltf/include/CesiumGltf/CgltfMapping.h | 63 ---------------- CesiumGltf/include/CesiumGltf/GltfAccessor.h | 22 ++++-- .../include/CesiumGltf/GltfCollection.h | 46 +++++------- CesiumGltf/include/CesiumGltf/GltfModel.h | 9 +-- .../include/CesiumGltf/TinyGltfMapping.h | 71 +++++++++++++++++++ CesiumGltf/src/GltfAccessor.cpp | 28 ++++++-- CesiumGltf/src/GltfModel.cpp | 65 +++++++++-------- CesiumGltf/src/cgltf.cpp | 3 - 9 files changed, 170 insertions(+), 140 deletions(-) delete mode 100644 CesiumGltf/include/CesiumGltf/CgltfMapping.h create mode 100644 CesiumGltf/include/CesiumGltf/TinyGltfMapping.h delete mode 100644 CesiumGltf/src/cgltf.cpp diff --git a/CesiumGltf/CMakeLists.txt b/CesiumGltf/CMakeLists.txt index 56103ef65..72c822a67 100644 --- a/CesiumGltf/CMakeLists.txt +++ b/CesiumGltf/CMakeLists.txt @@ -15,6 +15,9 @@ target_sources( target_include_directories( CesiumGltf + SYSTEM PUBLIC + # We're not using CMake for tinygltf at all, but it's header only. Add its headers here. + ${CMAKE_CURRENT_SOURCE_DIR}/../extern/tinygltf PUBLIC include PRIVATE diff --git a/CesiumGltf/include/CesiumGltf/CgltfMapping.h b/CesiumGltf/include/CesiumGltf/CgltfMapping.h deleted file mode 100644 index 21c2ce114..000000000 --- a/CesiumGltf/include/CesiumGltf/CgltfMapping.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include - -struct cgltf_accessor; -struct cgltf_animation; -struct cgltf_buffer; -struct cgltf_buffer_view; -struct cgltf_image; -struct cgltf_material; -struct cgltf_mesh; -struct cgltf_node; -struct cgltf_sampler; -struct cgltf_scene; -struct cgltf_texture; - -namespace CesiumGltf { - - class GltfAccessor; - class GltfAnimation; - class GltfBuffer; - class GltfBufferView; - class GltfImage; - class GltfMaterial; - class GltfMesh; - class GltfNode; - class GltfSampler; - class GltfScene; - class GltfTexture; - - namespace Impl { - template - struct CesiumToCgltf; - - template <> struct CesiumToCgltf { using cgltf_type = cgltf_accessor; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_animation; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_buffer; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_buffer_view; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_image; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_material; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_mesh; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_node; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_sampler; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_scene; }; - template <> struct CesiumToCgltf { using cgltf_type = cgltf_texture; }; - template <> struct CesiumToCgltf { using cgltf_type = char*; }; - - template - struct CesiumGltfObjectFactory { - static T createFromCollectionElement(typename CesiumToCgltf::cgltf_type* pElements, size_t currentElement) { - return T::createFromCollectionElement(pElements, currentElement); - } - }; - - template <> - struct CesiumGltfObjectFactory { - static std::string createFromCollectionElement(char** pElements, size_t currentElement) { - return std::string(pElements[currentElement]); - } - }; - } - -} diff --git a/CesiumGltf/include/CesiumGltf/GltfAccessor.h b/CesiumGltf/include/CesiumGltf/GltfAccessor.h index 9c4217e11..0800faea3 100644 --- a/CesiumGltf/include/CesiumGltf/GltfAccessor.h +++ b/CesiumGltf/include/CesiumGltf/GltfAccessor.h @@ -1,15 +1,27 @@ #pragma once -struct cgltf_accessor; +namespace tinygltf { + struct Accessor; +} namespace CesiumGltf { - class GltfAccessor { + template + class GltfCollection; + + class GltfAccessor final { public: - static GltfAccessor createFromCollectionElement(cgltf_accessor* array, size_t arrayIndex); + GltfAccessor(); + ~GltfAccessor(); private: - GltfAccessor(cgltf_accessor* p); + using tinygltf_type = tinygltf::Accessor; + + GltfAccessor(tinygltf::Accessor* p); + + tinygltf::Accessor* _p; + bool _owns; - cgltf_accessor* _p; + template + friend class GltfCollection; }; } diff --git a/CesiumGltf/include/CesiumGltf/GltfCollection.h b/CesiumGltf/include/CesiumGltf/GltfCollection.h index 07872577f..6a2bbda83 100644 --- a/CesiumGltf/include/CesiumGltf/GltfCollection.h +++ b/CesiumGltf/include/CesiumGltf/GltfCollection.h @@ -1,8 +1,9 @@ #pragma once -#include "CesiumGltf/CgltfMapping.h" +#include "CesiumGltf/TinyGltfMapping.h" #include #include +#include namespace CesiumGltf { template @@ -16,7 +17,7 @@ namespace CesiumGltf { using pointer = T*; using reference = const value_type&; - const_iterator(typename Impl::CesiumToCgltf::cgltf_type* pElements, size_t numberOfElements, size_t currentElement) noexcept : + const_iterator(typename Impl::CesiumToTinyGltf::tinygltf_type* pElements, size_t numberOfElements, size_t currentElement) noexcept : _pElements(pElements), _numberOfElements(numberOfElements), _currentElement(currentElement), @@ -65,70 +66,55 @@ namespace CesiumGltf { } } - typename Impl::CesiumToCgltf::cgltf_type* _pElements; - size_t _numberOfElements; + std::vector::tinygltf_type>* _pElements; size_t _currentElement; mutable std::optional _temporary; }; - GltfCollection(typename Impl::CesiumToCgltf::cgltf_type** ppElements, size_t* pNumberOfElements) : - _ppElements(ppElements), - _pNumberOfElements(pNumberOfElements) + GltfCollection(std::vector::tinygltf_type>* pElements) : + _pElements(ppElements) { } using value_type = T; size_t size() const noexcept { - return *this->_pNumberOfElements; + return this->_pElements->size(); } const_iterator begin() noexcept { return { - *this->_ppElements, - *this->_pNumberOfElements, + this->_pElements, 0 }; } const_iterator end() noexcept { return { - *this->_ppElements, - *this->_pNumberOfElements, - *this->_pNumberOfElements + this->_pElements, + this->_pElements->size() }; } T operator[](size_t index) const noexcept { - return Impl::CesiumGltfObjectFactory::createFromCollectionElement(*this->_ppElements, index); + return Impl::CesiumGltfObjectFactory::createFromCollectionElement(&this->_pElements[index]); } void push_back(const T& item) { - size_t newNumberOfElements = *this->_pNumberOfElements + 1; - *this->_ppElements = realloc(*this->_ppElements, newNumberOfElements * sizeof(Impl::CesiumToCgltf::cgltf_type)); - (*this->_ppElements)[*this->_pNumberOfElements] = item; - *this->_pNumberOfElements = newNumberOfElements; + this->_pElements->push_back(*item._p); } void push_back(T&& item) { - size_t newNumberOfElements = *this->_pNumberOfElements + 1; - *this->_ppElements = realloc(*this->_ppElements, newNumberOfElements * sizeof(Impl::CesiumToCgltf::cgltf_type)); - (*this->_ppElements)[*this->_pNumberOfElements] = std::move(item); - *this->_pNumberOfElements = newNumberOfElements; + this->_pElements->push_back(std::move(*item._p)); } T emplace_back() { - size_t oldNumberOfElements = *this->_pNumberOfElements; - size_t newNumberOfElements = oldNumberOfElements + 1; - *this->_ppElements = realloc(*this->_ppElements, newNumberOfElements * sizeof(Impl::CesiumToCgltf::cgltf_type)); - (*this->_ppElements)[oldNumberOfElements] = Impl::CesiumToCgltf::cgltf_type(); - *this->_pNumberOfElements = newNumberOfElements; - return this->operator[](oldNumberOfElements); + return T(&this->_pElements->emplace_back()); } private: - typename Impl::CesiumToCgltf::cgltf_type** _ppElements; - size_t* _pNumberOfElements; + using tinygltf_type = typename Impl::CesiumToTinyGltf::tinygltf_type; + std::vector* _pElements; }; } diff --git a/CesiumGltf/include/CesiumGltf/GltfModel.h b/CesiumGltf/include/CesiumGltf/GltfModel.h index d10505ede..b6aec7548 100644 --- a/CesiumGltf/include/CesiumGltf/GltfModel.h +++ b/CesiumGltf/include/CesiumGltf/GltfModel.h @@ -15,14 +15,15 @@ #include #include #include - -struct cgltf_data; +#include namespace CesiumGltf { class GltfModel { public: static GltfModel fromMemory(gsl::span pData); + GltfModel(); + GltfCollection extensionsUsed() const noexcept; GltfCollection extensionsRequired() const noexcept; GltfCollection accessors() const noexcept; @@ -42,9 +43,9 @@ namespace CesiumGltf { GltfCollection textures() const noexcept; private: - GltfModel(cgltf_data* pData); + GltfModel(tinygltf::Model&& model); - std::unique_ptr _pData; + tinygltf::Model _model; }; } diff --git a/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h b/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h new file mode 100644 index 000000000..61036c5c6 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h @@ -0,0 +1,71 @@ +#pragma once + +#include + +// namespace tinygltf { +// struct Accessor; +// struct Animation; +// struct Buffer; +// struct BufferView; +// struct Image; +// struct Material; +// struct Mesh; +// struct Node; +// struct Sampler; +// struct Scene; +// struct Texture; +// } + +namespace CesiumGltf { + + class GltfAccessor; + class GltfAnimation; + class GltfBuffer; + class GltfBufferView; + class GltfImage; + class GltfMaterial; + class GltfMesh; + class GltfNode; + class GltfSampler; + class GltfScene; + class GltfTexture; + + namespace Impl { + template + struct CesiumToTinyGltf { + using tinygltf_type = typename T::tinygltf_type; + }; + + template <> + struct CesiumToTinyGltf { + using tinygltf_type = std::string; + }; + + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Accessor; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Animation; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Buffer; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::BufferView; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Image; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Material; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Mesh; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Node; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Sampler; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Scene; }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Texture; }; + + template + struct CesiumGltfObjectFactory { + static T createFromCollectionElement(typename T::tinygltf_type* pElement) { + return T(pElement); + } + }; + + template <> + struct CesiumGltfObjectFactory { + static std::string createFromCollectionElement(std::string* pElement) { + return *pElement; + } + }; + } + +} diff --git a/CesiumGltf/src/GltfAccessor.cpp b/CesiumGltf/src/GltfAccessor.cpp index 710090ce2..17ca02136 100644 --- a/CesiumGltf/src/GltfAccessor.cpp +++ b/CesiumGltf/src/GltfAccessor.cpp @@ -1,13 +1,31 @@ #include "CesiumGltf/GltfAccessor.h" -#include +#include namespace CesiumGltf { - /*static*/ GltfAccessor GltfAccessor::createFromCollectionElement(cgltf_accessor* array, size_t arrayIndex) { - return GltfAccessor(&array[arrayIndex]); + GltfAccessor::GltfAccessor() : + _p(new tinygltf_type()), + _owns(true) + { + } + + GltfAccessor::~GltfAccessor() { + if (this->_owns) { + delete this->_p; + } } - GltfAccessor::GltfAccessor(cgltf_accessor* p) : - _p(p) + // /*static*/ GltfAccessor GltfAccessor::createFromCollectionElement(cgltf_accessor* array, size_t arrayIndex) { + // return GltfAccessor(&array[arrayIndex]); + // } + + // GltfAccessor::GltfAccessor(cgltf_accessor* p) : + // _p(p) + // { + // } + + GltfAccessor::GltfAccessor(tinygltf::Accessor* p) : + _p(p), + _owns(false) { } } diff --git a/CesiumGltf/src/GltfModel.cpp b/CesiumGltf/src/GltfModel.cpp index 962868293..202fe4e99 100644 --- a/CesiumGltf/src/GltfModel.cpp +++ b/CesiumGltf/src/GltfModel.cpp @@ -1,40 +1,45 @@ #include "CesiumGltf/GltfModel.h" #include "CesiumGltf/GltfMesh.h" -#include #include namespace CesiumGltf { /*static*/ GltfModel GltfModel::fromMemory(gsl::span data) { - cgltf_options options{}; - cgltf_data* pResult = nullptr; - cgltf_result resultCode = cgltf_parse(&options, data.data(), data.size(), &pResult); - if (resultCode == cgltf_result_success) { - return GltfModel(pResult); - } else { - switch (resultCode) { - case cgltf_result_data_too_short: - throw std::runtime_error("glTF data is too short."); - case cgltf_result_unknown_format: - throw std::runtime_error("glTF is in an unknown format."); - case cgltf_result_invalid_json: - throw std::runtime_error("glTF JSON is invalid."); - case cgltf_result_invalid_gltf: - throw std::runtime_error("glTF is invalid."); - case cgltf_result_invalid_options: - throw std::runtime_error("glTF parsed with invalid options."); - case cgltf_result_file_not_found: - throw std::runtime_error("glTF file was not found."); - case cgltf_result_io_error: - throw std::runtime_error("I/O error while parsing glTF."); - case cgltf_result_out_of_memory: - throw std::runtime_error("Out of memory while parsing glTF."); - case cgltf_result_legacy_gltf: - throw std::runtime_error("glTF uses an unsupported legacy format."); - default: - throw std::runtime_error("An unknown error occurred while parsing a glTF."); - } - } + GltfModel result; + std::string warnings; + std::string errors; + tinygltf::TinyGLTF loader; + bool success = loader.LoadBinaryFromMemory(&result._model, &errors, &warnings, data.data(), static_cast(data.size())); + return result; + // cgltf_options options{}; + // cgltf_data* pResult = nullptr; + // cgltf_result resultCode = cgltf_parse(&options, data.data(), data.size(), &pResult); + // if (resultCode == cgltf_result_success) { + // return GltfModel(pResult); + // } else { + // switch (resultCode) { + // case cgltf_result_data_too_short: + // throw std::runtime_error("glTF data is too short."); + // case cgltf_result_unknown_format: + // throw std::runtime_error("glTF is in an unknown format."); + // case cgltf_result_invalid_json: + // throw std::runtime_error("glTF JSON is invalid."); + // case cgltf_result_invalid_gltf: + // throw std::runtime_error("glTF is invalid."); + // case cgltf_result_invalid_options: + // throw std::runtime_error("glTF parsed with invalid options."); + // case cgltf_result_file_not_found: + // throw std::runtime_error("glTF file was not found."); + // case cgltf_result_io_error: + // throw std::runtime_error("I/O error while parsing glTF."); + // case cgltf_result_out_of_memory: + // throw std::runtime_error("Out of memory while parsing glTF."); + // case cgltf_result_legacy_gltf: + // throw std::runtime_error("glTF uses an unsupported legacy format."); + // default: + // throw std::runtime_error("An unknown error occurred while parsing a glTF."); + // } + // } } // cgltf_asset asset; diff --git a/CesiumGltf/src/cgltf.cpp b/CesiumGltf/src/cgltf.cpp deleted file mode 100644 index b0133d63b..000000000 --- a/CesiumGltf/src/cgltf.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#define CGLTF_IMPLEMENTATION -#pragma warning(disable:4996) -#include From 767b5d3a6d26c59ac99f6ac99b39c51f3ee41489 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Sun, 27 Dec 2020 23:11:01 +1100 Subject: [PATCH 04/61] WIP glTF --- CesiumGltf/include/CesiumGltf/GltfCollection.h | 9 ++++++++- CesiumGltf/include/CesiumGltf/GltfModel.h | 4 +++- CesiumGltf/include/CesiumGltf/TinyGltfMapping.h | 5 +++++ CesiumGltf/src/GltfModel.cpp | 12 ++++++------ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/CesiumGltf/include/CesiumGltf/GltfCollection.h b/CesiumGltf/include/CesiumGltf/GltfCollection.h index 6a2bbda83..a07243b53 100644 --- a/CesiumGltf/include/CesiumGltf/GltfCollection.h +++ b/CesiumGltf/include/CesiumGltf/GltfCollection.h @@ -9,6 +9,7 @@ namespace CesiumGltf { template class GltfCollection { public: + class const_iterator { public: using iterator_category = std::random_access_iterator_tag; @@ -71,7 +72,13 @@ namespace CesiumGltf { mutable std::optional _temporary; }; - GltfCollection(std::vector::tinygltf_type>* pElements) : + using vector_type = std::conditional_t< + std::is_const::value, + std::vector>::tinygltf_type>, + std::vector>::tinygltf_type> + >; + + GltfCollection(vector_type* pElements) : _pElements(ppElements) { } diff --git a/CesiumGltf/include/CesiumGltf/GltfModel.h b/CesiumGltf/include/CesiumGltf/GltfModel.h index b6aec7548..d4f7b93a1 100644 --- a/CesiumGltf/include/CesiumGltf/GltfModel.h +++ b/CesiumGltf/include/CesiumGltf/GltfModel.h @@ -24,7 +24,9 @@ namespace CesiumGltf { GltfModel(); - GltfCollection extensionsUsed() const noexcept; + GltfCollection extensionsUsed() const noexcept; + GltfCollection extensionsUsed() noexcept; + GltfCollection extensionsRequired() const noexcept; GltfCollection accessors() const noexcept; GltfCollection animations() const noexcept; diff --git a/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h b/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h index 61036c5c6..50b9ed81e 100644 --- a/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h +++ b/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h @@ -41,6 +41,11 @@ namespace CesiumGltf { using tinygltf_type = std::string; }; + template <> + struct CesiumToTinyGltf { + using tinygltf_type = const std::string; + }; + // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Accessor; }; // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Animation; }; // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Buffer; }; diff --git a/CesiumGltf/src/GltfModel.cpp b/CesiumGltf/src/GltfModel.cpp index 202fe4e99..8dd8e91f2 100644 --- a/CesiumGltf/src/GltfModel.cpp +++ b/CesiumGltf/src/GltfModel.cpp @@ -9,7 +9,7 @@ namespace CesiumGltf { std::string warnings; std::string errors; tinygltf::TinyGLTF loader; - bool success = loader.LoadBinaryFromMemory(&result._model, &errors, &warnings, data.data(), static_cast(data.size())); + /*bool success =*/ loader.LoadBinaryFromMemory(&result._model, &errors, &warnings, data.data(), static_cast(data.size())); return result; // cgltf_options options{}; // cgltf_data* pResult = nullptr; @@ -60,12 +60,12 @@ namespace CesiumGltf { // cgltf_scene* scene; // cgltf_animation* animations; - GltfCollection GltfModel::extensionsUsed() const noexcept { - return { &this->_pData->extensions_used, &this->_pData->extensions_used_count }; + GltfCollection GltfModel::extensionsUsed() const noexcept { + return GltfCollection(&this->_model.extensionsUsed); } GltfCollection GltfModel::extensionsRequired() const noexcept { - return { &this->_pData->extensions_required, &this->_pData->extensions_required_count }; + return { &this->_model.extensionsRequired }; } GltfCollection GltfModel::meshes() const noexcept { @@ -76,8 +76,8 @@ namespace CesiumGltf { return { &this->_pData->accessors, &this->_pData->accessors_count }; } - GltfModel::GltfModel(cgltf_data* pData) : - _pData(pData, cgltf_free) + GltfModel::GltfModel(tinygltf::Model&& model) : + _model(std::move(model)) { } } From c29069f613f4ac91533cb053dcf908202ec46df4 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Sat, 2 Jan 2021 22:23:04 +1100 Subject: [PATCH 05/61] Some very broken experiments. --- .../Cesium3DTiles/TileContentLoadResult.h | 2 +- Cesium3DTiles/src/GltfContent.cpp | 22 +- CesiumGltf/CMakeLists.txt | 3 +- CesiumGltf/include/CesiumGltf/GltfAccessor.h | 53 +++- CesiumGltf/include/CesiumGltf/GltfBuffer.h | 8 +- CesiumGltf/include/CesiumGltf/GltfModel.h | 59 +++-- CesiumGltf/src/GltfAccessor.cpp | 72 ++++-- CesiumGltf/src/GltfBuffer.cpp | 71 +++--- CesiumGltf/src/GltfMesh.cpp | 15 +- CesiumGltf/src/GltfModel.cpp | 32 +-- CesiumGltf/test/TestGltfModel.cpp | 237 +++++++++++++++++- 11 files changed, 442 insertions(+), 132 deletions(-) diff --git a/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h b/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h index ab0280d36..c0816e0d0 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h +++ b/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h @@ -30,7 +30,7 @@ namespace Cesium3DTiles { * If it has a value but the model is blank, the tile can * be "rendered", but it is rendered as nothing. */ - std::optional model; + std::optional model; /** * @brief A new context, if any, used by the `childTiles`. diff --git a/Cesium3DTiles/src/GltfContent.cpp b/Cesium3DTiles/src/GltfContent.cpp index cf91ac5f0..259997d5d 100644 --- a/Cesium3DTiles/src/GltfContent.cpp +++ b/Cesium3DTiles/src/GltfContent.cpp @@ -40,7 +40,7 @@ namespace Cesium3DTiles { } static int generateOverlayTextureCoordinates( - GltfModel& gltf, + tinygltf::Model& gltf, int positionAccessorIndex, const glm::dmat4x4& transform, const CesiumGeospatial::Projection& projection, @@ -52,22 +52,22 @@ namespace Cesium3DTiles { double& minimumHeight, double& maximumHeight ) { - GltfCollection buffers = gltf.buffers(); - GltfCollection bufferViews = gltf.bufferViews(); - GltfCollection accessors = gltf.accessors(); + std::vector& buffers = gltf.buffers; + std::vector& bufferViews = gltf.bufferViews; + std::vector& accessors = gltf.accessors; - size_t uvBufferId = buffers.size(); - GltfBuffer uvBuffer = buffers.emplace_back(); + int uvBufferId = static_cast(buffers.size()); + tinygltf::Buffer uvBuffer = buffers.emplace_back(); - size_t uvBufferViewId = bufferViews.size(); - GltfBufferView uvBufferView = bufferViews.emplace_back(); + int uvBufferViewId = static_cast(bufferViews.size()); + bufferViews.emplace_back(); - size_t uvAccessorId = accessors.size(); - CesiumGltf::GltfAccessor uvAccessor = accessors.emplace_back(); + int uvAccessorId = static_cast(accessors.size()); + accessors.emplace_back(); GltfAccessor positionAccessor(gltf, static_cast(positionAccessorIndex)); - uvBuffer.resizeData(positionAccessor.size() * 2 * sizeof(float)); + uvBuffer.data.resize(positionAccessor.size() * 2 * sizeof(float)); tinygltf::BufferView& uvBufferView = gltf.bufferViews[static_cast(uvBufferViewId)]; uvBufferView.buffer = uvBufferId; diff --git a/CesiumGltf/CMakeLists.txt b/CesiumGltf/CMakeLists.txt index 72c822a67..5a590fb48 100644 --- a/CesiumGltf/CMakeLists.txt +++ b/CesiumGltf/CMakeLists.txt @@ -18,6 +18,7 @@ target_include_directories( SYSTEM PUBLIC # We're not using CMake for tinygltf at all, but it's header only. Add its headers here. ${CMAKE_CURRENT_SOURCE_DIR}/../extern/tinygltf + ${CMAKE_CURRENT_SOURCE_DIR}/../extern/rapidjson/include PUBLIC include PRIVATE @@ -26,4 +27,4 @@ target_include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../extern/cgltf ) -target_link_libraries(CesiumGltf PUBLIC CesiumGeometry CesiumUtility simdjson) +target_link_libraries(CesiumGltf PUBLIC CesiumGeometry CesiumUtility) diff --git a/CesiumGltf/include/CesiumGltf/GltfAccessor.h b/CesiumGltf/include/CesiumGltf/GltfAccessor.h index 0800faea3..fbd16ef8f 100644 --- a/CesiumGltf/include/CesiumGltf/GltfAccessor.h +++ b/CesiumGltf/include/CesiumGltf/GltfAccessor.h @@ -8,20 +8,51 @@ namespace CesiumGltf { template class GltfCollection; - class GltfAccessor final { - public: - GltfAccessor(); - ~GltfAccessor(); + class GltfAccessor; + + #define CESIUM_GLTF_CONST_WRAPPER_DECL(Type, WrappedType) \ + public: \ + Type##Const(); \ + Type##Const(const Type##Const& rhs); \ + Type##Const(Type##Const&& rhs) = delete; \ + ~Type##Const(); \ + Type##Const& operator=(const Type##Const& rhs) = delete; \ + Type##Const& operator=(Type##Const&& rhs) = delete; \ + private: \ + using Tiny = WrappedType; \ + Type##Const(const WrappedType* p); \ + const WrappedType* _p; \ + bool _owns; \ + template \ + friend class GltfCollection; \ + friend class GltfAccessor; + + #define CESIUM_GLTF_MUTABLE_WRAPPER_DECL(Type, WrappedType) \ + public: \ + Type(); \ + Type(const Type& rhs); \ + Type(Type&& rhs); \ + Type(const Type##Const& rhs); \ + Type(Type##Const&& rhs); \ + Type& operator=(const Type& rhs); \ + Type& operator=(Type&& rhs); \ + Type& operator=(const Type##Const& rhs); \ + private: \ + using Const = Type##Const; \ + Type(WrappedType* p); \ + Tiny*& tiny() { return const_cast(this->_p); } - private: - using tinygltf_type = tinygltf::Accessor; + class GltfAccessorConst { + public: + size_t getCount() const; - GltfAccessor(tinygltf::Accessor* p); + CESIUM_GLTF_CONST_WRAPPER_DECL(GltfAccessor, tinygltf::Accessor); + }; - tinygltf::Accessor* _p; - bool _owns; + class GltfAccessor final : public GltfAccessorConst { + public: + void setCount(size_t value); - template - friend class GltfCollection; + CESIUM_GLTF_MUTABLE_WRAPPER_DECL(GltfAccessor, tinygltf::Accessor); }; } diff --git a/CesiumGltf/include/CesiumGltf/GltfBuffer.h b/CesiumGltf/include/CesiumGltf/GltfBuffer.h index d90e9a227..884dd9d40 100644 --- a/CesiumGltf/include/CesiumGltf/GltfBuffer.h +++ b/CesiumGltf/include/CesiumGltf/GltfBuffer.h @@ -3,12 +3,12 @@ #include #include -struct cgltf_buffer; +// struct cgltf_buffer; namespace CesiumGltf { class GltfBuffer { public: - static GltfBuffer createFromCollectionElement(cgltf_buffer* array, size_t arrayIndex); + // static GltfBuffer createFromCollectionElement(cgltf_buffer* array, size_t arrayIndex); std::string getUri() const noexcept; void setUri(const std::string& value) noexcept; @@ -19,8 +19,8 @@ namespace CesiumGltf { void resizeData(size_t newSize) noexcept; private: - GltfBuffer(cgltf_buffer* p); + // GltfBuffer(cgltf_buffer* p); - cgltf_buffer* _p; + // cgltf_buffer* _p; }; } diff --git a/CesiumGltf/include/CesiumGltf/GltfModel.h b/CesiumGltf/include/CesiumGltf/GltfModel.h index d4f7b93a1..92d9ee412 100644 --- a/CesiumGltf/include/CesiumGltf/GltfModel.h +++ b/CesiumGltf/include/CesiumGltf/GltfModel.h @@ -18,31 +18,62 @@ #include namespace CesiumGltf { - class GltfModel { + + template + class GltfConstPointer final { + public: + const T& operator*() const noexcept { return this->_obj; } + const T* operator->() const noexcept { return &this->_obj; } + + private: + GltfConstPointer(const typename T::tinygltf_type* p) noexcept : + _obj(p) + { + } + + const T _obj; + }; + + template + class GltfPointer final { + public: + T& operator*() const noexcept { return this->_obj; } + T* operator->() const noexcept { return &this->_obj; } + + private: + GltfPointer(typename T::tinygltf_type* p) noexcept : + _obj(p) + { + } + + T _obj; + }; + + class GltfModel final { public: static GltfModel fromMemory(gsl::span pData); GltfModel(); - GltfCollection extensionsUsed() const noexcept; - GltfCollection extensionsUsed() noexcept; + // GltfCollection extensionsUsed() const noexcept; + // GltfCollection extensionsUsed() noexcept; - GltfCollection extensionsRequired() const noexcept; + // GltfCollection extensionsRequired() const noexcept; GltfCollection accessors() const noexcept; - GltfCollection animations() const noexcept; + // GltfCollection animations() const noexcept; // GltfAsset asset() const noexcept; - GltfCollection buffers() const noexcept; - GltfCollection bufferViews() const noexcept; + // GltfCollection buffers() const noexcept; + // GltfCollection bufferViews() const noexcept; // GltfCollection cameras() const noexcept; - GltfCollection images() const noexcept; - GltfCollection materials() const noexcept; - GltfCollection meshes() const noexcept; - GltfCollection nodes() const noexcept; - GltfCollection samplers() const noexcept; + // GltfCollection images() const noexcept; + // GltfCollection materials() const noexcept; + // GltfCollection meshes() const noexcept; + // GltfCollection nodes() const noexcept; + // GltfCollection samplers() const noexcept; // size_t scene() const noexcept; - GltfCollection scenes() const noexcept; + // GltfCollection scenes() const noexcept; // GltfCollection skins() const noexcept; - GltfCollection textures() const noexcept; + // GltfCollection textures() const noexcept; private: GltfModel(tinygltf::Model&& model); diff --git a/CesiumGltf/src/GltfAccessor.cpp b/CesiumGltf/src/GltfAccessor.cpp index 17ca02136..14bea1d00 100644 --- a/CesiumGltf/src/GltfAccessor.cpp +++ b/CesiumGltf/src/GltfAccessor.cpp @@ -1,31 +1,59 @@ #include "CesiumGltf/GltfAccessor.h" #include -namespace CesiumGltf { - GltfAccessor::GltfAccessor() : - _p(new tinygltf_type()), - _owns(true) - { - } - - GltfAccessor::~GltfAccessor() { - if (this->_owns) { - delete this->_p; - } +#define CESIUM_GLTF_WRAPPER_IMPL(Type) \ + Type##Const::Type##Const() : \ + _p(new Tiny()), \ + _owns(true) \ + {} \ + Type##Const::Type##Const(const Type##Const& rhs) : \ + _p(new Tiny(*rhs._p)), \ + _owns(true) \ + {} \ + Type##Const::~Type##Const() { \ + if (this->_owns) { \ + delete this->_p; \ + } \ + } \ + Type##Const::Type##Const(const Tiny* p) : \ + _p(p), \ + _owns(false) \ + {} \ + Type::Type() : Type##Const() {} \ + Type::Type(const Type& rhs) : Type##Const(rhs) {} \ + Type::Type(GltfAccessor&& rhs) : \ + Type(static_cast(std::move(rhs))) \ + {} \ + Type::Type(const Type##Const& rhs) : \ + Type##Const(rhs) \ + {} \ + Type::Type(Type##Const&& rhs) : \ + Type##Const(std::exchange(rhs._p, nullptr)) \ + { \ + this->_owns = rhs._owns; \ + } \ + Type& Type::operator=(const Type& rhs) { \ + *this->tiny() = *rhs._p; \ + return *this; \ + } \ + Type& Type::operator=(Type&& rhs) { \ + std::swap(this->_p, rhs._p); \ + std::swap(this->_owns, rhs._owns); \ + return *this; \ + } \ + Type& Type::operator=(const Type##Const& rhs) { \ + *this->tiny() = *rhs._p; \ + return *this; \ } - // /*static*/ GltfAccessor GltfAccessor::createFromCollectionElement(cgltf_accessor* array, size_t arrayIndex) { - // return GltfAccessor(&array[arrayIndex]); - // } +namespace CesiumGltf { + CESIUM_GLTF_WRAPPER_IMPL(GltfAccessor); - // GltfAccessor::GltfAccessor(cgltf_accessor* p) : - // _p(p) - // { - // } + size_t GltfAccessorConst::getCount() const { + return this->_p->count; + } - GltfAccessor::GltfAccessor(tinygltf::Accessor* p) : - _p(p), - _owns(false) - { + void GltfAccessor::setCount(size_t value) { + this->tiny()->count = value; } } diff --git a/CesiumGltf/src/GltfBuffer.cpp b/CesiumGltf/src/GltfBuffer.cpp index 2ae76aebd..026fd094b 100644 --- a/CesiumGltf/src/GltfBuffer.cpp +++ b/CesiumGltf/src/GltfBuffer.cpp @@ -1,42 +1,41 @@ #include "CesiumGltf/GltfBuffer.h" -#include #include namespace CesiumGltf { - /*static*/ GltfBuffer GltfBuffer::createFromCollectionElement(cgltf_buffer* array, size_t arrayIndex) { - return GltfBuffer(&array[arrayIndex]); - } - - GltfBuffer::GltfBuffer(cgltf_buffer* p) : - _p(p) - { - } - - std::string GltfBuffer::getUri() const noexcept { - return this->_p->uri; - } - - void GltfBuffer::setUri(const std::string& value) noexcept { - this->_p->uri = static_cast(realloc(this->_p->uri, value.size() + 1)); - value.copy(this->_p->uri, value.size(), 0); - this->_p->uri[value.size()] = '\0'; - } - - gsl::span GltfBuffer::getData() const noexcept { - return gsl::span(static_cast(this->_p->data), this->_p->size); - } - - gsl::span GltfBuffer::getData() noexcept { - return gsl::span(static_cast(this->_p->data), this->_p->size); - } - - void GltfBuffer::setData(const gsl::span& value) noexcept { - this->_p->data = realloc(this->_p->data, value.size()); - std::copy(value.begin(), value.end(), static_cast(this->_p->data)); - } - - void GltfBuffer::resizeData(size_t newSize) noexcept { - this->_p->data = realloc(this->_p->data, newSize); - } + // /*static*/ GltfBuffer GltfBuffer::createFromCollectionElement(cgltf_buffer* array, size_t arrayIndex) { + // return GltfBuffer(&array[arrayIndex]); + // } + + // GltfBuffer::GltfBuffer(cgltf_buffer* p) : + // _p(p) + // { + // } + + // std::string GltfBuffer::getUri() const noexcept { + // return this->_p->uri; + // } + + // void GltfBuffer::setUri(const std::string& value) noexcept { + // this->_p->uri = static_cast(realloc(this->_p->uri, value.size() + 1)); + // value.copy(this->_p->uri, value.size(), 0); + // this->_p->uri[value.size()] = '\0'; + // } + + // gsl::span GltfBuffer::getData() const noexcept { + // return gsl::span(static_cast(this->_p->data), this->_p->size); + // } + + // gsl::span GltfBuffer::getData() noexcept { + // return gsl::span(static_cast(this->_p->data), this->_p->size); + // } + + // void GltfBuffer::setData(const gsl::span& value) noexcept { + // this->_p->data = realloc(this->_p->data, value.size()); + // std::copy(value.begin(), value.end(), static_cast(this->_p->data)); + // } + + // void GltfBuffer::resizeData(size_t newSize) noexcept { + // this->_p->data = realloc(this->_p->data, newSize); + // } } diff --git a/CesiumGltf/src/GltfMesh.cpp b/CesiumGltf/src/GltfMesh.cpp index 467519b94..724c4a32b 100644 --- a/CesiumGltf/src/GltfMesh.cpp +++ b/CesiumGltf/src/GltfMesh.cpp @@ -1,13 +1,12 @@ #include "CesiumGltf/GltfMesh.h" -#include namespace CesiumGltf { - /*static*/ GltfMesh GltfMesh::createFromCollectionElement(cgltf_mesh* array, size_t arrayIndex) { - return GltfMesh(&array[arrayIndex]); - } + // /*static*/ GltfMesh GltfMesh::createFromCollectionElement(cgltf_mesh* array, size_t arrayIndex) { + // return GltfMesh(&array[arrayIndex]); + // } - GltfMesh::GltfMesh(cgltf_mesh* p) : - _p(p) - { - } + // GltfMesh::GltfMesh(cgltf_mesh* p) : + // _p(p) + // { + // } } diff --git a/CesiumGltf/src/GltfModel.cpp b/CesiumGltf/src/GltfModel.cpp index 8dd8e91f2..3f05f0b3d 100644 --- a/CesiumGltf/src/GltfModel.cpp +++ b/CesiumGltf/src/GltfModel.cpp @@ -60,24 +60,24 @@ namespace CesiumGltf { // cgltf_scene* scene; // cgltf_animation* animations; - GltfCollection GltfModel::extensionsUsed() const noexcept { - return GltfCollection(&this->_model.extensionsUsed); - } + // GltfCollection GltfModel::extensionsUsed() const noexcept { + // return GltfCollection(&this->_model.extensionsUsed); + // } - GltfCollection GltfModel::extensionsRequired() const noexcept { - return { &this->_model.extensionsRequired }; - } + // GltfCollection GltfModel::extensionsRequired() const noexcept { + // return { &this->_model.extensionsRequired }; + // } - GltfCollection GltfModel::meshes() const noexcept { - return { &this->_pData->meshes, &this->_pData->meshes_count }; - } + // GltfCollection GltfModel::meshes() const noexcept { + // return { &this->_pData->meshes, &this->_pData->meshes_count }; + // } - GltfCollection GltfModel::accessors() const noexcept { - return { &this->_pData->accessors, &this->_pData->accessors_count }; - } + // GltfCollection GltfModel::accessors() const noexcept { + // return { &this->_pData->accessors, &this->_pData->accessors_count }; + // } - GltfModel::GltfModel(tinygltf::Model&& model) : - _model(std::move(model)) - { - } + // GltfModel::GltfModel(tinygltf::Model&& model) : + // _model(std::move(model)) + // { + // } } diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index ba6d41682..f9da8e172 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -1,17 +1,238 @@ #include "catch2/catch.hpp" #include "CesiumGltf/GltfModel.h" +#include +#include +#include using namespace CesiumGltf; -TEST_CASE("GltfModel") { - std::vector v; - GltfModel model = GltfModel::fromMemory(v); - GltfCollection meshes = model.meshes(); - for (const GltfMesh& mesh : meshes) { - mesh; +namespace CesiumGltf { + template + void goParse(T&& handler) { + while (!handler.reader.IterativeParseComplete() && !handler.done) { + if (handler.next) { + handler.next(); + handler.next = nullptr; + } else { + handler.reader.IterativeParseNext(handler.inputStream, handler); + } + } } - for (const std::string& s : model.extensionsUsed()) { - s; + struct DefaultHandler { + DefaultHandler(rapidjson::Reader& reader_, rapidjson::MemoryStream& inputStream_) : + reader(reader_), + inputStream(inputStream_), + done(false) + {} + + rapidjson::Reader& reader; + rapidjson::MemoryStream& inputStream; + std::function next; + bool done; + + bool Null() { return false; } + bool Bool(bool /*b*/) { return false; } + bool Int(int /*i*/) { return false; } + bool Uint(unsigned /*i*/) { return false; } + bool Int64(int64_t /*i*/) { return false; } + bool Uint64(uint64_t /*i*/) { return false; } + bool Double(double /*d*/) { return false; } + bool RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return false; } + bool String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return false; } + bool StartObject() { return false; } + bool Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return false; } + bool EndObject(size_t /*memberCount*/) { return false; } + bool StartArray() { return false; } + bool EndArray(size_t /*elementCount*/) { return false; } + }; + + struct ObjectHandler : public DefaultHandler { + ObjectHandler( + rapidjson::Reader& reader_, + rapidjson::MemoryStream& inputStream_ + ) : + DefaultHandler(reader_, inputStream_) + {} + + bool StartObject() { return true; } + bool EndObject(size_t) { + this->done = true; + return true; + } + }; + + template + struct ObjectArrayHandler : public DefaultHandler { + ObjectArrayHandler( + rapidjson::Reader& reader_, + rapidjson::MemoryStream& inputStream_, + std::vector& array_ + ) : + DefaultHandler(reader_, inputStream_), + array(array_), + _arrayOpen(false) + {} + + std::vector& array; + bool _arrayOpen; + + bool StartArray() { + if (this->_arrayOpen) { + return false; + } + + this->_arrayOpen = true; + return true; + } + + bool StartObject() { + if (!this->_arrayOpen) { + return false; + } + + T& o = this->array.emplace_back(); + THandler handler(this->reader, this->inputStream, o); + bool result = handler.StartObject(); + + if (result) { + next = [handler = std::move(handler)]() mutable { + goParse(handler); + }; + } + + return result; + } + + bool EndArray(size_t /*elementCount*/) { + if (!this->_arrayOpen) { + return false; + } + + this->_arrayOpen = false; + this->done = true; + return true; + } + }; + + struct Accessor { + size_t count; + }; + + struct Model { + std::vector accessors; + }; + + template + struct IntegerHandler : public DefaultHandler { + IntegerHandler( + rapidjson::Reader& reader_, + rapidjson::MemoryStream& inputStream_, + T& value_ + ) : + DefaultHandler(reader_, inputStream_), + value(value_) + {} + + T& value; + + bool Int(int i) { + this->value = static_cast(i); + this->done = true; + return true; + } + bool Uint(unsigned i) { + this->value = static_cast(i); + this->done = true; + return true; + } + bool Int64(int64_t i) { + this->value = static_cast(i); + this->done = true; + return true; + } + bool Uint64(uint64_t i) { + this->value = static_cast(i); + this->done = true; + return true; + } + }; + + struct AccessorHandler : public ObjectHandler { + AccessorHandler( + rapidjson::Reader& reader_, + rapidjson::MemoryStream& inputStream_, + Accessor& accessor_ + ) : + ObjectHandler(reader_, inputStream_), + accessor(accessor_) + {} + + Accessor& accessor; + + bool Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + if ("count"s == str) { + next = [this]() { + goParse(IntegerHandler(this->reader, this->inputStream, this->accessor.count)); + }; + } + + return true; + } + }; + + struct ModelHandler : public ObjectHandler { + ModelHandler( + rapidjson::Reader& reader_, + rapidjson::MemoryStream& inputStream_, + Model& model_ + ) : + ObjectHandler(reader_, inputStream_), + model(model_) + {} + + Model& model; + + bool Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + if ("accessors"s == str) { + next = [this]() { goParse(ObjectArrayHandler(this->reader, this->inputStream, this->model.accessors)); }; + + } + return true; + } + }; + + Model parseModel(const gsl::span& data) { + rapidjson::Reader reader; + rapidjson::MemoryStream inputStream(reinterpret_cast(data.data()), data.size()); + + reader.IterativeParseInit(); + + Model model; + ModelHandler handler(reader, inputStream, model); + goParse(handler); + + return model; } +} + +TEST_CASE("GltfModel") { + std::string s = "{\"accessors\": [{\"count\": 4}]}"; + Model model = CesiumGltf::parseModel(gsl::span(reinterpret_cast(s.c_str()), s.size())); + CHECK(model.accessors.size() == 1); + CHECK(model.accessors[0].count == 4); + // std::vector v; + // GltfModel model = GltfModel::fromMemory(v); + // GltfCollection meshes = model.meshes(); + // for (const GltfMesh& mesh : meshes) { + // mesh; + // } + + // for (const std::string& s : model.extensionsUsed()) { + // s; + // } } \ No newline at end of file From a72c111c0feec375d1bc345ea52d772bd2e06fa7 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Sun, 3 Jan 2021 00:15:47 +1100 Subject: [PATCH 06/61] Another experiment. --- CesiumGltf/test/TestGltfModel.cpp | 275 +++++++++++++++++++++++++++++- 1 file changed, 266 insertions(+), 9 deletions(-) diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index f9da8e172..29e337d09 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -7,6 +7,269 @@ using namespace CesiumGltf; namespace CesiumGltf { + class JsonHandler { + public: + virtual JsonHandler* Null() { return nullptr; } + virtual JsonHandler* Bool(bool /*b*/) { return nullptr; } + virtual JsonHandler* Int(int /*i*/) { return nullptr; } + virtual JsonHandler* Uint(unsigned /*i*/) { return nullptr; } + virtual JsonHandler* Int64(int64_t /*i*/) { return nullptr; } + virtual JsonHandler* Uint64(uint64_t /*i*/) { return nullptr; } + virtual JsonHandler* Double(double /*d*/) { return nullptr; } + virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return nullptr; } + virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return nullptr; } + virtual JsonHandler* StartObject() { return nullptr; } + virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return nullptr; } + virtual JsonHandler* EndObject(size_t /*memberCount*/) { return nullptr; } + virtual JsonHandler* StartArray() { return nullptr; } + virtual JsonHandler* EndArray(size_t /*elementCount*/) { return nullptr; } + + template + JsonHandler* property(TAccessor& accessor, TProperty& value) { + accessor.reset(this, &value); + return &accessor; + } + + JsonHandler* parent() { + return this->_pParent; + } + + protected: + void reset(JsonHandler* pParent) { + this->_pParent = pParent; + } + + private: + JsonHandler* _pParent = nullptr; + }; + + class IgnoreValueJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent) { + JsonHandler::reset(pParent); + this->_depth = 0; + } + + virtual JsonHandler* Null() { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Bool(bool /*b*/) { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Int(int /*i*/) { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Uint(unsigned /*i*/) { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Int64(int64_t /*i*/) { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Uint64(uint64_t /*i*/) { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Double(double /*d*/) { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* StartObject() { ++this->_depth; return this; } + virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return this; } + virtual JsonHandler* EndObject(size_t /*memberCount*/) { --this->_depth; return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* StartArray() { ++this->_depth; return this; } + virtual JsonHandler* EndArray(size_t /*elementCount*/) { --this->_depth; return this->_depth == 0 ? this->parent() : this; } + + private: + size_t _depth = 0; + }; + + class RejectAllJsonHandler : public JsonHandler { + public: + RejectAllJsonHandler() { + reset(this); + } + }; + + struct Accessor { + size_t count; + }; + + struct Model { + std::vector accessors; + }; + + template + class IntegerJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, T* pInteger) { + JsonHandler::reset(pParent); + this->_pInteger = pInteger; + } + + virtual JsonHandler* Int(int i) override { + assert(this->_pInteger); + *this->_pInteger = static_cast(i); + return this->parent(); + } + virtual JsonHandler* Uint(unsigned i) override { + assert(this->_pInteger); + *this->_pInteger = static_cast(i); + return this->parent(); + } + virtual JsonHandler* Int64(int64_t i) override { + assert(this->_pInteger); + *this->_pInteger = static_cast(i); + return this->parent(); + } + virtual JsonHandler* Uint64(uint64_t i) override { + assert(this->_pInteger); + *this->_pInteger = static_cast(i); + return this->parent(); + } + + private: + T* _pInteger = nullptr; + }; + + class ObjectJsonHandler : public JsonHandler { + public: + virtual JsonHandler* StartObject() override { + return this; + } + + virtual JsonHandler* EndObject(size_t /*memberCount*/) override { + return this->parent(); + } + + JsonHandler* ignore() { + this->_ignoreHandler.reset(this); + return &this->_ignoreHandler; + } + + private: + IgnoreValueJsonHandler _ignoreHandler; + }; + + class AccessorJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Accessor* pAccessor) { + JsonHandler::reset(pParent); + this->_pAccessor = pAccessor; + } + + virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { + using namespace std::string_literals; + + assert(this->_pAccessor); + if ("count"s == str) return property(this->_count, this->_pAccessor->count); + + return this->ignore(); + } + + private: + Accessor* _pAccessor = nullptr; + IntegerJsonHandler _count; + }; + + template + class ObjectArrayJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, std::vector* pArray) { + this->_pParent = pParent; + this->_pArray = pArray; + this->_arrayIsOpen = false; + } + + virtual JsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return nullptr; + } + + this->_arrayIsOpen = true; + return this; + } + + virtual JsonHandler* EndArray(size_t) override { + return this->_pParent; + } + + virtual JsonHandler* StartObject() override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + T& o = this->_pArray->emplace_back(); + this->_objectHandler.reset(this, &o); + return this->_objectHandler.StartObject(); + } + + private: + JsonHandler* _pParent = nullptr; + std::vector* _pArray = nullptr; + bool _arrayIsOpen = false; + THandler _objectHandler; + }; + + class ModelJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Model* pModel) { + ObjectJsonHandler::reset(pParent); + this->_pModel = pModel; + } + + virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { + using namespace std::string_literals; + + assert(this->_pModel); + if ("accessors"s == str) return property(this->_accessors, this->_pModel->accessors); + + return this->ignore(); + } + + private: + Model* _pModel; + ObjectArrayJsonHandler _accessors; + }; + + class GltfReader final { + public: + Model parse(const gsl::span& data) { + rapidjson::Reader reader; + rapidjson::MemoryStream inputStream(reinterpret_cast(data.data()), data.size()); + + Model result; + ModelJsonHandler modelHandler; + RejectAllJsonHandler rejectHandler; + Dispatcher dispatcher { &modelHandler }; + + modelHandler.reset(&rejectHandler, &result); + + reader.IterativeParseInit(); + + while (!reader.IterativeParseComplete()) { + reader.IterativeParseNext(inputStream, dispatcher); + } + + return result; + } + + private: + struct Dispatcher { + JsonHandler* pCurrent; + + bool update(JsonHandler* pNext) { + if (pNext == nullptr) { + return false; + } + + this->pCurrent = pNext; + return true; + } + + bool Null() { return update(pCurrent->Null()); } + bool Bool(bool b) { return update(pCurrent->Bool(b)); } + bool Int(int i) { return update(pCurrent->Int(i)); } + bool Uint(unsigned i) { return update(pCurrent->Uint(i)); } + bool Int64(int64_t i) { return update(pCurrent->Int64(i)); } + bool Uint64(uint64_t i) { return update(pCurrent->Uint64(i)); } + bool Double(double d) { return update(pCurrent->Double(d)); } + bool RawNumber(const char* str, size_t length, bool copy) { return update(pCurrent->RawNumber(str, length, copy)); } + bool String(const char* str, size_t length, bool copy) { return update(pCurrent->String(str, length, copy)); } + bool StartObject() { return update(pCurrent->StartObject()); } + bool Key(const char* str, size_t length, bool copy) { return update(pCurrent->Key(str, length, copy)); } + bool EndObject(size_t memberCount) { return update(pCurrent->EndObject(memberCount)); } + bool StartArray() { return update(pCurrent->StartArray()); } + bool EndArray(size_t elementCount) { return update(pCurrent->EndArray(elementCount)); } + }; + }; + template void goParse(T&& handler) { while (!handler.reader.IterativeParseComplete() && !handler.done) { @@ -115,14 +378,6 @@ namespace CesiumGltf { } }; - struct Accessor { - size_t count; - }; - - struct Model { - std::vector accessors; - }; - template struct IntegerHandler : public DefaultHandler { IntegerHandler( @@ -222,7 +477,9 @@ namespace CesiumGltf { TEST_CASE("GltfModel") { std::string s = "{\"accessors\": [{\"count\": 4}]}"; - Model model = CesiumGltf::parseModel(gsl::span(reinterpret_cast(s.c_str()), s.size())); + GltfReader reader; + + Model model = reader.parse(gsl::span(reinterpret_cast(s.c_str()), s.size())); CHECK(model.accessors.size() == 1); CHECK(model.accessors[0].count == 4); // std::vector v; From 0d7d7d041432f0f61591884fa2d4d4ff5f7a5363 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 4 Jan 2021 13:36:34 +1100 Subject: [PATCH 07/61] Add Mesh and Primitve to POC. --- CesiumGltf/test/TestGltfModel.cpp | 261 ++++++++++++++++++++++++++---- 1 file changed, 233 insertions(+), 28 deletions(-) diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index 29e337d09..0a59bf8a6 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -50,20 +50,20 @@ namespace CesiumGltf { this->_depth = 0; } - virtual JsonHandler* Null() { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Bool(bool /*b*/) { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Int(int /*i*/) { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Uint(unsigned /*i*/) { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Int64(int64_t /*i*/) { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Uint64(uint64_t /*i*/) { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Double(double /*d*/) { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* StartObject() { ++this->_depth; return this; } - virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return this; } - virtual JsonHandler* EndObject(size_t /*memberCount*/) { --this->_depth; return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* StartArray() { ++this->_depth; return this; } - virtual JsonHandler* EndArray(size_t /*elementCount*/) { --this->_depth; return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Null() override { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Bool(bool /*b*/) override { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Int(int /*i*/) override { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Uint(unsigned /*i*/) override { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Int64(int64_t /*i*/) override { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Uint64(uint64_t /*i*/) override { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* Double(double /*d*/) override { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) override { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/) override { return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* StartObject() override { ++this->_depth; return this; } + virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) override { return this; } + virtual JsonHandler* EndObject(size_t /*memberCount*/) override { --this->_depth; return this->_depth == 0 ? this->parent() : this; } + virtual JsonHandler* StartArray() override { ++this->_depth; return this; } + virtual JsonHandler* EndArray(size_t /*elementCount*/) override { --this->_depth; return this->_depth == 0 ? this->parent() : this; } private: size_t _depth = 0; @@ -76,12 +76,62 @@ namespace CesiumGltf { } }; + enum class ComponentType { + BYTE = 5120, + UNSIGNED_BYTE = 5121, + SHORT = 5122, + UNSIGNED_SHORT = 5123, + UNSIGNED_INT = 5125, + FLOAT = 5126 + }; + + enum class AccessorType { + SCALAR, + VEC2, + VEC3, + VEC4, + MAT2, + MAT3, + MAT4 + }; + struct Accessor { + size_t bufferView; + size_t byteOffset = 0; + ComponentType componentType; + bool normalized = false; size_t count; + AccessorType type; + std::vector max; + std::vector min; + }; + + enum class PrimitiveMode { + POINTS = 0, + LINES = 1, + LINE_LOOP = 2, + LINE_STRIP = 3, + TRIANGLES = 4, + TRIANGLE_STRIP = 5, + TRIANGLE_FAN = 6 + }; + + struct Primitive { + std::unordered_map attributes; + size_t indices; + size_t material; + PrimitiveMode mode = PrimitiveMode::TRIANGLES; + std::vector> targets; + }; + + struct Mesh { + std::vector primitives; + std::vector weights; }; struct Model { std::vector accessors; + std::vector meshes; }; template @@ -117,6 +167,49 @@ namespace CesiumGltf { T* _pInteger = nullptr; }; + class BoolJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, bool* pBool) { + JsonHandler::reset(pParent); + this->_pBool = pBool; + } + + virtual JsonHandler* Bool(bool b) override { + assert(this->_pBool); + *this->_pBool = b; + return this->parent(); + } + + private: + bool* _pBool = nullptr; + }; + + class AccessorTypeJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, AccessorType* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; + } + + virtual JsonHandler* String(const char* str, size_t /*length*/, bool /*copy*/) override { + using namespace std::string_literals; + + if ("SCALAR"s == str) *this->_pEnum = AccessorType::SCALAR; + else if ("VEC2"s == str) *this->_pEnum = AccessorType::VEC2; + else if ("VEC3"s == str) *this->_pEnum = AccessorType::VEC3; + else if ("VEC4"s == str) *this->_pEnum = AccessorType::VEC4; + else if ("MAT2"s == str) *this->_pEnum = AccessorType::MAT2; + else if ("MAT3"s == str) *this->_pEnum = AccessorType::MAT3; + else if ("MAT4"s == str) *this->_pEnum = AccessorType::MAT4; + else return nullptr; + + return this->parent(); + } + + private: + AccessorType* _pEnum = nullptr; + }; + class ObjectJsonHandler : public JsonHandler { public: virtual JsonHandler* StartObject() override { @@ -136,25 +229,40 @@ namespace CesiumGltf { IgnoreValueJsonHandler _ignoreHandler; }; - class AccessorJsonHandler : public ObjectJsonHandler { + class DoubleArrayJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, Accessor* pAccessor) { + void reset(JsonHandler* pParent, std::vector* pArray) { JsonHandler::reset(pParent); - this->_pAccessor = pAccessor; + this->_pArray = pArray; + this->_arrayIsOpen = false; } - virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { - using namespace std::string_literals; + virtual JsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return nullptr; + } - assert(this->_pAccessor); - if ("count"s == str) return property(this->_count, this->_pAccessor->count); + this->_arrayIsOpen = true; + return this; + } - return this->ignore(); + virtual JsonHandler* EndArray(size_t) override { + return this->parent(); + } + + virtual JsonHandler* Double(double d) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(d); + return this; } private: - Accessor* _pAccessor = nullptr; - IntegerJsonHandler _count; + std::vector* _pArray = nullptr; + bool _arrayIsOpen = false; }; template @@ -197,6 +305,91 @@ namespace CesiumGltf { THandler _objectHandler; }; + class AccessorJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Accessor* pAccessor) { + JsonHandler::reset(pParent); + this->_pAccessor = pAccessor; + } + + virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { + using namespace std::string_literals; + + assert(this->_pAccessor); + if ("bufferView"s == str) return property(this->_bufferView, this->_pAccessor->bufferView); + if ("byteOffset"s == str) return property(this->_byteOffset, this->_pAccessor->byteOffset); + if ("componentType"s == str) return property(this->_componentType, this->_pAccessor->componentType); + if ("normalized"s == str) return property(this->_normalized, this->_pAccessor->normalized); + if ("count"s == str) return property(this->_count, this->_pAccessor->count); + if ("type"s == str) return property(this->_type, this->_pAccessor->type); + if ("max"s == str) return property(this->_max, this->_pAccessor->max); + if ("min"s == str) return property(this->_min, this->_pAccessor->min); + + return this->ignore(); + } + + private: + Accessor* _pAccessor = nullptr; + IntegerJsonHandler _bufferView; + IntegerJsonHandler _byteOffset; + IntegerJsonHandler _componentType; + BoolJsonHandler _normalized; + IntegerJsonHandler _count; + AccessorTypeJsonHandler _type; + DoubleArrayJsonHandler _max; + DoubleArrayJsonHandler _min; + }; + + class PrimitiveJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Primitive* pPrimitive) { + JsonHandler::reset(pParent); + this->_pPrimitive = pPrimitive; + } + + virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { + using namespace std::string_literals; + + assert(this->_pPrimitive); + if ("indices"s == str) return property(this->_indices, this->_pPrimitive->indices); + if ("material"s == str) return property(this->_material, this->_pPrimitive->material); + if ("mode"s == str) return property(this->_mode, this->_pPrimitive->mode); + + return this->ignore(); + } + + private: + Primitive* _pPrimitive = nullptr; + // std::unordered_map attributes; + IntegerJsonHandler _indices; + IntegerJsonHandler _material; + IntegerJsonHandler _mode; + // std::vector> targets; + }; + + class MeshJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Mesh* pMesh) { + JsonHandler::reset(pParent); + this->_pMesh = pMesh; + } + + virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { + using namespace std::string_literals; + + assert(this->_pMesh); + if ("primitives"s == str) return property(this->_primitives, this->_pMesh->primitives); + if ("weights"s == str) return property(this->_weights, this->_pMesh->weights); + + return this->ignore(); + } + + private: + Mesh* _pMesh = nullptr; + ObjectArrayJsonHandler _primitives; + DoubleArrayJsonHandler _weights; + }; + class ModelJsonHandler : public ObjectJsonHandler { public: void reset(JsonHandler* pParent, Model* pModel) { @@ -209,6 +402,7 @@ namespace CesiumGltf { assert(this->_pModel); if ("accessors"s == str) return property(this->_accessors, this->_pModel->accessors); + if ("meshes"s == str) return property(this->_meshes, this->_pModel->meshes); return this->ignore(); } @@ -216,6 +410,7 @@ namespace CesiumGltf { private: Model* _pModel; ObjectArrayJsonHandler _accessors; + ObjectArrayJsonHandler _meshes; }; class GltfReader final { @@ -233,8 +428,9 @@ namespace CesiumGltf { reader.IterativeParseInit(); - while (!reader.IterativeParseComplete()) { - reader.IterativeParseNext(inputStream, dispatcher); + bool success = true; + while (success && !reader.IterativeParseComplete()) { + success = reader.IterativeParseNext(inputStream, dispatcher); } return result; @@ -476,12 +672,21 @@ namespace CesiumGltf { } TEST_CASE("GltfModel") { - std::string s = "{\"accessors\": [{\"count\": 4}]}"; + std::string s = "{\"accessors\": [{\"count\": 4,\"componentType\":5121,\"type\":\"VEC2\",\"max\":[1.0, 2.2, 3.3],\"min\":[0.0, -1.2]}],\"surprise\":{\"foo\":true}}"; GltfReader reader; Model model = reader.parse(gsl::span(reinterpret_cast(s.c_str()), s.size())); - CHECK(model.accessors.size() == 1); + REQUIRE(model.accessors.size() == 1); CHECK(model.accessors[0].count == 4); + CHECK(model.accessors[0].componentType == ComponentType::UNSIGNED_BYTE); + CHECK(model.accessors[0].type == AccessorType::VEC2); + REQUIRE(model.accessors[0].min.size() == 2); + CHECK(model.accessors[0].min[0] == 0.0); + CHECK(model.accessors[0].min[1] == -1.2); + REQUIRE(model.accessors[0].max.size() == 3); + CHECK(model.accessors[0].max[0] == 1.0); + CHECK(model.accessors[0].max[1] == 2.2); + CHECK(model.accessors[0].max[2] == 3.3); // std::vector v; // GltfModel model = GltfModel::fromMemory(v); // GltfCollection meshes = model.meshes(); From ae16a4888f9c09087e33a35545081ff00aad0ef5 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 4 Jan 2021 17:41:37 +1100 Subject: [PATCH 08/61] Separate files for glTF reader PoC. --- .vscode/settings.json | 6 +- CMakeLists.txt | 1 + .../Cesium3DTiles/TileContentLoadResult.h | 1 - Cesium3DTiles/src/GltfContent.cpp | 2 - CesiumGltf/include/CesiumGltf/Accessor.h | 81 +++ CesiumGltf/include/CesiumGltf/AttributeType.h | 44 ++ CesiumGltf/include/CesiumGltf/ComponentType.h | 58 ++ CesiumGltf/include/CesiumGltf/GltfAccessor.h | 58 -- CesiumGltf/include/CesiumGltf/GltfAnimation.h | 15 - CesiumGltf/include/CesiumGltf/GltfBuffer.h | 26 - .../include/CesiumGltf/GltfBufferView.h | 15 - .../include/CesiumGltf/GltfCollection.h | 127 ---- CesiumGltf/include/CesiumGltf/GltfImage.h | 15 - CesiumGltf/include/CesiumGltf/GltfMaterial.h | 15 - CesiumGltf/include/CesiumGltf/GltfMesh.h | 15 - CesiumGltf/include/CesiumGltf/GltfModel.h | 84 --- CesiumGltf/include/CesiumGltf/GltfNode.h | 15 - CesiumGltf/include/CesiumGltf/GltfSampler.h | 15 - CesiumGltf/include/CesiumGltf/GltfScene.h | 15 - CesiumGltf/include/CesiumGltf/GltfTexture.h | 15 - CesiumGltf/include/CesiumGltf/Mesh.h | 23 + CesiumGltf/include/CesiumGltf/Model.h | 26 + CesiumGltf/include/CesiumGltf/Primitive.h | 51 ++ CesiumGltf/include/CesiumGltf/PrimitiveMode.h | 61 ++ .../include/CesiumGltf/TinyGltfMapping.h | 76 -- CesiumGltf/src/GltfAccessor.cpp | 59 -- CesiumGltf/src/GltfBuffer.cpp | 41 -- CesiumGltf/src/GltfMesh.cpp | 12 - CesiumGltf/src/GltfModel.cpp | 83 --- CesiumGltf/src/Model.cpp | 1 + CesiumGltf/test/TestGltfModel.cpp | 674 +----------------- CesiumGltfReader/CMakeLists.txt | 26 + CesiumGltfReader/include/CesiumGltf/Reader.h | 14 + CesiumGltfReader/src/AccessorJsonHandler.cpp | 26 + CesiumGltfReader/src/AccessorJsonHandler.h | 29 + .../src/AttributeTypeJsonHandler.cpp | 24 + .../src/AttributeTypeJsonHandler.h | 15 + CesiumGltfReader/src/BoolJsonHandler.cpp | 15 + CesiumGltfReader/src/BoolJsonHandler.h | 15 + .../src/DoubleArrayJsonHandler.cpp | 33 + CesiumGltfReader/src/DoubleArrayJsonHandler.h | 18 + .../src/IgnoreValueJsonHandler.cpp | 64 ++ CesiumGltfReader/src/IgnoreValueJsonHandler.h | 29 + CesiumGltfReader/src/IntegerJsonHandler.h | 39 + CesiumGltfReader/src/JsonHandler.cpp | 64 ++ CesiumGltfReader/src/JsonHandler.h | 39 + CesiumGltfReader/src/MeshJsonHandler.cpp | 20 + CesiumGltfReader/src/MeshJsonHandler.h | 22 + CesiumGltfReader/src/ModelJsonHandler.cpp | 20 + CesiumGltfReader/src/ModelJsonHandler.h | 20 + CesiumGltfReader/src/ObjectArrayJsonHandler.h | 47 ++ CesiumGltfReader/src/ObjectJsonHandler.h | 25 + CesiumGltfReader/src/PrimitiveJsonHandler.cpp | 22 + CesiumGltfReader/src/PrimitiveJsonHandler.h | 23 + CesiumGltfReader/src/Reader.cpp | 58 ++ CesiumGltfReader/src/RejectAllJsonHandler.h | 10 + 56 files changed, 1072 insertions(+), 1375 deletions(-) create mode 100644 CesiumGltf/include/CesiumGltf/Accessor.h create mode 100644 CesiumGltf/include/CesiumGltf/AttributeType.h create mode 100644 CesiumGltf/include/CesiumGltf/ComponentType.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfAccessor.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfAnimation.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfBuffer.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfBufferView.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfCollection.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfImage.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfMaterial.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfMesh.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfModel.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfNode.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfSampler.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfScene.h delete mode 100644 CesiumGltf/include/CesiumGltf/GltfTexture.h create mode 100644 CesiumGltf/include/CesiumGltf/Mesh.h create mode 100644 CesiumGltf/include/CesiumGltf/Model.h create mode 100644 CesiumGltf/include/CesiumGltf/Primitive.h create mode 100644 CesiumGltf/include/CesiumGltf/PrimitiveMode.h delete mode 100644 CesiumGltf/include/CesiumGltf/TinyGltfMapping.h delete mode 100644 CesiumGltf/src/GltfAccessor.cpp delete mode 100644 CesiumGltf/src/GltfBuffer.cpp delete mode 100644 CesiumGltf/src/GltfMesh.cpp delete mode 100644 CesiumGltf/src/GltfModel.cpp create mode 100644 CesiumGltf/src/Model.cpp create mode 100644 CesiumGltfReader/CMakeLists.txt create mode 100644 CesiumGltfReader/include/CesiumGltf/Reader.h create mode 100644 CesiumGltfReader/src/AccessorJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AccessorJsonHandler.h create mode 100644 CesiumGltfReader/src/AttributeTypeJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AttributeTypeJsonHandler.h create mode 100644 CesiumGltfReader/src/BoolJsonHandler.cpp create mode 100644 CesiumGltfReader/src/BoolJsonHandler.h create mode 100644 CesiumGltfReader/src/DoubleArrayJsonHandler.cpp create mode 100644 CesiumGltfReader/src/DoubleArrayJsonHandler.h create mode 100644 CesiumGltfReader/src/IgnoreValueJsonHandler.cpp create mode 100644 CesiumGltfReader/src/IgnoreValueJsonHandler.h create mode 100644 CesiumGltfReader/src/IntegerJsonHandler.h create mode 100644 CesiumGltfReader/src/JsonHandler.cpp create mode 100644 CesiumGltfReader/src/JsonHandler.h create mode 100644 CesiumGltfReader/src/MeshJsonHandler.cpp create mode 100644 CesiumGltfReader/src/MeshJsonHandler.h create mode 100644 CesiumGltfReader/src/ModelJsonHandler.cpp create mode 100644 CesiumGltfReader/src/ModelJsonHandler.h create mode 100644 CesiumGltfReader/src/ObjectArrayJsonHandler.h create mode 100644 CesiumGltfReader/src/ObjectJsonHandler.h create mode 100644 CesiumGltfReader/src/PrimitiveJsonHandler.cpp create mode 100644 CesiumGltfReader/src/PrimitiveJsonHandler.h create mode 100644 CesiumGltfReader/src/Reader.cpp create mode 100644 CesiumGltfReader/src/RejectAllJsonHandler.h diff --git a/.vscode/settings.json b/.vscode/settings.json index d19550f28..600e29f74 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -95,7 +95,11 @@ "shared_mutex": "cpp", "gsl_assert": "cpp", "compare": "cpp", - "resumable": "cpp" + "resumable": "cpp", + "codecvt": "cpp", + "ranges": "cpp", + "scoped_allocator": "cpp", + "typeindex": "cpp" }, "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", "cmake.configureOnOpen": true diff --git a/CMakeLists.txt b/CMakeLists.txt index b657fa738..e3a25842b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ add_subdirectory(CesiumUtility) add_subdirectory(CesiumGeometry) add_subdirectory(CesiumGeospatial) add_subdirectory(CesiumGltf) +add_subdirectory(CesiumGltfReader) add_subdirectory(CesiumAsync) add_subdirectory(Cesium3DTiles) diff --git a/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h b/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h index c0816e0d0..76da162fc 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h +++ b/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h @@ -3,7 +3,6 @@ #include "Cesium3DTiles/Tile.h" #include "Cesium3DTiles/TileContext.h" #include "CesiumGeometry/QuadtreeTileRectangularRange.h" -#include "CesiumGltf/GltfModel.h" namespace Cesium3DTiles { diff --git a/Cesium3DTiles/src/GltfContent.cpp b/Cesium3DTiles/src/GltfContent.cpp index 259997d5d..5d24ea404 100644 --- a/Cesium3DTiles/src/GltfContent.cpp +++ b/Cesium3DTiles/src/GltfContent.cpp @@ -5,8 +5,6 @@ #include "CesiumUtility/Math.h" #include -using namespace CesiumGltf; - namespace Cesium3DTiles { /*static*/ std::unique_ptr GltfContent::load( diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h new file mode 100644 index 000000000..5692b7606 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -0,0 +1,81 @@ +#pragma once + +#include "AttributeType.h" +#include "ComponentType.h" +#include +#include + +namespace CesiumGltf { + /** + * @brief A typed view into a {@link BufferView}. + * + * A {@link BufferView} contains raw binary data. An accessor provides a typed view into a + * `BufferView` or a subset of a `BufferView` similar to how WebGL's `vertexAttribPointer()` + * defines an attribute in a buffer. + */ + struct Accessor { + /** + * @brief The index of the `BufferView` in {@link Model::bufferViews}. + * + * When this value is less than 0, no `BufferView` is associated with this accessor. + * The accessor should be treated as being initialized with all zeros. The `sparse` + * property or extensions may override the zeros with actual values. + */ + int32_t bufferView = -1; + + /** + * @brief The offset relative to the start of the {@link Accessor::bufferView} in bytes. + * + * This must be a multiple of the size of the component datatype. + */ + int64_t byteOffset = 0; + + /** + * @brief The datatype of components in the attribute. + */ + ComponentType componentType = ComponentType::FLOAT; + + /** + * @brief Specifies whether integer data values should be normalized. + * + * Specifies whether integer data values should be normalized (`true`) to [0, 1] (for unsigned types) or + * [-1, 1] (for signed types), or converted directly (`false`) when they are accessed. This property is + * meaningful only for accessors that contain vertex attributes or animation output data. + */ + bool normalized = false; + + /** + * @brief The number of attributes referenced by this accessor. + * + * Not to be confused with the number of bytes or number of components. + */ + int64_t count = 0; + + /** + * @brief Specifies if the attribute is a scalar, vector, or matrix. + */ + AttributeType type = AttributeType::SCALAR; + + /** + * @brief Maximum value of each component in this attribute. + * + * Array elements must be treated as having the same data type as accessor's {@link Accessor::componentType}. Both min + * and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. + * + * The {@link Accessor::normalized} property has no effect on array values: they always correspond to the actual values stored in the buffer. + * When accessor is sparse, this property must contain max values of accessor data with sparse substitution applied. + */ + std::vector max; + + /** + * @brief Minimum value of each component in this attribute. + * + * Array elements must be treated as having the same data type as accessor's {@link Accessor::componentType}. Both min + * and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. + * + * The {@link Accessor::normalized} property has no effect on array values: they always correspond to the actual values stored in the buffer. + * When accessor is sparse, this property must contain min values of accessor data with sparse substitution applied. + */ + std::vector min; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/AttributeType.h b/CesiumGltf/include/CesiumGltf/AttributeType.h new file mode 100644 index 000000000..aa795ea37 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AttributeType.h @@ -0,0 +1,44 @@ +#pragma once + +namespace CesiumGltf { + /** + * @brief Specifies if the attribute is a scalar, vector, or matrix. + */ + enum class AttributeType { + /** + * @brief The attribute is a scalar, i.e. a single numeric value. + */ + SCALAR, + + /** + * @brief The attribute is a 2D vector, i.e. two numeric values. + */ + VEC2, + + /** + * @brief The attribute is a 3D vector, i.e. three numeric values. + */ + VEC3, + + /** + * @brief The attribute is a 4D vector, i.e. four numeric values. + */ + VEC4, + + /** + * @brief The attribute is a 2x2 matrix in column-major order, i.e. four numeric values. + */ + MAT2, + + /** + * @brief The attribute is a 3x3 matrix in column-major order, i.e. nine numeric values. + */ + MAT3, + + /** + * @brief The attribute is a 4x4 matrix in column-major order, i.e. sixtreen numeric values. + * + */ + MAT4 + }; +} diff --git a/CesiumGltf/include/CesiumGltf/ComponentType.h b/CesiumGltf/include/CesiumGltf/ComponentType.h new file mode 100644 index 000000000..eddc68af1 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/ComponentType.h @@ -0,0 +1,58 @@ +#pragma once + +namespace CesiumGltf { + /** + * @brief The datatype of components in the attribute. + * + * The datatype of components in the attribute. All valid values correspond to WebGL enums. + * The corresponding typed arrays are `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Uint32Array`, + * and `Float32Array`, respectively. 5125 (UNSIGNED_INT) is only allowed when the accessor contains + * indices, i.e., the accessor is only referenced by `primitive.indices`. + */ + enum class ComponentType { + /** + * @brief A single-byte (8-bit), signed integer. + * + * Corresponds to C++11's `int8_t` or JavaScript's `Int8Array`. + */ + BYTE = 5120, + + /** + * @brief A single-byte (8-bit), unsigned integer. + * + * Corresponds to C++11's `uint8_t` or JavaScript's `Uint8Array`. + */ + UNSIGNED_BYTE = 5121, + + /** + * @brief A two-byte (16-bit), signed integer. + * + * Corresponds to C++11's `int16_t` or JavaScript's `Int16Array`. + */ + SHORT = 5122, + + /** + * @brief A two-byte (16-bit), unsigned integer. + * + * Corresponds to C++11's `uint16_t` or JavaScript's `Uint16Array`. + */ + UNSIGNED_SHORT = 5123, + + /** + * @brief A four-byte (32-bit), unsigned integer. + * + * Corresponds to C++11's `uint32_t` or JavaScript's `Uint32Array`. + * + * This component type is only allowed for accessors that only contain indices, + * i.e. the accessor is only referenced by `primitive.indices`. + */ + UNSIGNED_INT = 5125, + + /** + * @brief A four-byte (32-bit), floating-point number. + * + * Corresponds to C++'s `float` or JavaScript's `Float32Array`. + */ + FLOAT = 5126 + }; +} diff --git a/CesiumGltf/include/CesiumGltf/GltfAccessor.h b/CesiumGltf/include/CesiumGltf/GltfAccessor.h deleted file mode 100644 index fbd16ef8f..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfAccessor.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -namespace tinygltf { - struct Accessor; -} - -namespace CesiumGltf { - template - class GltfCollection; - - class GltfAccessor; - - #define CESIUM_GLTF_CONST_WRAPPER_DECL(Type, WrappedType) \ - public: \ - Type##Const(); \ - Type##Const(const Type##Const& rhs); \ - Type##Const(Type##Const&& rhs) = delete; \ - ~Type##Const(); \ - Type##Const& operator=(const Type##Const& rhs) = delete; \ - Type##Const& operator=(Type##Const&& rhs) = delete; \ - private: \ - using Tiny = WrappedType; \ - Type##Const(const WrappedType* p); \ - const WrappedType* _p; \ - bool _owns; \ - template \ - friend class GltfCollection; \ - friend class GltfAccessor; - - #define CESIUM_GLTF_MUTABLE_WRAPPER_DECL(Type, WrappedType) \ - public: \ - Type(); \ - Type(const Type& rhs); \ - Type(Type&& rhs); \ - Type(const Type##Const& rhs); \ - Type(Type##Const&& rhs); \ - Type& operator=(const Type& rhs); \ - Type& operator=(Type&& rhs); \ - Type& operator=(const Type##Const& rhs); \ - private: \ - using Const = Type##Const; \ - Type(WrappedType* p); \ - Tiny*& tiny() { return const_cast(this->_p); } - - class GltfAccessorConst { - public: - size_t getCount() const; - - CESIUM_GLTF_CONST_WRAPPER_DECL(GltfAccessor, tinygltf::Accessor); - }; - - class GltfAccessor final : public GltfAccessorConst { - public: - void setCount(size_t value); - - CESIUM_GLTF_MUTABLE_WRAPPER_DECL(GltfAccessor, tinygltf::Accessor); - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfAnimation.h b/CesiumGltf/include/CesiumGltf/GltfAnimation.h deleted file mode 100644 index fed80d0d5..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfAnimation.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct cgltf_animation; - -namespace CesiumGltf { - class GltfAnimation { - public: - static GltfAnimation createFromCollectionElement(cgltf_animation* array, size_t arrayIndex); - - private: - GltfAnimation(cgltf_animation* p); - - cgltf_animation* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfBuffer.h b/CesiumGltf/include/CesiumGltf/GltfBuffer.h deleted file mode 100644 index 884dd9d40..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfBuffer.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include -#include - -// struct cgltf_buffer; - -namespace CesiumGltf { - class GltfBuffer { - public: - // static GltfBuffer createFromCollectionElement(cgltf_buffer* array, size_t arrayIndex); - - std::string getUri() const noexcept; - void setUri(const std::string& value) noexcept; - - gsl::span getData() noexcept; - gsl::span getData() const noexcept; - void setData(const gsl::span& value) noexcept; - void resizeData(size_t newSize) noexcept; - - private: - // GltfBuffer(cgltf_buffer* p); - - // cgltf_buffer* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfBufferView.h b/CesiumGltf/include/CesiumGltf/GltfBufferView.h deleted file mode 100644 index 7d2418ccd..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfBufferView.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct cgltf_buffer_view; - -namespace CesiumGltf { - class GltfBufferView { - public: - static GltfBufferView createFromCollectionElement(cgltf_buffer_view* array, size_t arrayIndex); - - private: - GltfBufferView(cgltf_buffer_view* p); - - cgltf_buffer_view* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfCollection.h b/CesiumGltf/include/CesiumGltf/GltfCollection.h deleted file mode 100644 index a07243b53..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfCollection.h +++ /dev/null @@ -1,127 +0,0 @@ -#pragma once - -#include "CesiumGltf/TinyGltfMapping.h" -#include -#include -#include - -namespace CesiumGltf { - template - class GltfCollection { - public: - - class const_iterator { - public: - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = int64_t; - using pointer = T*; - using reference = const value_type&; - - const_iterator(typename Impl::CesiumToTinyGltf::tinygltf_type* pElements, size_t numberOfElements, size_t currentElement) noexcept : - _pElements(pElements), - _numberOfElements(numberOfElements), - _currentElement(currentElement), - _temporary() - { - } - - const T& operator*() const noexcept { - this->_fill(); - return this->_temporary.value(); - } - - const T* operator->() const { - this->_fill(); - return &this->_temporary.value(); - } - - const_iterator& operator++() noexcept { - ++this->_currentElement; - this->_temporary.reset(); - return *this; - } - - const_iterator operator++(int) noexcept { - const_iterator copy = *this; - ++*this; - this->_temporary.reset(); - return copy; - } - - bool operator==(const const_iterator& rhs) const noexcept { - return - this->_currentElement == rhs._currentElement && - this->_pElements == rhs._pElements; - } - - bool operator!=(const const_iterator& rhs) const noexcept { - return !(*this == rhs); - } - - private: - void _fill() const { - if (!this->_temporary) { - assert(this->_currentElement < this->_numberOfElements); - this->_temporary = Impl::CesiumGltfObjectFactory::createFromCollectionElement(this->_pElements, this->_currentElement); - } - } - - std::vector::tinygltf_type>* _pElements; - size_t _currentElement; - mutable std::optional _temporary; - }; - - using vector_type = std::conditional_t< - std::is_const::value, - std::vector>::tinygltf_type>, - std::vector>::tinygltf_type> - >; - - GltfCollection(vector_type* pElements) : - _pElements(ppElements) - { - } - - using value_type = T; - - size_t size() const noexcept { - return this->_pElements->size(); - } - - const_iterator begin() noexcept { - return { - this->_pElements, - 0 - }; - } - - const_iterator end() noexcept { - return { - this->_pElements, - this->_pElements->size() - }; - } - - T operator[](size_t index) const noexcept { - return Impl::CesiumGltfObjectFactory::createFromCollectionElement(&this->_pElements[index]); - } - - void push_back(const T& item) { - this->_pElements->push_back(*item._p); - } - - void push_back(T&& item) { - this->_pElements->push_back(std::move(*item._p)); - } - - T emplace_back() { - return T(&this->_pElements->emplace_back()); - } - - private: - using tinygltf_type = typename Impl::CesiumToTinyGltf::tinygltf_type; - std::vector* _pElements; - }; - -} diff --git a/CesiumGltf/include/CesiumGltf/GltfImage.h b/CesiumGltf/include/CesiumGltf/GltfImage.h deleted file mode 100644 index 5a10d5343..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfImage.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct cgltf_image; - -namespace CesiumGltf { - class GltfImage { - public: - static GltfImage createFromCollectionElement(cgltf_image* array, size_t arrayIndex); - - private: - GltfImage(cgltf_image* p); - - cgltf_image* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfMaterial.h b/CesiumGltf/include/CesiumGltf/GltfMaterial.h deleted file mode 100644 index cf61505d9..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfMaterial.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct cgltf_material; - -namespace CesiumGltf { - class GltfMaterial { - public: - static GltfMaterial createFromCollectionElement(cgltf_material* array, size_t arrayIndex); - - private: - GltfMaterial(cgltf_material* p); - - cgltf_material* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfMesh.h b/CesiumGltf/include/CesiumGltf/GltfMesh.h deleted file mode 100644 index 80fc0c55b..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfMesh.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct cgltf_mesh; - -namespace CesiumGltf { - class GltfMesh { - public: - static GltfMesh createFromCollectionElement(cgltf_mesh* array, size_t arrayIndex); - - private: - GltfMesh(cgltf_mesh* p); - - cgltf_mesh* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfModel.h b/CesiumGltf/include/CesiumGltf/GltfModel.h deleted file mode 100644 index 92d9ee412..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfModel.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include "CesiumGltf/GltfCollection.h" -#include "CesiumGltf/GltfAccessor.h" -#include "CesiumGltf/GltfAnimation.h" -#include "CesiumGltf/GltfBuffer.h" -#include "CesiumGltf/GltfBufferView.h" -#include "CesiumGltf/GltfImage.h" -#include "CesiumGltf/GltfMaterial.h" -#include "CesiumGltf/GltfMesh.h" -#include "CesiumGltf/GltfNode.h" -#include "CesiumGltf/GltfSampler.h" -#include "CesiumGltf/GltfScene.h" -#include "CesiumGltf/GltfTexture.h" -#include -#include -#include -#include - -namespace CesiumGltf { - - template - class GltfConstPointer final { - public: - const T& operator*() const noexcept { return this->_obj; } - const T* operator->() const noexcept { return &this->_obj; } - - private: - GltfConstPointer(const typename T::tinygltf_type* p) noexcept : - _obj(p) - { - } - - const T _obj; - }; - - template - class GltfPointer final { - public: - T& operator*() const noexcept { return this->_obj; } - T* operator->() const noexcept { return &this->_obj; } - - private: - GltfPointer(typename T::tinygltf_type* p) noexcept : - _obj(p) - { - } - - T _obj; - }; - - class GltfModel final { - public: - static GltfModel fromMemory(gsl::span pData); - - GltfModel(); - - // GltfCollection extensionsUsed() const noexcept; - // GltfCollection extensionsUsed() noexcept; - - // GltfCollection extensionsRequired() const noexcept; - GltfCollection accessors() const noexcept; - // GltfCollection animations() const noexcept; - // GltfAsset asset() const noexcept; - // GltfCollection buffers() const noexcept; - // GltfCollection bufferViews() const noexcept; - // GltfCollection cameras() const noexcept; - // GltfCollection images() const noexcept; - // GltfCollection materials() const noexcept; - // GltfCollection meshes() const noexcept; - // GltfCollection nodes() const noexcept; - // GltfCollection samplers() const noexcept; - // size_t scene() const noexcept; - // GltfCollection scenes() const noexcept; - // GltfCollection skins() const noexcept; - // GltfCollection textures() const noexcept; - - private: - GltfModel(tinygltf::Model&& model); - - tinygltf::Model _model; - }; - -} diff --git a/CesiumGltf/include/CesiumGltf/GltfNode.h b/CesiumGltf/include/CesiumGltf/GltfNode.h deleted file mode 100644 index 5a496b333..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfNode.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct cgltf_node; - -namespace CesiumGltf { - class GltfNode { - public: - static GltfNode createFromCollectionElement(cgltf_node* array, size_t arrayIndex); - - private: - GltfNode(cgltf_node* p); - - cgltf_node* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfSampler.h b/CesiumGltf/include/CesiumGltf/GltfSampler.h deleted file mode 100644 index 8e224f4a7..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfSampler.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct cgltf_sampler; - -namespace CesiumGltf { - class GltfSampler { - public: - static GltfSampler createFromCollectionElement(cgltf_sampler* array, size_t arrayIndex); - - private: - GltfSampler(cgltf_sampler* p); - - cgltf_sampler* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfScene.h b/CesiumGltf/include/CesiumGltf/GltfScene.h deleted file mode 100644 index 860d9915d..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfScene.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct cgltf_scene; - -namespace CesiumGltf { - class GltfScene { - public: - static GltfScene createFromCollectionElement(cgltf_scene* array, size_t arrayIndex); - - private: - GltfScene(cgltf_scene* p); - - cgltf_scene* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/GltfTexture.h b/CesiumGltf/include/CesiumGltf/GltfTexture.h deleted file mode 100644 index cc828739a..000000000 --- a/CesiumGltf/include/CesiumGltf/GltfTexture.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct cgltf_texture; - -namespace CesiumGltf { - class GltfTexture { - public: - static GltfTexture createFromCollectionElement(cgltf_texture* array, size_t arrayIndex); - - private: - GltfTexture(cgltf_texture* p); - - cgltf_texture* _p; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/Mesh.h b/CesiumGltf/include/CesiumGltf/Mesh.h new file mode 100644 index 000000000..ba95f9768 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Mesh.h @@ -0,0 +1,23 @@ +#pragma once + +#include "CesiumGltf/Primitive.h" +#include + +namespace CesiumGltf { + /** + * @brief A set of primitives to be rendered. + * + * A {@link Node} can contain one mesh. A node's transform places the mesh in the scene. + */ + struct Mesh { + /** + * @brief An array of primitives, each defining geometry to be rendered with a material. + */ + std::vector primitives; + + /** + * @brief Array of weights to be applied to the Morph Targets. + */ + std::vector weights; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h new file mode 100644 index 000000000..7dee64cd6 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -0,0 +1,26 @@ +#pragma once + +#include "CesiumGltf/Accessor.h" +#include "CesiumGltf/Mesh.h" +#include + +namespace CesiumGltf { + /** + * @brief A glTF model. + */ + struct Model { + /** + * @brief An array of accessors. + * + * An accessor is a typed view into a {@link BufferView}. + */ + std::vector accessors; + + /** + * @brief An array of meshes. + * + * A mesh is a set of {@link Primitive} instances to be rendered. + */ + std::vector meshes; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Primitive.h b/CesiumGltf/include/CesiumGltf/Primitive.h new file mode 100644 index 000000000..34e41aae6 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Primitive.h @@ -0,0 +1,51 @@ +#pragma once + +#include "CesiumGltf/PrimitiveMode.h" +#include +#include +#include +#include + +namespace CesiumGltf { + struct Primitive { + /** + * @brief A dictionary object, where each key corresponds to mesh attribute semantic and each value is the index of the accessor containing attribute's data. + */ + std::unordered_map attributes; + + /** + * @brief The index of the accessor that contains the indices. + * + * The index of the accessor in {@link Model::accessors} that contains mesh indices. When this is not defined (-1), the primitives should be + * rendered without indices using `drawArrays()`. When defined, the accessor must contain indices: the {@link BufferView} referenced by the + * accessor should have a {@link BufferView::target} equal to {@link BufferViewTarget::ELEMENT_ARRAY_BUFFER}; componentType must be + * {@link ComponentType::UNSIGNED_BYTE}, {@link ComponentType::UNSIGNED_SHORT} or {@link ComponentType::UNSIGNED_INT}, the latter may + * require enabling additional hardware support; {@link Accessor::type} must be {@link AccessorType::SCALAR}. For triangle primitives, the front face has a + * counter-clockwise (CCW) winding order. + * + * Values of the index accessor must not include the maximum value for the given component type, which triggers primitive restart in several graphics APIs + * and would require client implementations to rebuild the index buffer. Primitive restart values are disallowed and all index values must refer to actual + * vertices. As a result, the index accessor's values must not exceed the following maxima: {@link ComponentType::BYTE} `< 255`, + * {@link ComponentType::UNSIGNED_SHORT} `< 65535`, {@link ComponentType::UNSIGNED_INT} `< 4294967295`. + */ + int32_t indices = -1; + + /** + * @brief The index of the material to apply to this primitive when rendering. + * + * When this value is not defined (-1), the default material is used. + */ + int32_t material = -1; + + /** + * @brief The type of primitives to render. + */ + PrimitiveMode mode = PrimitiveMode::TRIANGLES; + + /** + * @brief An array of Morph Targets, each Morph Target is a dictionary mapping attributes + * (only `POSITION`, `NORMAL`, and `TANGENT` supported) to their deviations in the Morph Target. + */ + std::vector> targets; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/PrimitiveMode.h b/CesiumGltf/include/CesiumGltf/PrimitiveMode.h new file mode 100644 index 000000000..0566a2f37 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/PrimitiveMode.h @@ -0,0 +1,61 @@ +#pragma once + +namespace CesiumGltf { + /** + * @brief The type of primitives to render. + * + * All valid values correspond to WebGL enums. + */ + enum class PrimitiveMode { + /** + * @brief Points. + * + * A single dot at each vertex. + */ + POINTS = 0, + + /** + * @brief Lines. + * + * Straight lines between pairs of vertices. + */ + LINES = 1, + + /** + * @brief A line loop. + * + * Straight lines to each vertex in succession, and the last vertex connected back to the rfirst. + */ + LINE_LOOP = 2, + + /** + * @brief A line strip. + * + * Straight lines to each vertex in succession. + */ + LINE_STRIP = 3, + + /** + * @brief Triangles. + * + * A triangle for each group of three vertices. + */ + TRIANGLES = 4, + + /** + * @brief A triangle strip. + * + * The first three vertices define the first triangle, and each single vertex thereafter defines an + * additional triangle by connecting with the previous two vertices. + */ + TRIANGLE_STRIP = 5, + + /** + * @brief A triangle fan. + * + * The first three vertices define the first triangle, and each successive vertex defines another triangle + * fanning around the very first vertex. + */ + TRIANGLE_FAN = 6 + }; +} diff --git a/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h b/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h deleted file mode 100644 index 50b9ed81e..000000000 --- a/CesiumGltf/include/CesiumGltf/TinyGltfMapping.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include - -// namespace tinygltf { -// struct Accessor; -// struct Animation; -// struct Buffer; -// struct BufferView; -// struct Image; -// struct Material; -// struct Mesh; -// struct Node; -// struct Sampler; -// struct Scene; -// struct Texture; -// } - -namespace CesiumGltf { - - class GltfAccessor; - class GltfAnimation; - class GltfBuffer; - class GltfBufferView; - class GltfImage; - class GltfMaterial; - class GltfMesh; - class GltfNode; - class GltfSampler; - class GltfScene; - class GltfTexture; - - namespace Impl { - template - struct CesiumToTinyGltf { - using tinygltf_type = typename T::tinygltf_type; - }; - - template <> - struct CesiumToTinyGltf { - using tinygltf_type = std::string; - }; - - template <> - struct CesiumToTinyGltf { - using tinygltf_type = const std::string; - }; - - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Accessor; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Animation; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Buffer; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::BufferView; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Image; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Material; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Mesh; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Node; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Sampler; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Scene; }; - // template <> struct CesiumToTinyGltf { using tinygltf_type = tinygltf::Texture; }; - - template - struct CesiumGltfObjectFactory { - static T createFromCollectionElement(typename T::tinygltf_type* pElement) { - return T(pElement); - } - }; - - template <> - struct CesiumGltfObjectFactory { - static std::string createFromCollectionElement(std::string* pElement) { - return *pElement; - } - }; - } - -} diff --git a/CesiumGltf/src/GltfAccessor.cpp b/CesiumGltf/src/GltfAccessor.cpp deleted file mode 100644 index 14bea1d00..000000000 --- a/CesiumGltf/src/GltfAccessor.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "CesiumGltf/GltfAccessor.h" -#include - -#define CESIUM_GLTF_WRAPPER_IMPL(Type) \ - Type##Const::Type##Const() : \ - _p(new Tiny()), \ - _owns(true) \ - {} \ - Type##Const::Type##Const(const Type##Const& rhs) : \ - _p(new Tiny(*rhs._p)), \ - _owns(true) \ - {} \ - Type##Const::~Type##Const() { \ - if (this->_owns) { \ - delete this->_p; \ - } \ - } \ - Type##Const::Type##Const(const Tiny* p) : \ - _p(p), \ - _owns(false) \ - {} \ - Type::Type() : Type##Const() {} \ - Type::Type(const Type& rhs) : Type##Const(rhs) {} \ - Type::Type(GltfAccessor&& rhs) : \ - Type(static_cast(std::move(rhs))) \ - {} \ - Type::Type(const Type##Const& rhs) : \ - Type##Const(rhs) \ - {} \ - Type::Type(Type##Const&& rhs) : \ - Type##Const(std::exchange(rhs._p, nullptr)) \ - { \ - this->_owns = rhs._owns; \ - } \ - Type& Type::operator=(const Type& rhs) { \ - *this->tiny() = *rhs._p; \ - return *this; \ - } \ - Type& Type::operator=(Type&& rhs) { \ - std::swap(this->_p, rhs._p); \ - std::swap(this->_owns, rhs._owns); \ - return *this; \ - } \ - Type& Type::operator=(const Type##Const& rhs) { \ - *this->tiny() = *rhs._p; \ - return *this; \ - } - -namespace CesiumGltf { - CESIUM_GLTF_WRAPPER_IMPL(GltfAccessor); - - size_t GltfAccessorConst::getCount() const { - return this->_p->count; - } - - void GltfAccessor::setCount(size_t value) { - this->tiny()->count = value; - } -} diff --git a/CesiumGltf/src/GltfBuffer.cpp b/CesiumGltf/src/GltfBuffer.cpp deleted file mode 100644 index 026fd094b..000000000 --- a/CesiumGltf/src/GltfBuffer.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "CesiumGltf/GltfBuffer.h" -#include - -namespace CesiumGltf { - // /*static*/ GltfBuffer GltfBuffer::createFromCollectionElement(cgltf_buffer* array, size_t arrayIndex) { - // return GltfBuffer(&array[arrayIndex]); - // } - - // GltfBuffer::GltfBuffer(cgltf_buffer* p) : - // _p(p) - // { - // } - - // std::string GltfBuffer::getUri() const noexcept { - // return this->_p->uri; - // } - - // void GltfBuffer::setUri(const std::string& value) noexcept { - // this->_p->uri = static_cast(realloc(this->_p->uri, value.size() + 1)); - // value.copy(this->_p->uri, value.size(), 0); - // this->_p->uri[value.size()] = '\0'; - // } - - // gsl::span GltfBuffer::getData() const noexcept { - // return gsl::span(static_cast(this->_p->data), this->_p->size); - // } - - // gsl::span GltfBuffer::getData() noexcept { - // return gsl::span(static_cast(this->_p->data), this->_p->size); - // } - - // void GltfBuffer::setData(const gsl::span& value) noexcept { - // this->_p->data = realloc(this->_p->data, value.size()); - // std::copy(value.begin(), value.end(), static_cast(this->_p->data)); - // } - - // void GltfBuffer::resizeData(size_t newSize) noexcept { - // this->_p->data = realloc(this->_p->data, newSize); - // } - -} diff --git a/CesiumGltf/src/GltfMesh.cpp b/CesiumGltf/src/GltfMesh.cpp deleted file mode 100644 index 724c4a32b..000000000 --- a/CesiumGltf/src/GltfMesh.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "CesiumGltf/GltfMesh.h" - -namespace CesiumGltf { - // /*static*/ GltfMesh GltfMesh::createFromCollectionElement(cgltf_mesh* array, size_t arrayIndex) { - // return GltfMesh(&array[arrayIndex]); - // } - - // GltfMesh::GltfMesh(cgltf_mesh* p) : - // _p(p) - // { - // } -} diff --git a/CesiumGltf/src/GltfModel.cpp b/CesiumGltf/src/GltfModel.cpp deleted file mode 100644 index 3f05f0b3d..000000000 --- a/CesiumGltf/src/GltfModel.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "CesiumGltf/GltfModel.h" -#include "CesiumGltf/GltfMesh.h" -#include - -namespace CesiumGltf { - - /*static*/ GltfModel GltfModel::fromMemory(gsl::span data) { - GltfModel result; - std::string warnings; - std::string errors; - tinygltf::TinyGLTF loader; - /*bool success =*/ loader.LoadBinaryFromMemory(&result._model, &errors, &warnings, data.data(), static_cast(data.size())); - return result; - // cgltf_options options{}; - // cgltf_data* pResult = nullptr; - // cgltf_result resultCode = cgltf_parse(&options, data.data(), data.size(), &pResult); - // if (resultCode == cgltf_result_success) { - // return GltfModel(pResult); - // } else { - // switch (resultCode) { - // case cgltf_result_data_too_short: - // throw std::runtime_error("glTF data is too short."); - // case cgltf_result_unknown_format: - // throw std::runtime_error("glTF is in an unknown format."); - // case cgltf_result_invalid_json: - // throw std::runtime_error("glTF JSON is invalid."); - // case cgltf_result_invalid_gltf: - // throw std::runtime_error("glTF is invalid."); - // case cgltf_result_invalid_options: - // throw std::runtime_error("glTF parsed with invalid options."); - // case cgltf_result_file_not_found: - // throw std::runtime_error("glTF file was not found."); - // case cgltf_result_io_error: - // throw std::runtime_error("I/O error while parsing glTF."); - // case cgltf_result_out_of_memory: - // throw std::runtime_error("Out of memory while parsing glTF."); - // case cgltf_result_legacy_gltf: - // throw std::runtime_error("glTF uses an unsupported legacy format."); - // default: - // throw std::runtime_error("An unknown error occurred while parsing a glTF."); - // } - // } - } - - // cgltf_asset asset; - - // cgltf_mesh* meshes; - // cgltf_material* materials; - // cgltf_accessor* accessors; - // cgltf_buffer_view* buffer_views; - // cgltf_buffer* buffers; - // cgltf_image* images; - // cgltf_texture* textures; - // cgltf_sampler* samplers; - // cgltf_skin* skins; - // cgltf_camera* cameras; - // cgltf_light* lights; - // cgltf_node* nodes; - // cgltf_scene* scenes; - // cgltf_scene* scene; - // cgltf_animation* animations; - - // GltfCollection GltfModel::extensionsUsed() const noexcept { - // return GltfCollection(&this->_model.extensionsUsed); - // } - - // GltfCollection GltfModel::extensionsRequired() const noexcept { - // return { &this->_model.extensionsRequired }; - // } - - // GltfCollection GltfModel::meshes() const noexcept { - // return { &this->_pData->meshes, &this->_pData->meshes_count }; - // } - - // GltfCollection GltfModel::accessors() const noexcept { - // return { &this->_pData->accessors, &this->_pData->accessors_count }; - // } - - // GltfModel::GltfModel(tinygltf::Model&& model) : - // _model(std::move(model)) - // { - // } -} diff --git a/CesiumGltf/src/Model.cpp b/CesiumGltf/src/Model.cpp new file mode 100644 index 000000000..5865dd096 --- /dev/null +++ b/CesiumGltf/src/Model.cpp @@ -0,0 +1 @@ +#include "CesiumGltf/Model.h" diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index 0a59bf8a6..f3532269e 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -1,685 +1,19 @@ #include "catch2/catch.hpp" -#include "CesiumGltf/GltfModel.h" +#include "CesiumGltf/Reader.h" #include #include #include using namespace CesiumGltf; -namespace CesiumGltf { - class JsonHandler { - public: - virtual JsonHandler* Null() { return nullptr; } - virtual JsonHandler* Bool(bool /*b*/) { return nullptr; } - virtual JsonHandler* Int(int /*i*/) { return nullptr; } - virtual JsonHandler* Uint(unsigned /*i*/) { return nullptr; } - virtual JsonHandler* Int64(int64_t /*i*/) { return nullptr; } - virtual JsonHandler* Uint64(uint64_t /*i*/) { return nullptr; } - virtual JsonHandler* Double(double /*d*/) { return nullptr; } - virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return nullptr; } - virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return nullptr; } - virtual JsonHandler* StartObject() { return nullptr; } - virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return nullptr; } - virtual JsonHandler* EndObject(size_t /*memberCount*/) { return nullptr; } - virtual JsonHandler* StartArray() { return nullptr; } - virtual JsonHandler* EndArray(size_t /*elementCount*/) { return nullptr; } - - template - JsonHandler* property(TAccessor& accessor, TProperty& value) { - accessor.reset(this, &value); - return &accessor; - } - - JsonHandler* parent() { - return this->_pParent; - } - - protected: - void reset(JsonHandler* pParent) { - this->_pParent = pParent; - } - - private: - JsonHandler* _pParent = nullptr; - }; - - class IgnoreValueJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent) { - JsonHandler::reset(pParent); - this->_depth = 0; - } - - virtual JsonHandler* Null() override { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Bool(bool /*b*/) override { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Int(int /*i*/) override { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Uint(unsigned /*i*/) override { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Int64(int64_t /*i*/) override { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Uint64(uint64_t /*i*/) override { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* Double(double /*d*/) override { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) override { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/) override { return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* StartObject() override { ++this->_depth; return this; } - virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) override { return this; } - virtual JsonHandler* EndObject(size_t /*memberCount*/) override { --this->_depth; return this->_depth == 0 ? this->parent() : this; } - virtual JsonHandler* StartArray() override { ++this->_depth; return this; } - virtual JsonHandler* EndArray(size_t /*elementCount*/) override { --this->_depth; return this->_depth == 0 ? this->parent() : this; } - - private: - size_t _depth = 0; - }; - - class RejectAllJsonHandler : public JsonHandler { - public: - RejectAllJsonHandler() { - reset(this); - } - }; - - enum class ComponentType { - BYTE = 5120, - UNSIGNED_BYTE = 5121, - SHORT = 5122, - UNSIGNED_SHORT = 5123, - UNSIGNED_INT = 5125, - FLOAT = 5126 - }; - - enum class AccessorType { - SCALAR, - VEC2, - VEC3, - VEC4, - MAT2, - MAT3, - MAT4 - }; - - struct Accessor { - size_t bufferView; - size_t byteOffset = 0; - ComponentType componentType; - bool normalized = false; - size_t count; - AccessorType type; - std::vector max; - std::vector min; - }; - - enum class PrimitiveMode { - POINTS = 0, - LINES = 1, - LINE_LOOP = 2, - LINE_STRIP = 3, - TRIANGLES = 4, - TRIANGLE_STRIP = 5, - TRIANGLE_FAN = 6 - }; - - struct Primitive { - std::unordered_map attributes; - size_t indices; - size_t material; - PrimitiveMode mode = PrimitiveMode::TRIANGLES; - std::vector> targets; - }; - - struct Mesh { - std::vector primitives; - std::vector weights; - }; - - struct Model { - std::vector accessors; - std::vector meshes; - }; - - template - class IntegerJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent, T* pInteger) { - JsonHandler::reset(pParent); - this->_pInteger = pInteger; - } - - virtual JsonHandler* Int(int i) override { - assert(this->_pInteger); - *this->_pInteger = static_cast(i); - return this->parent(); - } - virtual JsonHandler* Uint(unsigned i) override { - assert(this->_pInteger); - *this->_pInteger = static_cast(i); - return this->parent(); - } - virtual JsonHandler* Int64(int64_t i) override { - assert(this->_pInteger); - *this->_pInteger = static_cast(i); - return this->parent(); - } - virtual JsonHandler* Uint64(uint64_t i) override { - assert(this->_pInteger); - *this->_pInteger = static_cast(i); - return this->parent(); - } - - private: - T* _pInteger = nullptr; - }; - - class BoolJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent, bool* pBool) { - JsonHandler::reset(pParent); - this->_pBool = pBool; - } - - virtual JsonHandler* Bool(bool b) override { - assert(this->_pBool); - *this->_pBool = b; - return this->parent(); - } - - private: - bool* _pBool = nullptr; - }; - - class AccessorTypeJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent, AccessorType* pEnum) { - JsonHandler::reset(pParent); - this->_pEnum = pEnum; - } - - virtual JsonHandler* String(const char* str, size_t /*length*/, bool /*copy*/) override { - using namespace std::string_literals; - - if ("SCALAR"s == str) *this->_pEnum = AccessorType::SCALAR; - else if ("VEC2"s == str) *this->_pEnum = AccessorType::VEC2; - else if ("VEC3"s == str) *this->_pEnum = AccessorType::VEC3; - else if ("VEC4"s == str) *this->_pEnum = AccessorType::VEC4; - else if ("MAT2"s == str) *this->_pEnum = AccessorType::MAT2; - else if ("MAT3"s == str) *this->_pEnum = AccessorType::MAT3; - else if ("MAT4"s == str) *this->_pEnum = AccessorType::MAT4; - else return nullptr; - - return this->parent(); - } - - private: - AccessorType* _pEnum = nullptr; - }; - - class ObjectJsonHandler : public JsonHandler { - public: - virtual JsonHandler* StartObject() override { - return this; - } - - virtual JsonHandler* EndObject(size_t /*memberCount*/) override { - return this->parent(); - } - - JsonHandler* ignore() { - this->_ignoreHandler.reset(this); - return &this->_ignoreHandler; - } - - private: - IgnoreValueJsonHandler _ignoreHandler; - }; - - class DoubleArrayJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent, std::vector* pArray) { - JsonHandler::reset(pParent); - this->_pArray = pArray; - this->_arrayIsOpen = false; - } - - virtual JsonHandler* StartArray() override { - if (this->_arrayIsOpen) { - return nullptr; - } - - this->_arrayIsOpen = true; - return this; - } - - virtual JsonHandler* EndArray(size_t) override { - return this->parent(); - } - - virtual JsonHandler* Double(double d) override { - if (!this->_arrayIsOpen) { - return nullptr; - } - - assert(this->_pArray); - this->_pArray->emplace_back(d); - return this; - } - - private: - std::vector* _pArray = nullptr; - bool _arrayIsOpen = false; - }; - - template - class ObjectArrayJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent, std::vector* pArray) { - this->_pParent = pParent; - this->_pArray = pArray; - this->_arrayIsOpen = false; - } - - virtual JsonHandler* StartArray() override { - if (this->_arrayIsOpen) { - return nullptr; - } - - this->_arrayIsOpen = true; - return this; - } - - virtual JsonHandler* EndArray(size_t) override { - return this->_pParent; - } - - virtual JsonHandler* StartObject() override { - if (!this->_arrayIsOpen) { - return nullptr; - } - - assert(this->_pArray); - T& o = this->_pArray->emplace_back(); - this->_objectHandler.reset(this, &o); - return this->_objectHandler.StartObject(); - } - - private: - JsonHandler* _pParent = nullptr; - std::vector* _pArray = nullptr; - bool _arrayIsOpen = false; - THandler _objectHandler; - }; - - class AccessorJsonHandler : public ObjectJsonHandler { - public: - void reset(JsonHandler* pParent, Accessor* pAccessor) { - JsonHandler::reset(pParent); - this->_pAccessor = pAccessor; - } - - virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { - using namespace std::string_literals; - - assert(this->_pAccessor); - if ("bufferView"s == str) return property(this->_bufferView, this->_pAccessor->bufferView); - if ("byteOffset"s == str) return property(this->_byteOffset, this->_pAccessor->byteOffset); - if ("componentType"s == str) return property(this->_componentType, this->_pAccessor->componentType); - if ("normalized"s == str) return property(this->_normalized, this->_pAccessor->normalized); - if ("count"s == str) return property(this->_count, this->_pAccessor->count); - if ("type"s == str) return property(this->_type, this->_pAccessor->type); - if ("max"s == str) return property(this->_max, this->_pAccessor->max); - if ("min"s == str) return property(this->_min, this->_pAccessor->min); - - return this->ignore(); - } - - private: - Accessor* _pAccessor = nullptr; - IntegerJsonHandler _bufferView; - IntegerJsonHandler _byteOffset; - IntegerJsonHandler _componentType; - BoolJsonHandler _normalized; - IntegerJsonHandler _count; - AccessorTypeJsonHandler _type; - DoubleArrayJsonHandler _max; - DoubleArrayJsonHandler _min; - }; - - class PrimitiveJsonHandler : public ObjectJsonHandler { - public: - void reset(JsonHandler* pParent, Primitive* pPrimitive) { - JsonHandler::reset(pParent); - this->_pPrimitive = pPrimitive; - } - - virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { - using namespace std::string_literals; - - assert(this->_pPrimitive); - if ("indices"s == str) return property(this->_indices, this->_pPrimitive->indices); - if ("material"s == str) return property(this->_material, this->_pPrimitive->material); - if ("mode"s == str) return property(this->_mode, this->_pPrimitive->mode); - - return this->ignore(); - } - - private: - Primitive* _pPrimitive = nullptr; - // std::unordered_map attributes; - IntegerJsonHandler _indices; - IntegerJsonHandler _material; - IntegerJsonHandler _mode; - // std::vector> targets; - }; - - class MeshJsonHandler : public ObjectJsonHandler { - public: - void reset(JsonHandler* pParent, Mesh* pMesh) { - JsonHandler::reset(pParent); - this->_pMesh = pMesh; - } - - virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { - using namespace std::string_literals; - - assert(this->_pMesh); - if ("primitives"s == str) return property(this->_primitives, this->_pMesh->primitives); - if ("weights"s == str) return property(this->_weights, this->_pMesh->weights); - - return this->ignore(); - } - - private: - Mesh* _pMesh = nullptr; - ObjectArrayJsonHandler _primitives; - DoubleArrayJsonHandler _weights; - }; - - class ModelJsonHandler : public ObjectJsonHandler { - public: - void reset(JsonHandler* pParent, Model* pModel) { - ObjectJsonHandler::reset(pParent); - this->_pModel = pModel; - } - - virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { - using namespace std::string_literals; - - assert(this->_pModel); - if ("accessors"s == str) return property(this->_accessors, this->_pModel->accessors); - if ("meshes"s == str) return property(this->_meshes, this->_pModel->meshes); - - return this->ignore(); - } - - private: - Model* _pModel; - ObjectArrayJsonHandler _accessors; - ObjectArrayJsonHandler _meshes; - }; - - class GltfReader final { - public: - Model parse(const gsl::span& data) { - rapidjson::Reader reader; - rapidjson::MemoryStream inputStream(reinterpret_cast(data.data()), data.size()); - - Model result; - ModelJsonHandler modelHandler; - RejectAllJsonHandler rejectHandler; - Dispatcher dispatcher { &modelHandler }; - - modelHandler.reset(&rejectHandler, &result); - - reader.IterativeParseInit(); - - bool success = true; - while (success && !reader.IterativeParseComplete()) { - success = reader.IterativeParseNext(inputStream, dispatcher); - } - - return result; - } - - private: - struct Dispatcher { - JsonHandler* pCurrent; - - bool update(JsonHandler* pNext) { - if (pNext == nullptr) { - return false; - } - - this->pCurrent = pNext; - return true; - } - - bool Null() { return update(pCurrent->Null()); } - bool Bool(bool b) { return update(pCurrent->Bool(b)); } - bool Int(int i) { return update(pCurrent->Int(i)); } - bool Uint(unsigned i) { return update(pCurrent->Uint(i)); } - bool Int64(int64_t i) { return update(pCurrent->Int64(i)); } - bool Uint64(uint64_t i) { return update(pCurrent->Uint64(i)); } - bool Double(double d) { return update(pCurrent->Double(d)); } - bool RawNumber(const char* str, size_t length, bool copy) { return update(pCurrent->RawNumber(str, length, copy)); } - bool String(const char* str, size_t length, bool copy) { return update(pCurrent->String(str, length, copy)); } - bool StartObject() { return update(pCurrent->StartObject()); } - bool Key(const char* str, size_t length, bool copy) { return update(pCurrent->Key(str, length, copy)); } - bool EndObject(size_t memberCount) { return update(pCurrent->EndObject(memberCount)); } - bool StartArray() { return update(pCurrent->StartArray()); } - bool EndArray(size_t elementCount) { return update(pCurrent->EndArray(elementCount)); } - }; - }; - - template - void goParse(T&& handler) { - while (!handler.reader.IterativeParseComplete() && !handler.done) { - if (handler.next) { - handler.next(); - handler.next = nullptr; - } else { - handler.reader.IterativeParseNext(handler.inputStream, handler); - } - } - } - - struct DefaultHandler { - DefaultHandler(rapidjson::Reader& reader_, rapidjson::MemoryStream& inputStream_) : - reader(reader_), - inputStream(inputStream_), - done(false) - {} - - rapidjson::Reader& reader; - rapidjson::MemoryStream& inputStream; - std::function next; - bool done; - - bool Null() { return false; } - bool Bool(bool /*b*/) { return false; } - bool Int(int /*i*/) { return false; } - bool Uint(unsigned /*i*/) { return false; } - bool Int64(int64_t /*i*/) { return false; } - bool Uint64(uint64_t /*i*/) { return false; } - bool Double(double /*d*/) { return false; } - bool RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return false; } - bool String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return false; } - bool StartObject() { return false; } - bool Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return false; } - bool EndObject(size_t /*memberCount*/) { return false; } - bool StartArray() { return false; } - bool EndArray(size_t /*elementCount*/) { return false; } - }; - - struct ObjectHandler : public DefaultHandler { - ObjectHandler( - rapidjson::Reader& reader_, - rapidjson::MemoryStream& inputStream_ - ) : - DefaultHandler(reader_, inputStream_) - {} - - bool StartObject() { return true; } - bool EndObject(size_t) { - this->done = true; - return true; - } - }; - - template - struct ObjectArrayHandler : public DefaultHandler { - ObjectArrayHandler( - rapidjson::Reader& reader_, - rapidjson::MemoryStream& inputStream_, - std::vector& array_ - ) : - DefaultHandler(reader_, inputStream_), - array(array_), - _arrayOpen(false) - {} - - std::vector& array; - bool _arrayOpen; - - bool StartArray() { - if (this->_arrayOpen) { - return false; - } - - this->_arrayOpen = true; - return true; - } - - bool StartObject() { - if (!this->_arrayOpen) { - return false; - } - - T& o = this->array.emplace_back(); - THandler handler(this->reader, this->inputStream, o); - bool result = handler.StartObject(); - - if (result) { - next = [handler = std::move(handler)]() mutable { - goParse(handler); - }; - } - - return result; - } - - bool EndArray(size_t /*elementCount*/) { - if (!this->_arrayOpen) { - return false; - } - - this->_arrayOpen = false; - this->done = true; - return true; - } - }; - - template - struct IntegerHandler : public DefaultHandler { - IntegerHandler( - rapidjson::Reader& reader_, - rapidjson::MemoryStream& inputStream_, - T& value_ - ) : - DefaultHandler(reader_, inputStream_), - value(value_) - {} - - T& value; - - bool Int(int i) { - this->value = static_cast(i); - this->done = true; - return true; - } - bool Uint(unsigned i) { - this->value = static_cast(i); - this->done = true; - return true; - } - bool Int64(int64_t i) { - this->value = static_cast(i); - this->done = true; - return true; - } - bool Uint64(uint64_t i) { - this->value = static_cast(i); - this->done = true; - return true; - } - }; - - struct AccessorHandler : public ObjectHandler { - AccessorHandler( - rapidjson::Reader& reader_, - rapidjson::MemoryStream& inputStream_, - Accessor& accessor_ - ) : - ObjectHandler(reader_, inputStream_), - accessor(accessor_) - {} - - Accessor& accessor; - - bool Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - if ("count"s == str) { - next = [this]() { - goParse(IntegerHandler(this->reader, this->inputStream, this->accessor.count)); - }; - } - - return true; - } - }; - - struct ModelHandler : public ObjectHandler { - ModelHandler( - rapidjson::Reader& reader_, - rapidjson::MemoryStream& inputStream_, - Model& model_ - ) : - ObjectHandler(reader_, inputStream_), - model(model_) - {} - - Model& model; - - bool Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - if ("accessors"s == str) { - next = [this]() { goParse(ObjectArrayHandler(this->reader, this->inputStream, this->model.accessors)); }; - - } - return true; - } - }; - - Model parseModel(const gsl::span& data) { - rapidjson::Reader reader; - rapidjson::MemoryStream inputStream(reinterpret_cast(data.data()), data.size()); - - reader.IterativeParseInit(); - - Model model; - ModelHandler handler(reader, inputStream, model); - goParse(handler); - - return model; - } -} - TEST_CASE("GltfModel") { std::string s = "{\"accessors\": [{\"count\": 4,\"componentType\":5121,\"type\":\"VEC2\",\"max\":[1.0, 2.2, 3.3],\"min\":[0.0, -1.2]}],\"surprise\":{\"foo\":true}}"; - GltfReader reader; - - Model model = reader.parse(gsl::span(reinterpret_cast(s.c_str()), s.size())); + ModelReaderResult result = CesiumGltf::readModel(gsl::span(reinterpret_cast(s.c_str()), s.size())); + Model& model = result.model; REQUIRE(model.accessors.size() == 1); CHECK(model.accessors[0].count == 4); CHECK(model.accessors[0].componentType == ComponentType::UNSIGNED_BYTE); - CHECK(model.accessors[0].type == AccessorType::VEC2); + CHECK(model.accessors[0].type == AttributeType::VEC2); REQUIRE(model.accessors[0].min.size() == 2); CHECK(model.accessors[0].min[0] == 0.0); CHECK(model.accessors[0].min[1] == -1.2); diff --git a/CesiumGltfReader/CMakeLists.txt b/CesiumGltfReader/CMakeLists.txt new file mode 100644 index 000000000..9af4d6105 --- /dev/null +++ b/CesiumGltfReader/CMakeLists.txt @@ -0,0 +1,26 @@ +add_library(CesiumGltfReader "") + +configure_cesium_library(CesiumGltfReader) + +file(GLOB SOURCES include/CesiumGltf/*.h src/*.cpp src/*.h) +file(GLOB PUBLIC_INCLUDES include/CesiumGltf/*.h) + +target_sources( + CesiumGltfReader + PRIVATE + ${SOURCES} + PUBLIC + ${PUBLIC_INCLUDES} +) + +target_include_directories( + CesiumGltfReader + SYSTEM PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../extern/rapidjson/include + PUBLIC + include + PRIVATE + src +) + +target_link_libraries(CesiumGltfReader PUBLIC CesiumGltf) diff --git a/CesiumGltfReader/include/CesiumGltf/Reader.h b/CesiumGltfReader/include/CesiumGltf/Reader.h new file mode 100644 index 000000000..1d445ff62 --- /dev/null +++ b/CesiumGltfReader/include/CesiumGltf/Reader.h @@ -0,0 +1,14 @@ +#pragma once + +#include "CesiumGltf/Model.h" +#include + +namespace CesiumGltf { + struct ModelReaderResult { + Model model; + std::string errors; + std::string warnings; + }; + + ModelReaderResult readModel(const gsl::span& data); +} diff --git a/CesiumGltfReader/src/AccessorJsonHandler.cpp b/CesiumGltfReader/src/AccessorJsonHandler.cpp new file mode 100644 index 000000000..9b9f4f1cc --- /dev/null +++ b/CesiumGltfReader/src/AccessorJsonHandler.cpp @@ -0,0 +1,26 @@ +#include "AccessorJsonHandler.h" +#include +#include + +using namespace CesiumGltf; + +void AccessorJsonHandler::reset(JsonHandler* pParent, Accessor* pAccessor) { + ObjectJsonHandler::reset(pParent); + this->_pAccessor = pAccessor; +} + +JsonHandler* AccessorJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pAccessor); + if ("bufferView"s == str) return property(this->_bufferView, this->_pAccessor->bufferView); + if ("byteOffset"s == str) return property(this->_byteOffset, this->_pAccessor->byteOffset); + if ("componentType"s == str) return property(this->_componentType, this->_pAccessor->componentType); + if ("normalized"s == str) return property(this->_normalized, this->_pAccessor->normalized); + if ("count"s == str) return property(this->_count, this->_pAccessor->count); + if ("type"s == str) return property(this->_type, this->_pAccessor->type); + if ("max"s == str) return property(this->_max, this->_pAccessor->max); + if ("min"s == str) return property(this->_min, this->_pAccessor->min); + + return this->ignore(); +} diff --git a/CesiumGltfReader/src/AccessorJsonHandler.h b/CesiumGltfReader/src/AccessorJsonHandler.h new file mode 100644 index 000000000..036b27d56 --- /dev/null +++ b/CesiumGltfReader/src/AccessorJsonHandler.h @@ -0,0 +1,29 @@ +#pragma once + +#include "AttributeTypeJsonHandler.h" +#include "BoolJsonHandler.h" +#include "CesiumGltf/Accessor.h" +#include "DoubleArrayJsonHandler.h" +#include "IntegerJsonHandler.h" +#include "ObjectJsonHandler.h" +#include + +namespace CesiumGltf { + class AccessorJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Accessor* pAccessor); + + virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override; + + private: + Accessor* _pAccessor = nullptr; + IntegerJsonHandler _bufferView; + IntegerJsonHandler _byteOffset; + IntegerJsonHandler _componentType; + BoolJsonHandler _normalized; + IntegerJsonHandler _count; + AttributeTypeJsonHandler _type; + DoubleArrayJsonHandler _max; + DoubleArrayJsonHandler _min; + }; +} diff --git a/CesiumGltfReader/src/AttributeTypeJsonHandler.cpp b/CesiumGltfReader/src/AttributeTypeJsonHandler.cpp new file mode 100644 index 000000000..d03e6aa44 --- /dev/null +++ b/CesiumGltfReader/src/AttributeTypeJsonHandler.cpp @@ -0,0 +1,24 @@ +#include "AttributeTypeJsonHandler.h" +#include + +using namespace CesiumGltf; + +void AttributeTypeJsonHandler::reset(JsonHandler* pParent, AttributeType* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +JsonHandler* AttributeTypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + if ("SCALAR"s == str) *this->_pEnum = AttributeType::SCALAR; + else if ("VEC2"s == str) *this->_pEnum = AttributeType::VEC2; + else if ("VEC3"s == str) *this->_pEnum = AttributeType::VEC3; + else if ("VEC4"s == str) *this->_pEnum = AttributeType::VEC4; + else if ("MAT2"s == str) *this->_pEnum = AttributeType::MAT2; + else if ("MAT3"s == str) *this->_pEnum = AttributeType::MAT3; + else if ("MAT4"s == str) *this->_pEnum = AttributeType::MAT4; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/AttributeTypeJsonHandler.h b/CesiumGltfReader/src/AttributeTypeJsonHandler.h new file mode 100644 index 000000000..34fceaf7c --- /dev/null +++ b/CesiumGltfReader/src/AttributeTypeJsonHandler.h @@ -0,0 +1,15 @@ +#pragma once + +#include "JsonHandler.h" +#include "CesiumGltf/AttributeType.h" + +namespace CesiumGltf { + class AttributeTypeJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, AttributeType* pEnum); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + + private: + AttributeType* _pEnum = nullptr; + }; +} diff --git a/CesiumGltfReader/src/BoolJsonHandler.cpp b/CesiumGltfReader/src/BoolJsonHandler.cpp new file mode 100644 index 000000000..0afb1572b --- /dev/null +++ b/CesiumGltfReader/src/BoolJsonHandler.cpp @@ -0,0 +1,15 @@ +#include "BoolJsonHandler.h" +#include + +using namespace CesiumGltf; + +void BoolJsonHandler::reset(JsonHandler* pParent, bool* pBool) { + JsonHandler::reset(pParent); + this->_pBool = pBool; +} + +JsonHandler* BoolJsonHandler::Bool(bool b) { + assert(this->_pBool); + *this->_pBool = b; + return this->parent(); +} diff --git a/CesiumGltfReader/src/BoolJsonHandler.h b/CesiumGltfReader/src/BoolJsonHandler.h new file mode 100644 index 000000000..e58935e3b --- /dev/null +++ b/CesiumGltfReader/src/BoolJsonHandler.h @@ -0,0 +1,15 @@ +#pragma once + +#include "JsonHandler.h" + +namespace CesiumGltf { + class BoolJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, bool* pBool); + + virtual JsonHandler* Bool(bool b) override; + + private: + bool* _pBool = nullptr; + }; +} diff --git a/CesiumGltfReader/src/DoubleArrayJsonHandler.cpp b/CesiumGltfReader/src/DoubleArrayJsonHandler.cpp new file mode 100644 index 000000000..82d967bc3 --- /dev/null +++ b/CesiumGltfReader/src/DoubleArrayJsonHandler.cpp @@ -0,0 +1,33 @@ +#include "DoubleArrayJsonHandler.h" +#include + +using namespace CesiumGltf; + +void DoubleArrayJsonHandler::reset(JsonHandler* pParent, std::vector* pArray) { + JsonHandler::reset(pParent); + this->_pArray = pArray; + this->_arrayIsOpen = false; +} + +JsonHandler* DoubleArrayJsonHandler::StartArray() { + if (this->_arrayIsOpen) { + return nullptr; + } + + this->_arrayIsOpen = true; + return this; +} + +JsonHandler* DoubleArrayJsonHandler::EndArray(size_t) { + return this->parent(); +} + +JsonHandler* DoubleArrayJsonHandler::Double(double d) { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(d); + return this; +} diff --git a/CesiumGltfReader/src/DoubleArrayJsonHandler.h b/CesiumGltfReader/src/DoubleArrayJsonHandler.h new file mode 100644 index 000000000..4b998632b --- /dev/null +++ b/CesiumGltfReader/src/DoubleArrayJsonHandler.h @@ -0,0 +1,18 @@ +#pragma once + +#include "JsonHandler.h" +#include + +namespace CesiumGltf { + class DoubleArrayJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, std::vector* pArray); + virtual JsonHandler* StartArray() override; + virtual JsonHandler* EndArray(size_t count) override; + virtual JsonHandler* Double(double d) override; + + private: + std::vector* _pArray = nullptr; + bool _arrayIsOpen = false; + }; +} diff --git a/CesiumGltfReader/src/IgnoreValueJsonHandler.cpp b/CesiumGltfReader/src/IgnoreValueJsonHandler.cpp new file mode 100644 index 000000000..f677b2618 --- /dev/null +++ b/CesiumGltfReader/src/IgnoreValueJsonHandler.cpp @@ -0,0 +1,64 @@ +#include "IgnoreValueJsonHandler.h" + +using namespace CesiumGltf; + +void IgnoreValueJsonHandler::reset(JsonHandler* pParent) { + JsonHandler::reset(pParent); + this->_depth = 0; +} + +CesiumGltf::JsonHandler* IgnoreValueJsonHandler::Null() { + return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::Bool(bool /*b*/) { + return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::Int(int /*i*/) { + return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::Uint(unsigned /*i*/) { + return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::Int64(int64_t /*i*/) { + return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::Uint64(uint64_t /*i*/) { + return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::Double(double /*d*/) { + return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { + return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { + return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::StartObject() { + ++this->_depth; return this; +} + +JsonHandler* IgnoreValueJsonHandler::Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { + return this; +} + +JsonHandler* IgnoreValueJsonHandler::EndObject(size_t /*memberCount*/) { + --this->_depth; return this->_depth == 0 ? this->parent() : this; +} + +JsonHandler* IgnoreValueJsonHandler::StartArray() { + ++this->_depth; return this; +} + +JsonHandler* IgnoreValueJsonHandler::EndArray(size_t /*elementCount*/) { + --this->_depth; return this->_depth == 0 ? this->parent() : this; +} diff --git a/CesiumGltfReader/src/IgnoreValueJsonHandler.h b/CesiumGltfReader/src/IgnoreValueJsonHandler.h new file mode 100644 index 000000000..6109b0945 --- /dev/null +++ b/CesiumGltfReader/src/IgnoreValueJsonHandler.h @@ -0,0 +1,29 @@ +#pragma once + +#include "JsonHandler.h" +#include + +namespace CesiumGltf { + class IgnoreValueJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent); + + virtual JsonHandler* Null() override; + virtual JsonHandler* Bool(bool /*b*/) override; + virtual JsonHandler* Int(int /*i*/) override; + virtual JsonHandler* Uint(unsigned /*i*/) override; + virtual JsonHandler* Int64(int64_t /*i*/) override; + virtual JsonHandler* Uint64(uint64_t /*i*/) override; + virtual JsonHandler* Double(double /*d*/) override; + virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) override; + virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/) override; + virtual JsonHandler* StartObject() override; + virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) override; + virtual JsonHandler* EndObject(size_t /*memberCount*/) override; + virtual JsonHandler* StartArray() override; + virtual JsonHandler* EndArray(size_t /*elementCount*/) override; + + private: + size_t _depth = 0; + }; +} diff --git a/CesiumGltfReader/src/IntegerJsonHandler.h b/CesiumGltfReader/src/IntegerJsonHandler.h new file mode 100644 index 000000000..7f0e957f3 --- /dev/null +++ b/CesiumGltfReader/src/IntegerJsonHandler.h @@ -0,0 +1,39 @@ +#pragma once + +#include "JsonHandler.h" +#include + +namespace CesiumGltf { + template + class IntegerJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, T* pInteger) { + JsonHandler::reset(pParent); + this->_pInteger = pInteger; + } + + virtual JsonHandler* Int(int i) override { + assert(this->_pInteger); + *this->_pInteger = static_cast(i); + return this->parent(); + } + virtual JsonHandler* Uint(unsigned i) override { + assert(this->_pInteger); + *this->_pInteger = static_cast(i); + return this->parent(); + } + virtual JsonHandler* Int64(int64_t i) override { + assert(this->_pInteger); + *this->_pInteger = static_cast(i); + return this->parent(); + } + virtual JsonHandler* Uint64(uint64_t i) override { + assert(this->_pInteger); + *this->_pInteger = static_cast(i); + return this->parent(); + } + + private: + T* _pInteger = nullptr; + }; +} diff --git a/CesiumGltfReader/src/JsonHandler.cpp b/CesiumGltfReader/src/JsonHandler.cpp new file mode 100644 index 000000000..33271b4e0 --- /dev/null +++ b/CesiumGltfReader/src/JsonHandler.cpp @@ -0,0 +1,64 @@ +#include "JsonHandler.h" + +using namespace CesiumGltf; + +JsonHandler* JsonHandler::Null() { + return nullptr; +} + +JsonHandler* JsonHandler::Bool(bool /*b*/) { + return nullptr; +} + +JsonHandler* JsonHandler::Int(int /*i*/) { + return nullptr; +} + +JsonHandler* JsonHandler::Uint(unsigned /*i*/) { + return nullptr; +} + +JsonHandler* JsonHandler::Int64(int64_t /*i*/) { + return nullptr; +} + +JsonHandler* JsonHandler::Uint64(uint64_t /*i*/) { + return nullptr; +} + +JsonHandler* JsonHandler::Double(double /*d*/) { + return nullptr; +} + +JsonHandler* JsonHandler::RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { + return nullptr; +} + +JsonHandler* JsonHandler::String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { + return nullptr; +} + +JsonHandler* JsonHandler::StartObject() { return nullptr; } +JsonHandler* JsonHandler::Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { + return nullptr; +} + +JsonHandler* JsonHandler::EndObject(size_t /*memberCount*/) { + return nullptr; +} + +JsonHandler* JsonHandler::StartArray() { + return nullptr; +} + +JsonHandler* JsonHandler::EndArray(size_t /*elementCount*/) { + return nullptr; +} + +JsonHandler* JsonHandler::parent() { + return this->_pParent; +} + +void JsonHandler::reset(JsonHandler* pParent) { + this->_pParent = pParent; +} diff --git a/CesiumGltfReader/src/JsonHandler.h b/CesiumGltfReader/src/JsonHandler.h new file mode 100644 index 000000000..f9434b727 --- /dev/null +++ b/CesiumGltfReader/src/JsonHandler.h @@ -0,0 +1,39 @@ +#pragma once + +#include + +namespace CesiumGltf { + + class JsonHandler { + public: + virtual JsonHandler* Null(); + virtual JsonHandler* Bool(bool /*b*/); + virtual JsonHandler* Int(int /*i*/); + virtual JsonHandler* Uint(unsigned /*i*/); + virtual JsonHandler* Int64(int64_t /*i*/); + virtual JsonHandler* Uint64(uint64_t /*i*/); + virtual JsonHandler* Double(double /*d*/); + virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/); + virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/); + virtual JsonHandler* StartObject(); + virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/); + virtual JsonHandler* EndObject(size_t /*memberCount*/); + virtual JsonHandler* StartArray(); + virtual JsonHandler* EndArray(size_t /*elementCount*/); + + template + JsonHandler* property(TAccessor& accessor, TProperty& value) { + accessor.reset(this, &value); + return &accessor; + } + + JsonHandler* parent(); + + protected: + void reset(JsonHandler* pParent); + + private: + JsonHandler* _pParent = nullptr; + }; + +} diff --git a/CesiumGltfReader/src/MeshJsonHandler.cpp b/CesiumGltfReader/src/MeshJsonHandler.cpp new file mode 100644 index 000000000..221ec05d3 --- /dev/null +++ b/CesiumGltfReader/src/MeshJsonHandler.cpp @@ -0,0 +1,20 @@ +#include "MeshJsonHandler.h" +#include +#include + +using namespace CesiumGltf; + +void MeshJsonHandler::reset(JsonHandler* pParent, Mesh* pMesh) { + JsonHandler::reset(pParent); + this->_pMesh = pMesh; +} + +JsonHandler* MeshJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pMesh); + if ("primitives"s == str) return property(this->_primitives, this->_pMesh->primitives); + if ("weights"s == str) return property(this->_weights, this->_pMesh->weights); + + return this->ignore(); +} diff --git a/CesiumGltfReader/src/MeshJsonHandler.h b/CesiumGltfReader/src/MeshJsonHandler.h new file mode 100644 index 000000000..fb84f465e --- /dev/null +++ b/CesiumGltfReader/src/MeshJsonHandler.h @@ -0,0 +1,22 @@ +#pragma once + +#include "CesiumGltf/Mesh.h" +#include "ObjectArrayJsonHandler.h" +#include "DoubleArrayJsonHandler.h" +#include "PrimitiveJsonHandler.h" + +namespace CesiumGltf { + struct Mesh; + struct Primitive; + + class MeshJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Mesh* pMesh); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + Mesh* _pMesh = nullptr; + ObjectArrayJsonHandler _primitives; + DoubleArrayJsonHandler _weights; + }; +} diff --git a/CesiumGltfReader/src/ModelJsonHandler.cpp b/CesiumGltfReader/src/ModelJsonHandler.cpp new file mode 100644 index 000000000..e36fd0a50 --- /dev/null +++ b/CesiumGltfReader/src/ModelJsonHandler.cpp @@ -0,0 +1,20 @@ +#include "ModelJsonHandler.h" +#include +#include + +using namespace CesiumGltf; + +void ModelJsonHandler::reset(JsonHandler* pParent, Model* pModel) { + ObjectJsonHandler::reset(pParent); + this->_pModel = pModel; +} + +JsonHandler* ModelJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pModel); + if ("accessors"s == str) return property(this->_accessors, this->_pModel->accessors); + if ("meshes"s == str) return property(this->_meshes, this->_pModel->meshes); + + return this->ignore(); +} diff --git a/CesiumGltfReader/src/ModelJsonHandler.h b/CesiumGltfReader/src/ModelJsonHandler.h new file mode 100644 index 000000000..ac8f07952 --- /dev/null +++ b/CesiumGltfReader/src/ModelJsonHandler.h @@ -0,0 +1,20 @@ +#pragma once + +#include "ObjectJsonHandler.h" +#include "ObjectArrayJsonHandler.h" +#include "CesiumGltf/Model.h" +#include "AccessorJsonHandler.h" +#include "MeshJsonHandler.h" + +namespace CesiumGltf { + class ModelJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Model* pModel); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + Model* _pModel; + ObjectArrayJsonHandler _accessors; + ObjectArrayJsonHandler _meshes; + }; +} diff --git a/CesiumGltfReader/src/ObjectArrayJsonHandler.h b/CesiumGltfReader/src/ObjectArrayJsonHandler.h new file mode 100644 index 000000000..25d6fc408 --- /dev/null +++ b/CesiumGltfReader/src/ObjectArrayJsonHandler.h @@ -0,0 +1,47 @@ +#pragma once + +#include "JsonHandler.h" +#include +#include + +namespace CesiumGltf { + template + class ObjectArrayJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, std::vector* pArray) { + this->_pParent = pParent; + this->_pArray = pArray; + this->_arrayIsOpen = false; + } + + virtual JsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return nullptr; + } + + this->_arrayIsOpen = true; + return this; + } + + virtual JsonHandler* EndArray(size_t) override { + return this->_pParent; + } + + virtual JsonHandler* StartObject() override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + T& o = this->_pArray->emplace_back(); + this->_objectHandler.reset(this, &o); + return this->_objectHandler.StartObject(); + } + + private: + JsonHandler* _pParent = nullptr; + std::vector* _pArray = nullptr; + bool _arrayIsOpen = false; + THandler _objectHandler; + }; +} diff --git a/CesiumGltfReader/src/ObjectJsonHandler.h b/CesiumGltfReader/src/ObjectJsonHandler.h new file mode 100644 index 000000000..fb53087e8 --- /dev/null +++ b/CesiumGltfReader/src/ObjectJsonHandler.h @@ -0,0 +1,25 @@ +#pragma once + +#include "JsonHandler.h" +#include "IgnoreValueJsonHandler.h" + +namespace CesiumGltf { + class ObjectJsonHandler : public JsonHandler { + public: + virtual JsonHandler* StartObject() override { + return this; + } + + virtual JsonHandler* EndObject(size_t /*memberCount*/) override { + return this->parent(); + } + + JsonHandler* ignore() { + this->_ignoreHandler.reset(this); + return &this->_ignoreHandler; + } + + private: + IgnoreValueJsonHandler _ignoreHandler; + }; +} diff --git a/CesiumGltfReader/src/PrimitiveJsonHandler.cpp b/CesiumGltfReader/src/PrimitiveJsonHandler.cpp new file mode 100644 index 000000000..4fc3bf0c8 --- /dev/null +++ b/CesiumGltfReader/src/PrimitiveJsonHandler.cpp @@ -0,0 +1,22 @@ +#include "PrimitiveJsonHandler.h" +#include "CesiumGltf/Primitive.h" +#include +#include + +using namespace CesiumGltf; + +void PrimitiveJsonHandler::reset(JsonHandler* pParent, Primitive* pPrimitive) { + JsonHandler::reset(pParent); + this->_pPrimitive = pPrimitive; +} + +JsonHandler* PrimitiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pPrimitive); + if ("indices"s == str) return property(this->_indices, this->_pPrimitive->indices); + if ("material"s == str) return property(this->_material, this->_pPrimitive->material); + if ("mode"s == str) return property(this->_mode, this->_pPrimitive->mode); + + return this->ignore(); +} diff --git a/CesiumGltfReader/src/PrimitiveJsonHandler.h b/CesiumGltfReader/src/PrimitiveJsonHandler.h new file mode 100644 index 000000000..d64f56efa --- /dev/null +++ b/CesiumGltfReader/src/PrimitiveJsonHandler.h @@ -0,0 +1,23 @@ +#pragma once + +#include "CesiumGltf/PrimitiveMode.h" +#include "ObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct Primitive; + + class PrimitiveJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Primitive* pPrimitive); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + Primitive* _pPrimitive = nullptr; + // std::unordered_map attributes; + IntegerJsonHandler _indices; + IntegerJsonHandler _material; + IntegerJsonHandler _mode; + // std::vector> targets; + }; +} diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp new file mode 100644 index 000000000..71944fb4e --- /dev/null +++ b/CesiumGltfReader/src/Reader.cpp @@ -0,0 +1,58 @@ +#include "CesiumGltf/Reader.h" +#include "JsonHandler.h" +#include "ModelJsonHandler.h" +#include "RejectAllJsonHandler.h" +#include + +using namespace CesiumGltf; + +namespace { + struct Dispatcher { + JsonHandler* pCurrent; + + bool update(JsonHandler* pNext) { + if (pNext == nullptr) { + return false; + } + + this->pCurrent = pNext; + return true; + } + + bool Null() { return update(pCurrent->Null()); } + bool Bool(bool b) { return update(pCurrent->Bool(b)); } + bool Int(int i) { return update(pCurrent->Int(i)); } + bool Uint(unsigned i) { return update(pCurrent->Uint(i)); } + bool Int64(int64_t i) { return update(pCurrent->Int64(i)); } + bool Uint64(uint64_t i) { return update(pCurrent->Uint64(i)); } + bool Double(double d) { return update(pCurrent->Double(d)); } + bool RawNumber(const char* str, size_t length, bool copy) { return update(pCurrent->RawNumber(str, length, copy)); } + bool String(const char* str, size_t length, bool copy) { return update(pCurrent->String(str, length, copy)); } + bool StartObject() { return update(pCurrent->StartObject()); } + bool Key(const char* str, size_t length, bool copy) { return update(pCurrent->Key(str, length, copy)); } + bool EndObject(size_t memberCount) { return update(pCurrent->EndObject(memberCount)); } + bool StartArray() { return update(pCurrent->StartArray()); } + bool EndArray(size_t elementCount) { return update(pCurrent->EndArray(elementCount)); } + }; +} + +ModelReaderResult CesiumGltf::readModel(const gsl::span& data) { + rapidjson::Reader reader; + rapidjson::MemoryStream inputStream(reinterpret_cast(data.data()), data.size()); + + ModelReaderResult result; + ModelJsonHandler modelHandler; + RejectAllJsonHandler rejectHandler; + Dispatcher dispatcher { &modelHandler }; + + modelHandler.reset(&rejectHandler, &result.model); + + reader.IterativeParseInit(); + + bool success = true; + while (success && !reader.IterativeParseComplete()) { + success = reader.IterativeParseNext(inputStream, dispatcher); + } + + return result; +} diff --git a/CesiumGltfReader/src/RejectAllJsonHandler.h b/CesiumGltfReader/src/RejectAllJsonHandler.h new file mode 100644 index 000000000..064edf35d --- /dev/null +++ b/CesiumGltfReader/src/RejectAllJsonHandler.h @@ -0,0 +1,10 @@ +#pragma once + +namespace CesiumGltf { + class RejectAllJsonHandler : public JsonHandler { + public: + RejectAllJsonHandler() { + reset(this); + } + }; +} From e4a69c6559aa6adc2ad6ee5daa25b806bc134e0f Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 4 Jan 2021 22:21:54 +1100 Subject: [PATCH 09/61] Support attributes, names. --- CesiumGltf/include/CesiumGltf/Accessor.h | 6 +++- .../include/CesiumGltf/ExtensibleObject.h | 11 +++++++ CesiumGltf/include/CesiumGltf/Mesh.h | 4 ++- CesiumGltf/include/CesiumGltf/Model.h | 3 +- CesiumGltf/include/CesiumGltf/NamedObject.h | 20 +++++++++++ CesiumGltf/include/CesiumGltf/Primitive.h | 8 +++-- CesiumGltf/test/TestGltfModel.cpp | 29 +++++++++++++++- CesiumGltfReader/src/AccessorJsonHandler.cpp | 5 ++- CesiumGltfReader/src/AccessorJsonHandler.h | 12 ++++--- CesiumGltfReader/src/AttributeJsonHandler.cpp | 17 ++++++++++ CesiumGltfReader/src/AttributeJsonHandler.h | 17 ++++++++++ .../src/ExtensibleObjectJsonHandler.cpp | 8 +++++ .../src/ExtensibleObjectJsonHandler.h | 12 +++++++ CesiumGltfReader/src/JsonHandler.h | 28 ++++++++-------- CesiumGltfReader/src/MeshJsonHandler.cpp | 3 +- CesiumGltfReader/src/MeshJsonHandler.h | 5 +-- .../src/NamedObjectJsonHandler.cpp | 11 +++++++ CesiumGltfReader/src/NamedObjectJsonHandler.h | 16 +++++++++ CesiumGltfReader/src/ObjectJsonHandler.cpp | 33 +++++++++++++++++++ CesiumGltfReader/src/ObjectJsonHandler.h | 17 ++++------ CesiumGltfReader/src/PrimitiveJsonHandler.cpp | 3 +- CesiumGltfReader/src/PrimitiveJsonHandler.h | 8 +++-- CesiumGltfReader/src/StringJsonHandler.cpp | 13 ++++++++ CesiumGltfReader/src/StringJsonHandler.h | 15 +++++++++ 24 files changed, 262 insertions(+), 42 deletions(-) create mode 100644 CesiumGltf/include/CesiumGltf/ExtensibleObject.h create mode 100644 CesiumGltf/include/CesiumGltf/NamedObject.h create mode 100644 CesiumGltfReader/src/AttributeJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AttributeJsonHandler.h create mode 100644 CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp create mode 100644 CesiumGltfReader/src/ExtensibleObjectJsonHandler.h create mode 100644 CesiumGltfReader/src/NamedObjectJsonHandler.cpp create mode 100644 CesiumGltfReader/src/NamedObjectJsonHandler.h create mode 100644 CesiumGltfReader/src/ObjectJsonHandler.cpp create mode 100644 CesiumGltfReader/src/StringJsonHandler.cpp create mode 100644 CesiumGltfReader/src/StringJsonHandler.h diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index 5692b7606..28e82ab60 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -1,8 +1,10 @@ #pragma once +#include "CesiumGltf/NamedObject.h" #include "AttributeType.h" #include "ComponentType.h" #include +#include #include namespace CesiumGltf { @@ -13,7 +15,7 @@ namespace CesiumGltf { * `BufferView` or a subset of a `BufferView` similar to how WebGL's `vertexAttribPointer()` * defines an attribute in a buffer. */ - struct Accessor { + struct Accessor : public NamedObject { /** * @brief The index of the `BufferView` in {@link Model::bufferViews}. * @@ -77,5 +79,7 @@ namespace CesiumGltf { * When accessor is sparse, this property must contain min values of accessor data with sparse substitution applied. */ std::vector min; + + // TODO: sparse }; } diff --git a/CesiumGltf/include/CesiumGltf/ExtensibleObject.h b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h new file mode 100644 index 000000000..0e95ea5f9 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h @@ -0,0 +1,11 @@ +#pragma once + +namespace CesiumGltf { + /** + * @brief The base class for objects in a glTF that have extensions and extras. + */ + struct ExtensibleObject { + // TODO: extensions + // TODO: extras + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Mesh.h b/CesiumGltf/include/CesiumGltf/Mesh.h index ba95f9768..096eb4753 100644 --- a/CesiumGltf/include/CesiumGltf/Mesh.h +++ b/CesiumGltf/include/CesiumGltf/Mesh.h @@ -1,7 +1,9 @@ #pragma once +#include "CesiumGltf/NamedObject.h" #include "CesiumGltf/Primitive.h" #include +#include namespace CesiumGltf { /** @@ -9,7 +11,7 @@ namespace CesiumGltf { * * A {@link Node} can contain one mesh. A node's transform places the mesh in the scene. */ - struct Mesh { + struct Mesh : public NamedObject { /** * @brief An array of primitives, each defining geometry to be rendered with a material. */ diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index 7dee64cd6..0254561d6 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -1,6 +1,7 @@ #pragma once #include "CesiumGltf/Accessor.h" +#include "CesiumGltf/ExtensibleObject.h" #include "CesiumGltf/Mesh.h" #include @@ -8,7 +9,7 @@ namespace CesiumGltf { /** * @brief A glTF model. */ - struct Model { + struct Model : public ExtensibleObject { /** * @brief An array of accessors. * diff --git a/CesiumGltf/include/CesiumGltf/NamedObject.h b/CesiumGltf/include/CesiumGltf/NamedObject.h new file mode 100644 index 000000000..1ddf52308 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/NamedObject.h @@ -0,0 +1,20 @@ +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include + +namespace CesiumGltf { + /** + * @brief The base class for objects in a glTF that have a name. + * + * A named object is also an {@link ExtensibleObject}. + */ + struct NamedObject : public ExtensibleObject { + /** + * @brief The user-defined name of this object. + * + * This is not necessarily unique, e.g., an accessor and a buffer could have the same name, or two accessors could even have the same name. + */ + std::string name; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Primitive.h b/CesiumGltf/include/CesiumGltf/Primitive.h index 34e41aae6..9492650cd 100644 --- a/CesiumGltf/include/CesiumGltf/Primitive.h +++ b/CesiumGltf/include/CesiumGltf/Primitive.h @@ -1,5 +1,6 @@ #pragma once +#include "CesiumGltf/ExtensibleObject.h" #include "CesiumGltf/PrimitiveMode.h" #include #include @@ -7,7 +8,10 @@ #include namespace CesiumGltf { - struct Primitive { + /** + * @brief Geometry to be rendered with the given material. + */ + struct Primitive : public ExtensibleObject { /** * @brief A dictionary object, where each key corresponds to mesh attribute semantic and each value is the index of the accessor containing attribute's data. */ @@ -46,6 +50,6 @@ namespace CesiumGltf { * @brief An array of Morph Targets, each Morph Target is a dictionary mapping attributes * (only `POSITION`, `NORMAL`, and `TANGENT` supported) to their deviations in the Morph Target. */ - std::vector> targets; + std::vector> targets; }; } diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index f3532269e..dd31aa476 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -7,7 +7,29 @@ using namespace CesiumGltf; TEST_CASE("GltfModel") { - std::string s = "{\"accessors\": [{\"count\": 4,\"componentType\":5121,\"type\":\"VEC2\",\"max\":[1.0, 2.2, 3.3],\"min\":[0.0, -1.2]}],\"surprise\":{\"foo\":true}}"; + using namespace std::string_literals; + + std::string s = + "{"s + + " \"accessors\": ["s + + " {"s + + " \"count\": 4,"s + + " \"componentType\":5121,"s + + " \"type\":\"VEC2\","s + + " \"max\":[1.0, 2.2, 3.3],"s + + " \"min\":[0.0, -1.2]"s + + " }"s + + " ],"s + + " \"meshes\": [{"s + + " \"primitives\": [{"s + + " \"attributes\": {"s + + " \"POSITION\": 0,"s + + " \"NORMAL\": 1"s + + " }"s + + " }]"s + + " }],"s + + " \"surprise\":{\"foo\":true}"s + + "}"s; ModelReaderResult result = CesiumGltf::readModel(gsl::span(reinterpret_cast(s.c_str()), s.size())); Model& model = result.model; REQUIRE(model.accessors.size() == 1); @@ -21,6 +43,11 @@ TEST_CASE("GltfModel") { CHECK(model.accessors[0].max[0] == 1.0); CHECK(model.accessors[0].max[1] == 2.2); CHECK(model.accessors[0].max[2] == 3.3); + + REQUIRE(model.meshes.size() == 1); + REQUIRE(model.meshes[0].primitives.size() == 1); + CHECK(model.meshes[0].primitives[0].attributes["POSITION"] == 0); + CHECK(model.meshes[0].primitives[0].attributes["NORMAL"] == 1); // std::vector v; // GltfModel model = GltfModel::fromMemory(v); // GltfCollection meshes = model.meshes(); diff --git a/CesiumGltfReader/src/AccessorJsonHandler.cpp b/CesiumGltfReader/src/AccessorJsonHandler.cpp index 9b9f4f1cc..8fee6a07e 100644 --- a/CesiumGltfReader/src/AccessorJsonHandler.cpp +++ b/CesiumGltfReader/src/AccessorJsonHandler.cpp @@ -1,4 +1,5 @@ #include "AccessorJsonHandler.h" +#include "CesiumGltf/Accessor.h" #include #include @@ -13,6 +14,7 @@ JsonHandler* AccessorJsonHandler::Key(const char* str, size_t /*length*/, bool / using namespace std::string_literals; assert(this->_pAccessor); + if ("bufferView"s == str) return property(this->_bufferView, this->_pAccessor->bufferView); if ("byteOffset"s == str) return property(this->_byteOffset, this->_pAccessor->byteOffset); if ("componentType"s == str) return property(this->_componentType, this->_pAccessor->componentType); @@ -21,6 +23,7 @@ JsonHandler* AccessorJsonHandler::Key(const char* str, size_t /*length*/, bool / if ("type"s == str) return property(this->_type, this->_pAccessor->type); if ("max"s == str) return property(this->_max, this->_pAccessor->max); if ("min"s == str) return property(this->_min, this->_pAccessor->min); + if ("name"s == str) return property(this->_name, this->_pAccessor->name); - return this->ignore(); + return this->NamedObjectKey(str, *this->_pAccessor); } diff --git a/CesiumGltfReader/src/AccessorJsonHandler.h b/CesiumGltfReader/src/AccessorJsonHandler.h index 036b27d56..9cd5918e3 100644 --- a/CesiumGltfReader/src/AccessorJsonHandler.h +++ b/CesiumGltfReader/src/AccessorJsonHandler.h @@ -2,18 +2,21 @@ #include "AttributeTypeJsonHandler.h" #include "BoolJsonHandler.h" -#include "CesiumGltf/Accessor.h" +#include "CesiumGltf/ComponentType.h" #include "DoubleArrayJsonHandler.h" #include "IntegerJsonHandler.h" -#include "ObjectJsonHandler.h" +#include "NamedObjectJsonHandler.h" +#include "StringJsonHandler.h" #include namespace CesiumGltf { - class AccessorJsonHandler : public ObjectJsonHandler { + struct Accessor; + + class AccessorJsonHandler : public NamedObjectJsonHandler { public: void reset(JsonHandler* pParent, Accessor* pAccessor); - virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override; + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; private: Accessor* _pAccessor = nullptr; @@ -25,5 +28,6 @@ namespace CesiumGltf { AttributeTypeJsonHandler _type; DoubleArrayJsonHandler _max; DoubleArrayJsonHandler _min; + StringJsonHandler _name; }; } diff --git a/CesiumGltfReader/src/AttributeJsonHandler.cpp b/CesiumGltfReader/src/AttributeJsonHandler.cpp new file mode 100644 index 000000000..d18719f7b --- /dev/null +++ b/CesiumGltfReader/src/AttributeJsonHandler.cpp @@ -0,0 +1,17 @@ +#include "AttributeJsonHandler.h" + +using namespace CesiumGltf; + +void AttributeJsonHandler::reset(JsonHandler* pParent, std::unordered_map* pAttributes) { + ObjectJsonHandler::reset(pParent); + this->_pAttributes = pAttributes; +} + +JsonHandler* AttributeJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + assert(this->_pAttributes); + + return this->property( + this->_index, + this->_pAttributes->emplace(str, -1).first->second + ); +} diff --git a/CesiumGltfReader/src/AttributeJsonHandler.h b/CesiumGltfReader/src/AttributeJsonHandler.h new file mode 100644 index 000000000..57f577efe --- /dev/null +++ b/CesiumGltfReader/src/AttributeJsonHandler.h @@ -0,0 +1,17 @@ +#pragma once + +#include "ObjectJsonHandler.h" +#include "IntegerJsonHandler.h" +#include + +namespace CesiumGltf { + class AttributeJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, std::unordered_map* pAttributes); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + std::unordered_map* _pAttributes; + IntegerJsonHandler _index; + }; +} \ No newline at end of file diff --git a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp new file mode 100644 index 000000000..15eb483ba --- /dev/null +++ b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp @@ -0,0 +1,8 @@ +#include "ExtensibleObjectJsonHandler.h" + +using namespace CesiumGltf; + +JsonHandler* ExtensibleObjectJsonHandler::ExtensibleObjectKey(const char* /*str*/, ExtensibleObject& /*o*/) { + // TODO: handle extensions and extras. + return this->ignore(); +} \ No newline at end of file diff --git a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h new file mode 100644 index 000000000..2fbe240aa --- /dev/null +++ b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h @@ -0,0 +1,12 @@ +#pragma once + +#include "ObjectJsonHandler.h" + +namespace CesiumGltf { + struct ExtensibleObject; + + class ExtensibleObjectJsonHandler : public ObjectJsonHandler { + protected: + JsonHandler* ExtensibleObjectKey(const char* str, ExtensibleObject& o); + }; +} diff --git a/CesiumGltfReader/src/JsonHandler.h b/CesiumGltfReader/src/JsonHandler.h index f9434b727..18a612acd 100644 --- a/CesiumGltfReader/src/JsonHandler.h +++ b/CesiumGltfReader/src/JsonHandler.h @@ -7,19 +7,22 @@ namespace CesiumGltf { class JsonHandler { public: virtual JsonHandler* Null(); - virtual JsonHandler* Bool(bool /*b*/); - virtual JsonHandler* Int(int /*i*/); - virtual JsonHandler* Uint(unsigned /*i*/); - virtual JsonHandler* Int64(int64_t /*i*/); - virtual JsonHandler* Uint64(uint64_t /*i*/); - virtual JsonHandler* Double(double /*d*/); - virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/); - virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/); + virtual JsonHandler* Bool(bool b); + virtual JsonHandler* Int(int i); + virtual JsonHandler* Uint(unsigned i); + virtual JsonHandler* Int64(int64_t i); + virtual JsonHandler* Uint64(uint64_t i); + virtual JsonHandler* Double(double d); + virtual JsonHandler* RawNumber(const char* str, size_t length, bool copy); + virtual JsonHandler* String(const char* str, size_t length, bool copy); virtual JsonHandler* StartObject(); - virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/); - virtual JsonHandler* EndObject(size_t /*memberCount*/); + virtual JsonHandler* Key(const char* str, size_t length, bool copy); + virtual JsonHandler* EndObject(size_t memberCount); virtual JsonHandler* StartArray(); - virtual JsonHandler* EndArray(size_t /*elementCount*/); + virtual JsonHandler* EndArray(size_t elementCount); + + protected: + void reset(JsonHandler* pParent); template JsonHandler* property(TAccessor& accessor, TProperty& value) { @@ -29,9 +32,6 @@ namespace CesiumGltf { JsonHandler* parent(); - protected: - void reset(JsonHandler* pParent); - private: JsonHandler* _pParent = nullptr; }; diff --git a/CesiumGltfReader/src/MeshJsonHandler.cpp b/CesiumGltfReader/src/MeshJsonHandler.cpp index 221ec05d3..ff777815f 100644 --- a/CesiumGltfReader/src/MeshJsonHandler.cpp +++ b/CesiumGltfReader/src/MeshJsonHandler.cpp @@ -13,8 +13,9 @@ JsonHandler* MeshJsonHandler::Key(const char* str, size_t /*length*/, bool /*cop using namespace std::string_literals; assert(this->_pMesh); + if ("primitives"s == str) return property(this->_primitives, this->_pMesh->primitives); if ("weights"s == str) return property(this->_weights, this->_pMesh->weights); - return this->ignore(); + return this->NamedObjectKey(str, *this->_pMesh); } diff --git a/CesiumGltfReader/src/MeshJsonHandler.h b/CesiumGltfReader/src/MeshJsonHandler.h index fb84f465e..9ee7dcb0e 100644 --- a/CesiumGltfReader/src/MeshJsonHandler.h +++ b/CesiumGltfReader/src/MeshJsonHandler.h @@ -1,15 +1,16 @@ #pragma once #include "CesiumGltf/Mesh.h" -#include "ObjectArrayJsonHandler.h" #include "DoubleArrayJsonHandler.h" +#include "NamedObjectJsonHandler.h" +#include "ObjectArrayJsonHandler.h" #include "PrimitiveJsonHandler.h" namespace CesiumGltf { struct Mesh; struct Primitive; - class MeshJsonHandler : public ObjectJsonHandler { + class MeshJsonHandler : public NamedObjectJsonHandler { public: void reset(JsonHandler* pParent, Mesh* pMesh); virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; diff --git a/CesiumGltfReader/src/NamedObjectJsonHandler.cpp b/CesiumGltfReader/src/NamedObjectJsonHandler.cpp new file mode 100644 index 000000000..b586e37b6 --- /dev/null +++ b/CesiumGltfReader/src/NamedObjectJsonHandler.cpp @@ -0,0 +1,11 @@ +#include "NamedObjectJsonHandler.h" +#include "CesiumGltf/NamedObject.h" +#include + +using namespace CesiumGltf; + +JsonHandler* NamedObjectJsonHandler::NamedObjectKey(const char* str, NamedObject& o) { + using namespace std::string_literals; + if ("name"s == str) return property(this->_name, o.name); + return this->ExtensibleObjectKey(str, o); +} diff --git a/CesiumGltfReader/src/NamedObjectJsonHandler.h b/CesiumGltfReader/src/NamedObjectJsonHandler.h new file mode 100644 index 000000000..66237ef6d --- /dev/null +++ b/CesiumGltfReader/src/NamedObjectJsonHandler.h @@ -0,0 +1,16 @@ +#pragma once + +#include "ExtensibleObjectJsonHandler.h" +#include "StringJsonHandler.h" + +namespace CesiumGltf { + struct NamedObject; + + class NamedObjectJsonHandler : public ExtensibleObjectJsonHandler { + protected: + JsonHandler* NamedObjectKey(const char* str, NamedObject& o); + + private: + StringJsonHandler _name; + }; +} diff --git a/CesiumGltfReader/src/ObjectJsonHandler.cpp b/CesiumGltfReader/src/ObjectJsonHandler.cpp new file mode 100644 index 000000000..7c04a64c9 --- /dev/null +++ b/CesiumGltfReader/src/ObjectJsonHandler.cpp @@ -0,0 +1,33 @@ +#include "ObjectJsonHandler.h" + +using namespace CesiumGltf; + +JsonHandler* ObjectJsonHandler::StartObject() { + ++this->_depth; + if (this->_depth > 1) { + return this->StartSubObject(); + } + return this; +} + +JsonHandler* ObjectJsonHandler::EndObject(size_t memberCount) { + --this->_depth; + + if (this->_depth > 0) + return this->EndSubObject(memberCount); + else + return this->parent(); +} + +JsonHandler* ObjectJsonHandler::StartSubObject() { + return nullptr; +} + +JsonHandler* ObjectJsonHandler::EndSubObject(size_t /*memberCount*/) { + return nullptr; +} + +JsonHandler* ObjectJsonHandler::ignore() { + this->_ignoreHandler.reset(this); + return &this->_ignoreHandler; +} diff --git a/CesiumGltfReader/src/ObjectJsonHandler.h b/CesiumGltfReader/src/ObjectJsonHandler.h index fb53087e8..8a41834b2 100644 --- a/CesiumGltfReader/src/ObjectJsonHandler.h +++ b/CesiumGltfReader/src/ObjectJsonHandler.h @@ -6,20 +6,17 @@ namespace CesiumGltf { class ObjectJsonHandler : public JsonHandler { public: - virtual JsonHandler* StartObject() override { - return this; - } + virtual JsonHandler* StartObject() override final; + virtual JsonHandler* EndObject(size_t memberCount) override final; - virtual JsonHandler* EndObject(size_t /*memberCount*/) override { - return this->parent(); - } + protected: + virtual JsonHandler* StartSubObject(); + virtual JsonHandler* EndSubObject(size_t memberCount); - JsonHandler* ignore() { - this->_ignoreHandler.reset(this); - return &this->_ignoreHandler; - } + JsonHandler* ignore(); private: IgnoreValueJsonHandler _ignoreHandler; + int32_t _depth = 0; }; } diff --git a/CesiumGltfReader/src/PrimitiveJsonHandler.cpp b/CesiumGltfReader/src/PrimitiveJsonHandler.cpp index 4fc3bf0c8..654fff367 100644 --- a/CesiumGltfReader/src/PrimitiveJsonHandler.cpp +++ b/CesiumGltfReader/src/PrimitiveJsonHandler.cpp @@ -14,9 +14,10 @@ JsonHandler* PrimitiveJsonHandler::Key(const char* str, size_t /*length*/, bool using namespace std::string_literals; assert(this->_pPrimitive); + if ("attributes"s == str) return property(this->_attributes, this->_pPrimitive->attributes); if ("indices"s == str) return property(this->_indices, this->_pPrimitive->indices); if ("material"s == str) return property(this->_material, this->_pPrimitive->material); if ("mode"s == str) return property(this->_mode, this->_pPrimitive->mode); - return this->ignore(); + return this->ExtensibleObjectKey(str, *this->_pPrimitive); } diff --git a/CesiumGltfReader/src/PrimitiveJsonHandler.h b/CesiumGltfReader/src/PrimitiveJsonHandler.h index d64f56efa..a341d395c 100644 --- a/CesiumGltfReader/src/PrimitiveJsonHandler.h +++ b/CesiumGltfReader/src/PrimitiveJsonHandler.h @@ -1,20 +1,22 @@ #pragma once +#include "AttributeJsonHandler.h" #include "CesiumGltf/PrimitiveMode.h" -#include "ObjectJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" #include "IntegerJsonHandler.h" namespace CesiumGltf { struct Primitive; - class PrimitiveJsonHandler : public ObjectJsonHandler { + class PrimitiveJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(JsonHandler* pParent, Primitive* pPrimitive); virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; private: Primitive* _pPrimitive = nullptr; - // std::unordered_map attributes; + + AttributeJsonHandler _attributes; IntegerJsonHandler _indices; IntegerJsonHandler _material; IntegerJsonHandler _mode; diff --git a/CesiumGltfReader/src/StringJsonHandler.cpp b/CesiumGltfReader/src/StringJsonHandler.cpp new file mode 100644 index 000000000..0cc0bfa56 --- /dev/null +++ b/CesiumGltfReader/src/StringJsonHandler.cpp @@ -0,0 +1,13 @@ +#include "StringJsonHandler.h" + +using namespace CesiumGltf; + +void StringJsonHandler::reset(JsonHandler* pParent, std::string* pString) { + JsonHandler::reset(pParent); + this->_pString = pString; +} + +JsonHandler* StringJsonHandler::String(const char* str, size_t length, bool /*copy*/) { + *this->_pString = std::string(str, length); + return this->parent(); +} diff --git a/CesiumGltfReader/src/StringJsonHandler.h b/CesiumGltfReader/src/StringJsonHandler.h new file mode 100644 index 000000000..29df3f70f --- /dev/null +++ b/CesiumGltfReader/src/StringJsonHandler.h @@ -0,0 +1,15 @@ +#pragma once + +#include "JsonHandler.h" +#include + +namespace CesiumGltf { + class StringJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, std::string* pString); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + + private: + std::string* _pString = nullptr; + }; +} From a67ed6a6ca71d891651d095465fa3eed15111b23 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 4 Jan 2021 22:32:35 +1100 Subject: [PATCH 10/61] Add support for primitive targets. --- CesiumGltf/test/TestGltfModel.cpp | 9 ++++++++- CesiumGltfReader/src/PrimitiveJsonHandler.cpp | 2 ++ CesiumGltfReader/src/PrimitiveJsonHandler.h | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index dd31aa476..735162720 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -25,7 +25,10 @@ TEST_CASE("GltfModel") { " \"attributes\": {"s + " \"POSITION\": 0,"s + " \"NORMAL\": 1"s + - " }"s + + " },"s + + " \"targets\": ["s + + " {\"POSITION\": 10, \"NORMAL\": 11}"s + + " ]"s + " }]"s + " }],"s + " \"surprise\":{\"foo\":true}"s + @@ -48,6 +51,10 @@ TEST_CASE("GltfModel") { REQUIRE(model.meshes[0].primitives.size() == 1); CHECK(model.meshes[0].primitives[0].attributes["POSITION"] == 0); CHECK(model.meshes[0].primitives[0].attributes["NORMAL"] == 1); + + REQUIRE(model.meshes[0].primitives[0].targets.size() == 1); + CHECK(model.meshes[0].primitives[0].targets[0]["POSITION"] == 10); + CHECK(model.meshes[0].primitives[0].targets[0]["NORMAL"] == 11); // std::vector v; // GltfModel model = GltfModel::fromMemory(v); // GltfCollection meshes = model.meshes(); diff --git a/CesiumGltfReader/src/PrimitiveJsonHandler.cpp b/CesiumGltfReader/src/PrimitiveJsonHandler.cpp index 654fff367..206c47825 100644 --- a/CesiumGltfReader/src/PrimitiveJsonHandler.cpp +++ b/CesiumGltfReader/src/PrimitiveJsonHandler.cpp @@ -14,10 +14,12 @@ JsonHandler* PrimitiveJsonHandler::Key(const char* str, size_t /*length*/, bool using namespace std::string_literals; assert(this->_pPrimitive); + if ("attributes"s == str) return property(this->_attributes, this->_pPrimitive->attributes); if ("indices"s == str) return property(this->_indices, this->_pPrimitive->indices); if ("material"s == str) return property(this->_material, this->_pPrimitive->material); if ("mode"s == str) return property(this->_mode, this->_pPrimitive->mode); + if ("targets"s == str) return property(this->_targets, this->_pPrimitive->targets); return this->ExtensibleObjectKey(str, *this->_pPrimitive); } diff --git a/CesiumGltfReader/src/PrimitiveJsonHandler.h b/CesiumGltfReader/src/PrimitiveJsonHandler.h index a341d395c..bc7e50db9 100644 --- a/CesiumGltfReader/src/PrimitiveJsonHandler.h +++ b/CesiumGltfReader/src/PrimitiveJsonHandler.h @@ -4,6 +4,7 @@ #include "CesiumGltf/PrimitiveMode.h" #include "ExtensibleObjectJsonHandler.h" #include "IntegerJsonHandler.h" +#include "ObjectArrayJsonHandler.h" namespace CesiumGltf { struct Primitive; @@ -20,6 +21,6 @@ namespace CesiumGltf { IntegerJsonHandler _indices; IntegerJsonHandler _material; IntegerJsonHandler _mode; - // std::vector> targets; + ObjectArrayJsonHandler, AttributeJsonHandler> _targets; }; } From 1504ed3d9026e2f8f76099ab5aea2c5713181ad4 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 4 Jan 2021 22:54:54 +1100 Subject: [PATCH 11/61] Add materials. --- CesiumGltf/include/CesiumGltf/AlphaMode.h | 9 ++++++++ CesiumGltf/include/CesiumGltf/Material.h | 22 +++++++++++++++++++ CesiumGltf/include/CesiumGltf/Model.h | 8 +++++++ .../include/CesiumGltf/NormalTextureInfo.h | 9 ++++++++ .../include/CesiumGltf/OcclusionTextureInfo.h | 9 ++++++++ .../include/CesiumGltf/PbrMetallicRoughness.h | 15 +++++++++++++ CesiumGltf/include/CesiumGltf/TextureInfo.h | 10 +++++++++ 7 files changed, 82 insertions(+) create mode 100644 CesiumGltf/include/CesiumGltf/AlphaMode.h create mode 100644 CesiumGltf/include/CesiumGltf/Material.h create mode 100644 CesiumGltf/include/CesiumGltf/NormalTextureInfo.h create mode 100644 CesiumGltf/include/CesiumGltf/OcclusionTextureInfo.h create mode 100644 CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h create mode 100644 CesiumGltf/include/CesiumGltf/TextureInfo.h diff --git a/CesiumGltf/include/CesiumGltf/AlphaMode.h b/CesiumGltf/include/CesiumGltf/AlphaMode.h new file mode 100644 index 000000000..0da91adba --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AlphaMode.h @@ -0,0 +1,9 @@ +#pragma once + +namespace CesiumGltf { + enum class AlphaMode { + OPAQUE, + MASK, + BLEND + }; +} \ No newline at end of file diff --git a/CesiumGltf/include/CesiumGltf/Material.h b/CesiumGltf/include/CesiumGltf/Material.h new file mode 100644 index 000000000..519eb0bee --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Material.h @@ -0,0 +1,22 @@ +#pragma once + +#include "CesiumGltf/AlphaMode.h" +#include "CesiumGltf/NamedObject.h" +#include "CesiumGltf/NormalTextureInfo.h" +#include "CesiumGltf/OcclusionTextureInfo.h" +#include "CesiumGltf/PbrMetallicRoughness.h" +#include "CesiumGltf/TextureInfo.h" +#include + +namespace CesiumGltf { + struct Material : public NamedObject { + PbrMetallicRoughness pbrMetallicRoughness; + NormalTextureInfo normalTexture; + OcclusionTextureInfo occlusionTexture; + TextureInfo emissiveTexture; + std::vector emissiveFactor; + AlphaMode alphaMode; + double alphaCutoff; + bool doubleSided; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index 0254561d6..d63204f81 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -3,6 +3,7 @@ #include "CesiumGltf/Accessor.h" #include "CesiumGltf/ExtensibleObject.h" #include "CesiumGltf/Mesh.h" +#include "CesiumGltf/Material.h" #include namespace CesiumGltf { @@ -23,5 +24,12 @@ namespace CesiumGltf { * A mesh is a set of {@link Primitive} instances to be rendered. */ std::vector meshes; + + /** + * @brief An array of materials. + * + * A material defines the appearance of a primitive. + */ + std::vector materials; }; } diff --git a/CesiumGltf/include/CesiumGltf/NormalTextureInfo.h b/CesiumGltf/include/CesiumGltf/NormalTextureInfo.h new file mode 100644 index 000000000..21d1e87c7 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/NormalTextureInfo.h @@ -0,0 +1,9 @@ +#pragma once + +#include "CesiumGltf/TextureInfo.h" + +namespace CesiumGltf { + struct NormalTextureInfo : public TextureInfo { + double scale; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/OcclusionTextureInfo.h b/CesiumGltf/include/CesiumGltf/OcclusionTextureInfo.h new file mode 100644 index 000000000..72d5d3c13 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/OcclusionTextureInfo.h @@ -0,0 +1,9 @@ +#pragma once + +#include "CesiumGltf/TextureInfo.h" + +namespace CesiumGltf { + struct OcclusionTextureInfo : public TextureInfo { + double strength; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h new file mode 100644 index 000000000..d16b3bcae --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h @@ -0,0 +1,15 @@ +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/TextureInfo.h" +#include + +namespace CesiumGltf { + struct PbrMetallicRoughness : public ExtensibleObject { + std::vector baseColorFactor; + TextureInfo baseColorTexture; + std::vector metallicFactor; + std::vector roughnessFactor; + TextureInfo metallicRoughnessTexture; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/TextureInfo.h b/CesiumGltf/include/CesiumGltf/TextureInfo.h new file mode 100644 index 000000000..f6d45bfa8 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/TextureInfo.h @@ -0,0 +1,10 @@ +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" + +namespace CesiumGltf { + struct TextureInfo : public ExtensibleObject { + int32_t index; + int32_t texCoord; + }; +} From e49e6552a908ec0745bcf14a51774ba992dc5a3e Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 4 Jan 2021 23:26:47 +1100 Subject: [PATCH 12/61] Deserialize materials. --- .../include/CesiumGltf/PbrMetallicRoughness.h | 4 +- CesiumGltfReader/src/AccessorJsonHandler.cpp | 1 - CesiumGltfReader/src/AccessorJsonHandler.h | 2 - CesiumGltfReader/src/AlphaModeJsonHandler.cpp | 20 ++++++++++ CesiumGltfReader/src/AlphaModeJsonHandler.h | 15 ++++++++ CesiumGltfReader/src/DoubleJsonHandler.cpp | 38 +++++++++++++++++++ CesiumGltfReader/src/DoubleJsonHandler.h | 20 ++++++++++ CesiumGltfReader/src/MaterialJsonHandler.cpp | 26 +++++++++++++ CesiumGltfReader/src/MaterialJsonHandler.h | 35 +++++++++++++++++ .../src/NormalTextureInfoJsonHandler.cpp | 21 ++++++++++ .../src/NormalTextureInfoJsonHandler.h | 19 ++++++++++ .../src/OcclusionTextureInfoJsonHandler.cpp | 21 ++++++++++ .../src/OcclusionTextureInfoJsonHandler.h | 19 ++++++++++ .../src/PbrMetallicRoughnessJsonHandler.cpp | 25 ++++++++++++ .../src/PbrMetallicRoughnessJsonHandler.h | 25 ++++++++++++ .../src/TextureInfoJsonHandler.cpp | 22 +++++++++++ CesiumGltfReader/src/TextureInfoJsonHandler.h | 20 ++++++++++ 17 files changed, 328 insertions(+), 5 deletions(-) create mode 100644 CesiumGltfReader/src/AlphaModeJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AlphaModeJsonHandler.h create mode 100644 CesiumGltfReader/src/DoubleJsonHandler.cpp create mode 100644 CesiumGltfReader/src/DoubleJsonHandler.h create mode 100644 CesiumGltfReader/src/MaterialJsonHandler.cpp create mode 100644 CesiumGltfReader/src/MaterialJsonHandler.h create mode 100644 CesiumGltfReader/src/NormalTextureInfoJsonHandler.cpp create mode 100644 CesiumGltfReader/src/NormalTextureInfoJsonHandler.h create mode 100644 CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.cpp create mode 100644 CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.h create mode 100644 CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.cpp create mode 100644 CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.h create mode 100644 CesiumGltfReader/src/TextureInfoJsonHandler.cpp create mode 100644 CesiumGltfReader/src/TextureInfoJsonHandler.h diff --git a/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h index d16b3bcae..216edaa31 100644 --- a/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h +++ b/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h @@ -8,8 +8,8 @@ namespace CesiumGltf { struct PbrMetallicRoughness : public ExtensibleObject { std::vector baseColorFactor; TextureInfo baseColorTexture; - std::vector metallicFactor; - std::vector roughnessFactor; + double metallicFactor; + double roughnessFactor; TextureInfo metallicRoughnessTexture; }; } diff --git a/CesiumGltfReader/src/AccessorJsonHandler.cpp b/CesiumGltfReader/src/AccessorJsonHandler.cpp index 8fee6a07e..5dbf38730 100644 --- a/CesiumGltfReader/src/AccessorJsonHandler.cpp +++ b/CesiumGltfReader/src/AccessorJsonHandler.cpp @@ -23,7 +23,6 @@ JsonHandler* AccessorJsonHandler::Key(const char* str, size_t /*length*/, bool / if ("type"s == str) return property(this->_type, this->_pAccessor->type); if ("max"s == str) return property(this->_max, this->_pAccessor->max); if ("min"s == str) return property(this->_min, this->_pAccessor->min); - if ("name"s == str) return property(this->_name, this->_pAccessor->name); return this->NamedObjectKey(str, *this->_pAccessor); } diff --git a/CesiumGltfReader/src/AccessorJsonHandler.h b/CesiumGltfReader/src/AccessorJsonHandler.h index 9cd5918e3..b3938cf13 100644 --- a/CesiumGltfReader/src/AccessorJsonHandler.h +++ b/CesiumGltfReader/src/AccessorJsonHandler.h @@ -6,7 +6,6 @@ #include "DoubleArrayJsonHandler.h" #include "IntegerJsonHandler.h" #include "NamedObjectJsonHandler.h" -#include "StringJsonHandler.h" #include namespace CesiumGltf { @@ -28,6 +27,5 @@ namespace CesiumGltf { AttributeTypeJsonHandler _type; DoubleArrayJsonHandler _max; DoubleArrayJsonHandler _min; - StringJsonHandler _name; }; } diff --git a/CesiumGltfReader/src/AlphaModeJsonHandler.cpp b/CesiumGltfReader/src/AlphaModeJsonHandler.cpp new file mode 100644 index 000000000..149d3e3a3 --- /dev/null +++ b/CesiumGltfReader/src/AlphaModeJsonHandler.cpp @@ -0,0 +1,20 @@ +#include "AlphaModeJsonHandler.h" +#include + +using namespace CesiumGltf; + +void AlphaModeJsonHandler::reset(JsonHandler* pParent, AlphaMode* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +JsonHandler* AlphaModeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + if ("OPAQUE"s == str) *this->_pEnum = AlphaMode::OPAQUE; + else if ("MASK"s == str) *this->_pEnum = AlphaMode::MASK; + else if ("BLEND"s == str) *this->_pEnum = AlphaMode::BLEND; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/AlphaModeJsonHandler.h b/CesiumGltfReader/src/AlphaModeJsonHandler.h new file mode 100644 index 000000000..5ecd44ebd --- /dev/null +++ b/CesiumGltfReader/src/AlphaModeJsonHandler.h @@ -0,0 +1,15 @@ +#pragma once + +#include "JsonHandler.h" +#include "CesiumGltf/AlphaMode.h" + +namespace CesiumGltf { + class AlphaModeJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, AlphaMode* pEnum); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + + private: + AlphaMode* _pEnum = nullptr; + }; +} diff --git a/CesiumGltfReader/src/DoubleJsonHandler.cpp b/CesiumGltfReader/src/DoubleJsonHandler.cpp new file mode 100644 index 000000000..d3a7b2f46 --- /dev/null +++ b/CesiumGltfReader/src/DoubleJsonHandler.cpp @@ -0,0 +1,38 @@ +#include "DoubleJsonHandler.h" + +using namespace CesiumGltf; + +void DoubleJsonHandler::reset(JsonHandler* pParent, double* pDouble) { + JsonHandler::reset(pParent); + this->_pDouble = pDouble; +} + +JsonHandler* DoubleJsonHandler::Int(int i) { + assert(this->_pDouble); + *this->_pDouble = static_cast(i); + return this->parent(); +} + +JsonHandler* DoubleJsonHandler::Uint(unsigned i) { + assert(this->_pDouble); + *this->_pDouble = static_cast(i); + return this->parent(); +} + +JsonHandler* DoubleJsonHandler::Int64(int64_t i) { + assert(this->_pDouble); + *this->_pDouble = static_cast(i); + return this->parent(); +} + +JsonHandler* DoubleJsonHandler::Uint64(uint64_t i) { + assert(this->_pDouble); + *this->_pDouble = static_cast(i); + return this->parent(); +} + +JsonHandler* DoubleJsonHandler::Double(double d) { + assert(this->_pDouble); + *this->_pDouble = d; + return this->parent(); +} diff --git a/CesiumGltfReader/src/DoubleJsonHandler.h b/CesiumGltfReader/src/DoubleJsonHandler.h new file mode 100644 index 000000000..8b1175e87 --- /dev/null +++ b/CesiumGltfReader/src/DoubleJsonHandler.h @@ -0,0 +1,20 @@ +#pragma once + +#include "JsonHandler.h" +#include + +namespace CesiumGltf { + class DoubleJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, double* pDouble); + + virtual JsonHandler* Int(int i) override; + virtual JsonHandler* Uint(unsigned i) override; + virtual JsonHandler* Int64(int64_t i) override; + virtual JsonHandler* Uint64(uint64_t i) override; + virtual JsonHandler* Double(double d) override; + + private: + double* _pDouble = nullptr; + }; +} diff --git a/CesiumGltfReader/src/MaterialJsonHandler.cpp b/CesiumGltfReader/src/MaterialJsonHandler.cpp new file mode 100644 index 000000000..2134586af --- /dev/null +++ b/CesiumGltfReader/src/MaterialJsonHandler.cpp @@ -0,0 +1,26 @@ +#include "MaterialJsonHandler.h" +#include "CesiumGltf/Material.h" +#include +#include + +using namespace CesiumGltf; + +void MaterialJsonHandler::reset(JsonHandler* pParent, Material* pMaterial) { + ObjectJsonHandler::reset(pParent); + this->_pMaterial = pMaterial; +} + +JsonHandler* MaterialJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pMaterial); + + if ("pbrMetallicRoughness"s == str) return property(this->_pbrMetallicRoughness, this->_pMaterial->pbrMetallicRoughness); + if ("emissiveTexture"s == str) return property(this->_emissiveTexture, this->_pMaterial->emissiveTexture); + if ("emissiveFactor"s == str) return property(this->_emissiveFactor, this->_pMaterial->emissiveFactor); + if ("alphaMode"s == str) return property(this->_alphaMode, this->_pMaterial->alphaMode); + if ("alphaCutoff"s == str) return property(this->_alphaCutoff, this->_pMaterial->alphaCutoff); + if ("doubleSided"s == str) return property(this->_doubleSided, this->_pMaterial->doubleSided); + + return this->NamedObjectKey(str, *this->_pMaterial); +} diff --git a/CesiumGltfReader/src/MaterialJsonHandler.h b/CesiumGltfReader/src/MaterialJsonHandler.h new file mode 100644 index 000000000..ef2510c44 --- /dev/null +++ b/CesiumGltfReader/src/MaterialJsonHandler.h @@ -0,0 +1,35 @@ +#pragma once + +#include "AlphaModeJsonHandler.h" +#include "BoolJsonHandler.h" +#include "DoubleArrayJsonHandler.h" +#include "DoubleJsonHandler.h" +#include "NamedObjectJsonHandler.h" +#include "NormalTextureInfoJsonHandler.h" +#include "OcclusionTextureInfoJsonHandler.h" +#include "PbrMetallicRoughnessJsonHandler.h" +#include "TextureInfoJsonHandler.h" +#include + +namespace CesiumGltf { + struct Material; + + class MaterialJsonHandler : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pParent, Material* pMaterial); + + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + Material* _pMaterial = nullptr; + + PbrMetallicRoughnessJsonHandler _pbrMetallicRoughness; + NormalTextureInfoJsonHandler normalTexture; + OcclusionTextureInfoJsonHandler occlusionTexture; + TextureInfoJsonHandler _emissiveTexture; + DoubleArrayJsonHandler _emissiveFactor; + AlphaModeJsonHandler _alphaMode; + DoubleJsonHandler _alphaCutoff; + BoolJsonHandler _doubleSided; + }; +} diff --git a/CesiumGltfReader/src/NormalTextureInfoJsonHandler.cpp b/CesiumGltfReader/src/NormalTextureInfoJsonHandler.cpp new file mode 100644 index 000000000..9a151469f --- /dev/null +++ b/CesiumGltfReader/src/NormalTextureInfoJsonHandler.cpp @@ -0,0 +1,21 @@ +#include "NormalTextureInfoJsonHandler.h" +#include "CesiumGltf/NormalTextureInfo.h" +#include +#include + +using namespace CesiumGltf; + +void NormalTextureInfoJsonHandler::reset(JsonHandler* pParent, NormalTextureInfo* pNormalTextureInfo) { + JsonHandler::reset(pParent); + this->_pNormalTextureInfo = pNormalTextureInfo; +} + +JsonHandler* NormalTextureInfoJsonHandler::Key(const char* str, size_t length, bool copy) { + using namespace std::string_literals; + + assert(this->_pNormalTextureInfo); + + if ("scale"s == str) return property(this->_scale, this->_pNormalTextureInfo->scale); + + return TextureInfoJsonHandler::Key(str, length, copy); +} diff --git a/CesiumGltfReader/src/NormalTextureInfoJsonHandler.h b/CesiumGltfReader/src/NormalTextureInfoJsonHandler.h new file mode 100644 index 000000000..8e20b9988 --- /dev/null +++ b/CesiumGltfReader/src/NormalTextureInfoJsonHandler.h @@ -0,0 +1,19 @@ +#pragma once + +#include "TextureInfoJsonHandler.h" +#include "DoubleJsonHandler.h" + +namespace CesiumGltf { + struct NormalTextureInfo; + + class NormalTextureInfoJsonHandler : public TextureInfoJsonHandler { + public: + void reset(JsonHandler* pParent, NormalTextureInfo* pNormalTextureInfo); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + NormalTextureInfo* _pNormalTextureInfo = nullptr; + + DoubleJsonHandler _scale; + }; +} diff --git a/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.cpp b/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.cpp new file mode 100644 index 000000000..eeb9bdae8 --- /dev/null +++ b/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.cpp @@ -0,0 +1,21 @@ +#include "OcclusionTextureInfoJsonHandler.h" +#include "CesiumGltf/OcclusionTextureInfo.h" +#include +#include + +using namespace CesiumGltf; + +void OcclusionTextureInfoJsonHandler::reset(JsonHandler* pParent, OcclusionTextureInfo* pOcclusionTextureInfo) { + JsonHandler::reset(pParent); + this->_pOcclusionTextureInfo = pOcclusionTextureInfo; +} + +JsonHandler* OcclusionTextureInfoJsonHandler::Key(const char* str, size_t length, bool copy) { + using namespace std::string_literals; + + assert(this->_pOcclusionTextureInfo); + + if ("strength"s == str) return property(this->_strength, this->_pOcclusionTextureInfo->strength); + + return TextureInfoJsonHandler::Key(str, length, copy); +} diff --git a/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.h b/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.h new file mode 100644 index 000000000..63fd16f6a --- /dev/null +++ b/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.h @@ -0,0 +1,19 @@ +#pragma once + +#include "TextureInfoJsonHandler.h" +#include "DoubleJsonHandler.h" + +namespace CesiumGltf { + struct OcclusionTextureInfo; + + class OcclusionTextureInfoJsonHandler : public TextureInfoJsonHandler { + public: + void reset(JsonHandler* pParent, OcclusionTextureInfo* pOcclusionTextureInfo); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + OcclusionTextureInfo* _pOcclusionTextureInfo = nullptr; + + DoubleJsonHandler _strength; + }; +} diff --git a/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.cpp b/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.cpp new file mode 100644 index 000000000..847bf565c --- /dev/null +++ b/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.cpp @@ -0,0 +1,25 @@ +#include "PbrMetallicRoughnessJsonHandler.h" +#include "CesiumGltf/PbrMetallicRoughness.h" +#include +#include + +using namespace CesiumGltf; + +void PbrMetallicRoughnessJsonHandler::reset(JsonHandler* pParent, PbrMetallicRoughness* pPbr) { + JsonHandler::reset(pParent); + this->_pPbr = pPbr; +} + +JsonHandler* PbrMetallicRoughnessJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pPbr); + + if ("baseColorFactor"s == str) return property(this->_baseColorFactor, this->_pPbr->baseColorFactor); + if ("baseColorTexture"s == str) return property(this->_baseColorTexture, this->_pPbr->baseColorTexture); + if ("metallicFactor"s == str) return property(this->_metallicFactor, this->_pPbr->metallicFactor); + if ("roughnessFactor"s == str) return property(this->_roughnessFactor, this->_pPbr->roughnessFactor); + if ("metallicRoughnessTexture"s == str) return property(this->_metallicRoughnessTexture, this->_pPbr->metallicRoughnessTexture); + + return this->ExtensibleObjectKey(str, *this->_pPbr); +} diff --git a/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.h b/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.h new file mode 100644 index 000000000..72f4068ef --- /dev/null +++ b/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.h @@ -0,0 +1,25 @@ +#pragma once + +#include "DoubleArrayJsonHandler.h" +#include "DoubleJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" +#include "TextureInfoJsonHandler.h" + +namespace CesiumGltf { + struct PbrMetallicRoughness; + + class PbrMetallicRoughnessJsonHandler : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pParent, PbrMetallicRoughness* pPbr); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + PbrMetallicRoughness* _pPbr = nullptr; + + DoubleArrayJsonHandler _baseColorFactor; + TextureInfoJsonHandler _baseColorTexture; + DoubleJsonHandler _metallicFactor; + DoubleJsonHandler _roughnessFactor; + TextureInfoJsonHandler _metallicRoughnessTexture; + }; +} diff --git a/CesiumGltfReader/src/TextureInfoJsonHandler.cpp b/CesiumGltfReader/src/TextureInfoJsonHandler.cpp new file mode 100644 index 000000000..a7aaca0ce --- /dev/null +++ b/CesiumGltfReader/src/TextureInfoJsonHandler.cpp @@ -0,0 +1,22 @@ +#include "TextureInfoJsonHandler.h" +#include "CesiumGltf/TextureInfo.h" +#include +#include + +using namespace CesiumGltf; + +void TextureInfoJsonHandler::reset(JsonHandler* pParent, TextureInfo* pTextureInfo) { + JsonHandler::reset(pParent); + this->_pTextureInfo = pTextureInfo; +} + +JsonHandler* TextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pTextureInfo); + + if ("index"s == str) return property(this->_index, this->_pTextureInfo->index); + if ("texCoord"s == str) return property(this->_texCoord, this->_pTextureInfo->texCoord); + + return this->ExtensibleObjectKey(str, *this->_pTextureInfo); +} diff --git a/CesiumGltfReader/src/TextureInfoJsonHandler.h b/CesiumGltfReader/src/TextureInfoJsonHandler.h new file mode 100644 index 000000000..bbd063378 --- /dev/null +++ b/CesiumGltfReader/src/TextureInfoJsonHandler.h @@ -0,0 +1,20 @@ +#pragma once + +#include "ExtensibleObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct TextureInfo; + + class TextureInfoJsonHandler : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pParent, TextureInfo* pTextureInfo); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + TextureInfo* _pTextureInfo = nullptr; + + IntegerJsonHandler _index; + IntegerJsonHandler _texCoord; + }; +} From 232b87c84f72e487f360aa0e532e7c2e1bb6bb28 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Tue, 5 Jan 2021 21:21:15 +1100 Subject: [PATCH 13/61] Generate glTF classes from JSON Schema. --- .gitmodules | 3 + extern/glTF | 1 + tools/generate-gltf-classes/.gitignore | 1 + .../generate-gltf-classes/.vscode/launch.json | 21 +++ tools/generate-gltf-classes/SchemaCache.js | 22 +++ tools/generate-gltf-classes/generate.js | 95 +++++++++++++ .../getNameFromSchema.js | 6 + tools/generate-gltf-classes/indent.js | 10 ++ tools/generate-gltf-classes/index.js | 40 ++++++ tools/generate-gltf-classes/package-lock.json | 132 ++++++++++++++++++ tools/generate-gltf-classes/package.json | 18 +++ .../generate-gltf-classes/resolveProperty.js | 102 ++++++++++++++ tools/generate-gltf-classes/unindent.js | 23 +++ 13 files changed, 474 insertions(+) create mode 160000 extern/glTF create mode 100644 tools/generate-gltf-classes/.gitignore create mode 100644 tools/generate-gltf-classes/.vscode/launch.json create mode 100644 tools/generate-gltf-classes/SchemaCache.js create mode 100644 tools/generate-gltf-classes/generate.js create mode 100644 tools/generate-gltf-classes/getNameFromSchema.js create mode 100644 tools/generate-gltf-classes/indent.js create mode 100644 tools/generate-gltf-classes/index.js create mode 100644 tools/generate-gltf-classes/package-lock.json create mode 100644 tools/generate-gltf-classes/package.json create mode 100644 tools/generate-gltf-classes/resolveProperty.js create mode 100644 tools/generate-gltf-classes/unindent.js diff --git a/.gitmodules b/.gitmodules index c5734baec..a3211153c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "extern/rapidjson"] path = extern/rapidjson url = https://github.com/Tencent/rapidjson.git +[submodule "extern/glTF"] + path = extern/glTF + url = https://github.com/KhronosGroup/glTF.git diff --git a/extern/glTF b/extern/glTF new file mode 160000 index 000000000..fa4e11c77 --- /dev/null +++ b/extern/glTF @@ -0,0 +1 @@ +Subproject commit fa4e11c77c906362f8ac3a22506c4d07f27fcb20 diff --git a/tools/generate-gltf-classes/.gitignore b/tools/generate-gltf-classes/.gitignore new file mode 100644 index 000000000..3c3629e64 --- /dev/null +++ b/tools/generate-gltf-classes/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/tools/generate-gltf-classes/.vscode/launch.json b/tools/generate-gltf-classes/.vscode/launch.json new file mode 100644 index 000000000..5cf20d2f3 --- /dev/null +++ b/tools/generate-gltf-classes/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-node", + "request": "launch", + "name": "Launch Program", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}\\index.js", + "args": [ + "--schema", "../../extern/glTF/specification/2.0/schema/", + "--output", "test" + ] + } + ] +} \ No newline at end of file diff --git a/tools/generate-gltf-classes/SchemaCache.js b/tools/generate-gltf-classes/SchemaCache.js new file mode 100644 index 000000000..9f6e8190f --- /dev/null +++ b/tools/generate-gltf-classes/SchemaCache.js @@ -0,0 +1,22 @@ +const path = require("path"); +const fs = require("fs"); + +class SchemaCache { + constructor(schemaPath) { + this.schemaPath = schemaPath; + this.cache = {}; + } + + load(name) { + const existing = this.cache[name]; + if (existing) { + return existing; + } + + const result = JSON.parse(fs.readFileSync(path.join(this.schemaPath, name), "utf-8")); + this.cache[name] = result; + return result; + } +} + +module.exports = SchemaCache; diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js new file mode 100644 index 000000000..13f1225cc --- /dev/null +++ b/tools/generate-gltf-classes/generate.js @@ -0,0 +1,95 @@ +const path = require("path"); +const fs = require("fs"); +const lodash = require("lodash"); +const resolveProperty = require("./resolveProperty"); +const getNameFromSchema = require("./getNameFromSchema"); +const unindent = require("./unindent"); +const indent = require("./indent"); + +function generate(schemaCache, nameMapping, outputDir, schema) { + const name = getNameFromSchema(nameMapping, schema); + + console.log(`Generating ${name}`); + // let baseSpecifier = ""; + // if (modelSchema.allOf && modelSchema.allOf.length > 0 && modelSchema.allOf[0].$ref) { + // switch (modelSchema.allOf[0].$ref) { + // case "" + // } + // } + + const properties = Object.keys(schema.properties) + .map((key) => + resolveProperty( + schemaCache, + nameMapping, + key, + schema.properties[key] + ) + ) + .filter((property) => property !== undefined); + + const localTypes = lodash.uniq(lodash.flatten(properties.map(property => property.localTypes))); + + const headers = lodash.uniq(lodash.flatten(properties.map(property => property.headers))); + headers.sort(); + + const header = ` + #pragma once + + ${headers.map(header => `#include ${header}`).join("\n")} + + namespace CesiumGltf { + struct ${name} { + ${indent(localTypes.join("\n\n"), 16)} + + ${properties.map(property => `${property.type} ${property.name};`).join("\n\n ")} + }; + } + `; + + const headerOutputDir = path.join(outputDir, "include", "CesiumGltf"); + fs.mkdirSync(headerOutputDir, { recursive: true }); + const headerOutputPath = path.join(headerOutputDir, name + ".h"); + fs.writeFileSync(headerOutputPath, unindent(header), "utf-8"); + + return lodash.uniq(lodash.flatten(properties.map(property => property.schemas))); +} + +function generateProperty( + schemaCache, + nameMapping, + propertyName, + propertyDetails +) { + if (Object.keys(propertyDetails).length === 0) { + return undefined; + } + + const type = getPropertyType(schemaCache, nameMapping, propertyDetails); + + return type + " " + propertyName + ";"; +} + +function getPropertyType(schemaCache, nameMapping, propertyDetails) { + if (propertyDetails.type == "array") { + return `std::vector<${getPropertyType( + schemaCache, + nameMapping, + propertyDetails.items + )}>`; + } else if (propertyDetails.type == "string") { + return "std::string"; + } else if (propertyDetails.$ref) { + const itemSchema = schemaCache.load(propertyDetails.$ref); + if (itemSchema.title === "glTF Id") { + return "int32_t"; + } + return getNameFromSchema(nameMapping, itemSchema); + } else if (propertyDetails.allOf && propertyDetails.allOf.length == 1) { + return getPropertyType(schemaCache, nameMapping, propertyDetails.allOf[0]); + } + + return "unknown"; +} + +module.exports = generate; diff --git a/tools/generate-gltf-classes/getNameFromSchema.js b/tools/generate-gltf-classes/getNameFromSchema.js new file mode 100644 index 000000000..901f916fa --- /dev/null +++ b/tools/generate-gltf-classes/getNameFromSchema.js @@ -0,0 +1,6 @@ +function getNameFromSchema(nameMapping, schema) { + const title = schema.title; + return nameMapping[title] ? nameMapping[title] : title.replace(/\s/g, ""); +} + +module.exports = getNameFromSchema; \ No newline at end of file diff --git a/tools/generate-gltf-classes/indent.js b/tools/generate-gltf-classes/indent.js new file mode 100644 index 000000000..e32faf938 --- /dev/null +++ b/tools/generate-gltf-classes/indent.js @@ -0,0 +1,10 @@ +function indent(text, spaces) { + let indentText = ""; + for (let i = 0; i < spaces; ++i) { + indentText += " "; + } + + return text.replace(new RegExp("\r?\n", "gm"), "\n" + indentText); +} + +module.exports = indent; \ No newline at end of file diff --git a/tools/generate-gltf-classes/index.js b/tools/generate-gltf-classes/index.js new file mode 100644 index 000000000..dc739bfeb --- /dev/null +++ b/tools/generate-gltf-classes/index.js @@ -0,0 +1,40 @@ +const yargs = require("yargs"); +const path = require("path"); +const SchemaCache = require("./SchemaCache"); +const generate = require("./generate") + +const argv = yargs.options({ + schema: { + alias: "s", + description: "The path to the glTF 2.0 JSONSchema files.", + demandOption: true, + type: "string" + }, + output: { + alias: "o", + description: "The output directory for the generated files.", + demandOption: true, + type: "string" + } +}).argv; + +const nameMapping = { + "glTF": "Model", + "glTF Id": "ExtensibleObject", + "glTFRootProperty": "NamedObject" +}; + +const schemaCache = new SchemaCache(argv.schema); +const modelSchema = schemaCache.load("glTF.schema.json"); + +const processed = {}; + +let schemas = [modelSchema]; +while (schemas.length > 0) { + const schema = schemas.pop(); + if (processed[schema.title]) { + continue; + } + processed[schema.title] = true; + schemas.push(...generate(schemaCache, nameMapping, argv.output, schema)); +} diff --git a/tools/generate-gltf-classes/package-lock.json b/tools/generate-gltf-classes/package-lock.json new file mode 100644 index 000000000..28dd5ea5e --- /dev/null +++ b/tools/generate-gltf-classes/package-lock.json @@ -0,0 +1,132 @@ +{ + "name": "generate-gltf-classes", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" + } + } +} diff --git a/tools/generate-gltf-classes/package.json b/tools/generate-gltf-classes/package.json new file mode 100644 index 000000000..b0ba3a874 --- /dev/null +++ b/tools/generate-gltf-classes/package.json @@ -0,0 +1,18 @@ +{ + "name": "generate-gltf-classes", + "version": "1.0.0", + "description": "Generate CesiumGltf C++ classes from the glTF spec.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "CesiumGS, Inc.", + "license": "UNLICENSED", + "dependencies": { + "lodash": "^4.17.20", + "yargs": "^16.2.0" + }, + "devDependencies": { + "prettier": "^2.2.1" + } +} diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js new file mode 100644 index 000000000..2d5bed626 --- /dev/null +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -0,0 +1,102 @@ +const getNameFromSchema = require("./getNameFromSchema"); +const unindent = require("./unindent"); +const indent = require("./indent"); + +function resolveProperty(schemaCache, nameMapping, propertyName, propertyDetails) { + if (Object.keys(propertyDetails).length === 0) { + // Ignore totally empty properties. + return undefined; + } + + const result = { + headers: [], + type: "", + name: propertyName, + handlerType: "", + schemas: [], + localTypes: [] + }; + + if (propertyDetails.type == "array") { + result.headers.push(""); + + const itemProperty = resolveProperty(schemaCache, nameMapping, propertyName + ".items", propertyDetails.items); + if (!itemProperty) { + return undefined; + } + + result.headers.push(...itemProperty.headers); + result.schemas.push(...itemProperty.schemas); + result.localTypes.push(...itemProperty.localTypes); + result.type = `std::vector<${itemProperty.type}>`; + } else if (propertyDetails.type == "integer") { + result.headers.push(""); + result.type = "int64_t"; + } else if (propertyDetails.type == "number") { + result.type = "double"; + } else if (propertyDetails.type == "boolean") { + result.type = "bool"; + } else if (propertyDetails.type == "string") { + result.headers.push(""); + result.type = "std::string"; + } else if (propertyDetails.type == "object" && propertyDetails.additionalProperties) { + const additionalPropertiesProperty = resolveProperty(schemaCache, nameMapping, propertyName + ".additionalProperties", propertyDetails.additionalProperties); + if (!additionalPropertiesProperty) { + return undefined; + } + + result.headers.push(...additionalPropertiesProperty.headers); + result.schemas.push(...additionalPropertiesProperty.schemas); + result.localTypes.push(...additionalPropertiesProperty.localTypes); + + result.headers.push(""); + result.type = `std::unordered_map`; + } else if (propertyDetails.anyOf && propertyDetails.anyOf.length > 0 && propertyDetails.anyOf[0].enum) { + const enumName = toPascalCase(propertyName); + result.localTypes.push(unindent(` + enum class ${toPascalCase(propertyName)} { + ${indent(propertyDetails.anyOf.map(e => createEnum(e)).filter(e => e !== undefined).join(",\n\n"), 16)} + };` + )); + result.type = enumName; + } else if (propertyDetails.$ref) { + const itemSchema = schemaCache.load(propertyDetails.$ref); + if (itemSchema.title === "glTF Id") { + result.headers.push(""); + result.type = "int32_t"; + } else { + result.type = getNameFromSchema(nameMapping, itemSchema); + result.headers.push(`"CesiumGltf/${result.type}.h"`); + result.schemas.push(itemSchema); + } + } else if (propertyDetails.allOf && propertyDetails.allOf.length == 1) { + return resolveProperty(schemaCache, nameMapping, propertyName, propertyDetails.allOf[0]); + } else { + console.warn(`Skipping unhandled property ${propertyName}.`); + return undefined; + } + + return result; +} + +function toPascalCase(name) { + if (name.length === 0) { + return name; + } + + return name[0].toUpperCase() + name.substr(1); +} + +function createEnum(enumDetails) { + if (!enumDetails.enum || enumDetails.enum.length === 0) { + return undefined; + } + + if (typeof enumDetails.enum[0] === 'string') { + return enumDetails.enum[0]; + } else { + return `${enumDetails.description} = ${enumDetails.enum[0]}`; + } +} + +module.exports = resolveProperty; \ No newline at end of file diff --git a/tools/generate-gltf-classes/unindent.js b/tools/generate-gltf-classes/unindent.js new file mode 100644 index 000000000..b71a5ab11 --- /dev/null +++ b/tools/generate-gltf-classes/unindent.js @@ -0,0 +1,23 @@ +function unindent(indentedText) { + let skip = 0; + let indent = 0; + let spaces = ""; + + for (let i = 0; i < indentedText.length; ++i) { + if (indentedText[i] == "\n" || indentedText[i] == "\r") { + ++skip; + } else if (indentedText[i] == " ") { + ++indent; + spaces += " "; + } else { + break; + } + } + + const regex = new RegExp("^(" + spaces + ")", "gm"); + const unindented = indentedText.substr(skip).replace(regex, ""); + return unindented; + } + + module.exports = unindent; + \ No newline at end of file From b27f43b057bc72e392a491823647af5efa6c2bf8 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Tue, 5 Jan 2021 21:46:21 +1100 Subject: [PATCH 14/61] Include doc in generated classes. --- tools/generate-gltf-classes/.gitignore | 1 + .../generate-gltf-classes/.vscode/launch.json | 2 +- tools/generate-gltf-classes/generate.js | 42 +++++-------------- .../generate-gltf-classes/resolveProperty.js | 9 +++- tools/generate-gltf-classes/unindent.js | 4 +- 5 files changed, 21 insertions(+), 37 deletions(-) diff --git a/tools/generate-gltf-classes/.gitignore b/tools/generate-gltf-classes/.gitignore index 3c3629e64..3e6e1184f 100644 --- a/tools/generate-gltf-classes/.gitignore +++ b/tools/generate-gltf-classes/.gitignore @@ -1 +1,2 @@ node_modules +test_output diff --git a/tools/generate-gltf-classes/.vscode/launch.json b/tools/generate-gltf-classes/.vscode/launch.json index 5cf20d2f3..2d1a585cf 100644 --- a/tools/generate-gltf-classes/.vscode/launch.json +++ b/tools/generate-gltf-classes/.vscode/launch.json @@ -14,7 +14,7 @@ "program": "${workspaceFolder}\\index.js", "args": [ "--schema", "../../extern/glTF/specification/2.0/schema/", - "--output", "test" + "--output", "test_output" ] } ] diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index 13f1225cc..400436214 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -42,7 +42,7 @@ function generate(schemaCache, nameMapping, outputDir, schema) { struct ${name} { ${indent(localTypes.join("\n\n"), 16)} - ${properties.map(property => `${property.type} ${property.name};`).join("\n\n ")} + ${indent(properties.map(property => formatProperty(property)).join("\n\n"), 16)} }; } `; @@ -55,41 +55,19 @@ function generate(schemaCache, nameMapping, outputDir, schema) { return lodash.uniq(lodash.flatten(properties.map(property => property.schemas))); } -function generateProperty( - schemaCache, - nameMapping, - propertyName, - propertyDetails -) { - if (Object.keys(propertyDetails).length === 0) { - return undefined; - } +function formatProperty(property) { + let result = ""; - const type = getPropertyType(schemaCache, nameMapping, propertyDetails); + result += `/**\n * @brief ${property.briefDoc || property.name}\n`; + if (property.fullDoc) { + result += ` *\n * ${property.fullDoc.split("\n").join("\n * ")}`; + } - return type + " " + propertyName + ";"; -} + result += ` */\n`; -function getPropertyType(schemaCache, nameMapping, propertyDetails) { - if (propertyDetails.type == "array") { - return `std::vector<${getPropertyType( - schemaCache, - nameMapping, - propertyDetails.items - )}>`; - } else if (propertyDetails.type == "string") { - return "std::string"; - } else if (propertyDetails.$ref) { - const itemSchema = schemaCache.load(propertyDetails.$ref); - if (itemSchema.title === "glTF Id") { - return "int32_t"; - } - return getNameFromSchema(nameMapping, itemSchema); - } else if (propertyDetails.allOf && propertyDetails.allOf.length == 1) { - return getPropertyType(schemaCache, nameMapping, propertyDetails.allOf[0]); - } + result += `${property.type} ${property.name};`; - return "unknown"; + return result; } module.exports = generate; diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index 2d5bed626..1090d6a7b 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -14,7 +14,9 @@ function resolveProperty(schemaCache, nameMapping, propertyName, propertyDetails name: propertyName, handlerType: "", schemas: [], - localTypes: [] + localTypes: [], + briefDoc: propertyDetails.description, + fullDoc: propertyDetails.gltf_detailedDescription }; if (propertyDetails.type == "array") { @@ -70,7 +72,10 @@ function resolveProperty(schemaCache, nameMapping, propertyName, propertyDetails result.schemas.push(itemSchema); } } else if (propertyDetails.allOf && propertyDetails.allOf.length == 1) { - return resolveProperty(schemaCache, nameMapping, propertyName, propertyDetails.allOf[0]); + const nested = resolveProperty(schemaCache, nameMapping, propertyName, propertyDetails.allOf[0]); + nested.briefDoc = propertyDetails.description; + nested.fullDoc = propertyDetails.gltf_detailedDescription; + return nested; } else { console.warn(`Skipping unhandled property ${propertyName}.`); return undefined; diff --git a/tools/generate-gltf-classes/unindent.js b/tools/generate-gltf-classes/unindent.js index b71a5ab11..03a59a5ed 100644 --- a/tools/generate-gltf-classes/unindent.js +++ b/tools/generate-gltf-classes/unindent.js @@ -15,9 +15,9 @@ function unindent(indentedText) { } const regex = new RegExp("^(" + spaces + ")", "gm"); - const unindented = indentedText.substr(skip).replace(regex, ""); + const lastLine = new RegExp("^\\s+$", "gm"); + const unindented = indentedText.substr(skip).replace(regex, "").replace(lastLine, ""); return unindented; } module.exports = unindent; - \ No newline at end of file From d206b096a0d19c81584b2cb360548f0ee146705b Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Tue, 5 Jan 2021 23:03:48 +1100 Subject: [PATCH 15/61] Generate reader header files. --- .../generate-gltf-classes/.vscode/launch.json | 3 +- tools/generate-gltf-classes/generate.js | 74 ++++- tools/generate-gltf-classes/index.js | 17 +- .../generate-gltf-classes/resolveProperty.js | 289 ++++++++++++------ 4 files changed, 279 insertions(+), 104 deletions(-) diff --git a/tools/generate-gltf-classes/.vscode/launch.json b/tools/generate-gltf-classes/.vscode/launch.json index 2d1a585cf..01b82159d 100644 --- a/tools/generate-gltf-classes/.vscode/launch.json +++ b/tools/generate-gltf-classes/.vscode/launch.json @@ -14,7 +14,8 @@ "program": "${workspaceFolder}\\index.js", "args": [ "--schema", "../../extern/glTF/specification/2.0/schema/", - "--output", "test_output" + "--output", "test_output/model", + "--readerOutput", "test_output/reader" ] } ] diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index 400436214..319068665 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -6,7 +6,9 @@ const getNameFromSchema = require("./getNameFromSchema"); const unindent = require("./unindent"); const indent = require("./indent"); -function generate(schemaCache, nameMapping, outputDir, schema) { +function generate(options, schema) { + const { schemaCache, nameMapping, outputDir, readerOutputDir } = options; + const name = getNameFromSchema(nameMapping, schema); console.log(`Generating ${name}`); @@ -19,30 +21,37 @@ function generate(schemaCache, nameMapping, outputDir, schema) { const properties = Object.keys(schema.properties) .map((key) => - resolveProperty( - schemaCache, - nameMapping, - key, - schema.properties[key] - ) + resolveProperty(schemaCache, nameMapping, key, schema.properties[key]) ) .filter((property) => property !== undefined); - const localTypes = lodash.uniq(lodash.flatten(properties.map(property => property.localTypes))); + const localTypes = lodash.uniq( + lodash.flatten(properties.map((property) => property.localTypes)) + ); - const headers = lodash.uniq(lodash.flatten(properties.map(property => property.headers))); + const headers = lodash.uniq( + lodash.flatten(properties.map((property) => property.headers)) + ); headers.sort(); const header = ` #pragma once - ${headers.map(header => `#include ${header}`).join("\n")} + ${headers.map((header) => `#include ${header}`).join("\n")} namespace CesiumGltf { + /** + * @brief ${schema.description} + */ struct ${name} { ${indent(localTypes.join("\n\n"), 16)} - ${indent(properties.map(property => formatProperty(property)).join("\n\n"), 16)} + ${indent( + properties + .map((property) => formatProperty(property)) + .join("\n\n"), + 16 + )} }; } `; @@ -52,7 +61,42 @@ function generate(schemaCache, nameMapping, outputDir, schema) { const headerOutputPath = path.join(headerOutputDir, name + ".h"); fs.writeFileSync(headerOutputPath, unindent(header), "utf-8"); - return lodash.uniq(lodash.flatten(properties.map(property => property.schemas))); + const readerHeaders = lodash.uniq( + lodash.flatten(properties.map((property) => property.readerHeaders)) + ); + headers.sort(); + + const readerHeader = ` + #pragma once + + ${readerHeaders.map((header) => `#include ${header}`).join("\n")} + + namespace CesiumGltf { + class ${name}JsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, ${name}* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + ${name}* _pObject; + ${indent( + properties + .map((property) => formatReaderProperty(property)) + .join("\n"), + 12 + )} + }; + } + `; + + const readerHeaderOutputDir = path.join(readerOutputDir, "src"); + fs.mkdirSync(readerHeaderOutputDir, { recursive: true }); + const readerHeaderOutputPath = path.join(readerHeaderOutputDir, name + "JsonHandler.h"); + fs.writeFileSync(readerHeaderOutputPath, unindent(readerHeader), "utf-8"); + + return lodash.uniq( + lodash.flatten(properties.map((property) => property.schemas)) + ); } function formatProperty(property) { @@ -60,7 +104,7 @@ function formatProperty(property) { result += `/**\n * @brief ${property.briefDoc || property.name}\n`; if (property.fullDoc) { - result += ` *\n * ${property.fullDoc.split("\n").join("\n * ")}`; + result += ` *\n * ${property.fullDoc.split("\n").join("\n * ")}\n`; } result += ` */\n`; @@ -70,4 +114,8 @@ function formatProperty(property) { return result; } +function formatReaderProperty(property) { + return `${property.readerType} _${property.name};` +} + module.exports = generate; diff --git a/tools/generate-gltf-classes/index.js b/tools/generate-gltf-classes/index.js index dc739bfeb..3a84339db 100644 --- a/tools/generate-gltf-classes/index.js +++ b/tools/generate-gltf-classes/index.js @@ -12,7 +12,13 @@ const argv = yargs.options({ }, output: { alias: "o", - description: "The output directory for the generated files.", + description: "The output directory for the generated glTF class files.", + demandOption: true, + type: "string" + }, + readerOutput: { + alias: "r", + description: "The output directory for the generated reader files.", demandOption: true, type: "string" } @@ -27,6 +33,13 @@ const nameMapping = { const schemaCache = new SchemaCache(argv.schema); const modelSchema = schemaCache.load("glTF.schema.json"); +const options = { + schemaCache, + nameMapping, + outputDir: argv.output, + readerOutputDir: argv.readerOutput +}; + const processed = {}; let schemas = [modelSchema]; @@ -36,5 +49,5 @@ while (schemas.length > 0) { continue; } processed[schema.title] = true; - schemas.push(...generate(schemaCache, nameMapping, argv.output, schema)); + schemas.push(...generate(options, schema)); } diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index 1090d6a7b..9a88a0cfc 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -1,107 +1,220 @@ const getNameFromSchema = require("./getNameFromSchema"); const unindent = require("./unindent"); const indent = require("./indent"); +const { result } = require("lodash"); -function resolveProperty(schemaCache, nameMapping, propertyName, propertyDetails) { - if (Object.keys(propertyDetails).length === 0) { - // Ignore totally empty properties. - return undefined; - } +function resolveProperty( + schemaCache, + nameMapping, + propertyName, + propertyDetails +) { + if (Object.keys(propertyDetails).length === 0) { + // Ignore totally empty properties. + return undefined; + } - const result = { - headers: [], - type: "", - name: propertyName, - handlerType: "", - schemas: [], - localTypes: [], - briefDoc: propertyDetails.description, - fullDoc: propertyDetails.gltf_detailedDescription + if (propertyDetails.type == "array") { + return resolveArray( + schemaCache, + nameMapping, + propertyName, + propertyDetails + ); + } else if (propertyDetails.type == "integer") { + return { + ...propertyDefaults(propertyName, propertyDetails), + headers: [""], + type: "int64_t", + readerHeaders: [`"IntegerJsonHandler.h"`], + readerType: "IntegerJsonHandler" + }; + } else if (propertyDetails.type == "number") { + return { + ...propertyDefaults(propertyName, propertyDetails), + type: "double", + readerHeaders: [`"DoubleJsonHandler.h"`], + readerType: "DoubleJsonHandler", + }; + } else if (propertyDetails.type == "boolean") { + return { + ...propertyDefaults(propertyName, propertyDetails), + type: "bool", + readerHeaders: `"BoolJsonHandler.h"`, + readerType: "BoolJsonHandler", }; + } else if (propertyDetails.type == "string") { + return { + ...propertyDefaults(propertyName, propertyDetails), + type: "bool", + headers: [""], + readerHeaders: [`"StringJsonHandler.h"`], + readerType: "StringJsonHandler", + }; + } else if ( + propertyDetails.type == "object" && + propertyDetails.additionalProperties + ) { + return resolveDictionary( + schemaCache, + nameMapping, + propertyName, + propertyDetails + ); + } else if ( + propertyDetails.anyOf && + propertyDetails.anyOf.length > 0 && + propertyDetails.anyOf[0].enum + ) { + return resolveEnum( + schemaCache, + nameMapping, + propertyName, + propertyDetails + ); + } else if (propertyDetails.$ref) { + const itemSchema = schemaCache.load(propertyDetails.$ref); + if (itemSchema.title === "glTF Id") { + return { + ...propertyDefaults(propertyName, propertyDetails), + type: "bool", + headers: [""], + readerHeaders: [`"IntegerJsonHandler.h"`], + readerType: "IntegerJsonHandler", + }; + } else { + const type = getNameFromSchema(nameMapping, itemSchema); + return { + ...propertyDefaults(propertyName, propertyDetails), + type: getNameFromSchema(nameMapping, itemSchema), + headers: [`"CesiumGltf/${type}.h"`], + readerType: `${type}JsonHandler`, + readerHeaders: [`"${type}JsonHandler.h"`], + schemas: [itemSchema] + }; + } + } else if (propertyDetails.allOf && propertyDetails.allOf.length == 1) { + const nested = resolveProperty( + schemaCache, + nameMapping, + propertyName, + propertyDetails.allOf[0] + ); + nested.briefDoc = propertyDetails.description; + nested.fullDoc = propertyDetails.gltf_detailedDescription; + return nested; + } else { + console.warn(`Skipping unhandled property ${propertyName}.`); + return undefined; + } +} - if (propertyDetails.type == "array") { - result.headers.push(""); - - const itemProperty = resolveProperty(schemaCache, nameMapping, propertyName + ".items", propertyDetails.items); - if (!itemProperty) { - return undefined; - } +function toPascalCase(name) { + if (name.length === 0) { + return name; + } - result.headers.push(...itemProperty.headers); - result.schemas.push(...itemProperty.schemas); - result.localTypes.push(...itemProperty.localTypes); - result.type = `std::vector<${itemProperty.type}>`; - } else if (propertyDetails.type == "integer") { - result.headers.push(""); - result.type = "int64_t"; - } else if (propertyDetails.type == "number") { - result.type = "double"; - } else if (propertyDetails.type == "boolean") { - result.type = "bool"; - } else if (propertyDetails.type == "string") { - result.headers.push(""); - result.type = "std::string"; - } else if (propertyDetails.type == "object" && propertyDetails.additionalProperties) { - const additionalPropertiesProperty = resolveProperty(schemaCache, nameMapping, propertyName + ".additionalProperties", propertyDetails.additionalProperties); - if (!additionalPropertiesProperty) { - return undefined; - } + return name[0].toUpperCase() + name.substr(1); +} - result.headers.push(...additionalPropertiesProperty.headers); - result.schemas.push(...additionalPropertiesProperty.schemas); - result.localTypes.push(...additionalPropertiesProperty.localTypes); +function createEnum(enumDetails) { + if (!enumDetails.enum || enumDetails.enum.length === 0) { + return undefined; + } - result.headers.push(""); - result.type = `std::unordered_map`; - } else if (propertyDetails.anyOf && propertyDetails.anyOf.length > 0 && propertyDetails.anyOf[0].enum) { - const enumName = toPascalCase(propertyName); - result.localTypes.push(unindent(` - enum class ${toPascalCase(propertyName)} { - ${indent(propertyDetails.anyOf.map(e => createEnum(e)).filter(e => e !== undefined).join(",\n\n"), 16)} - };` - )); - result.type = enumName; - } else if (propertyDetails.$ref) { - const itemSchema = schemaCache.load(propertyDetails.$ref); - if (itemSchema.title === "glTF Id") { - result.headers.push(""); - result.type = "int32_t"; - } else { - result.type = getNameFromSchema(nameMapping, itemSchema); - result.headers.push(`"CesiumGltf/${result.type}.h"`); - result.schemas.push(itemSchema); - } - } else if (propertyDetails.allOf && propertyDetails.allOf.length == 1) { - const nested = resolveProperty(schemaCache, nameMapping, propertyName, propertyDetails.allOf[0]); - nested.briefDoc = propertyDetails.description; - nested.fullDoc = propertyDetails.gltf_detailedDescription; - return nested; - } else { - console.warn(`Skipping unhandled property ${propertyName}.`); - return undefined; - } + if (typeof enumDetails.enum[0] === "string") { + return enumDetails.enum[0]; + } else { + return `${enumDetails.description} = ${enumDetails.enum[0]}`; + } +} - return result; +function propertyDefaults(propertyName, propertyDetails) { + return { + name: propertyName, + headers: [], + readerHeaders: [], + type: "", + readerType: "", + schemas: [], + localTypes: [], + readerLocalTypes: [], + briefDoc: propertyDetails.description, + fullDoc: propertyDetails.gltf_detailedDescription, + }; } -function toPascalCase(name) { - if (name.length === 0) { - return name; - } +function resolveArray(schemaCache, nameMapping, propertyName, propertyDetails) { + const itemProperty = resolveProperty( + schemaCache, + nameMapping, + propertyName + ".items", + propertyDetails.items + ); - return name[0].toUpperCase() + name.substr(1); + if (!itemProperty) { + return undefined; + } + + return { + ...propertyDefaults(propertyName, propertyDetails), + name: propertyName, + headers: ["", ...itemProperty.headers], + schemas: itemProperty.schemas, + localTypes: itemProperty.localTypes, + type: `std::vector<${itemProperty.type}>`, + readerHeaders: [`"ArrayJsonHandler.h"`, ...itemProperty.readerHeaders], + readerType: `ArrayJsonHandler<${itemProperty.type}>` + }; } -function createEnum(enumDetails) { - if (!enumDetails.enum || enumDetails.enum.length === 0) { - return undefined; - } +function resolveDictionary(schemaCache, nameMapping, propertyName, propertyDetails) { + const additional = resolveProperty( + schemaCache, + nameMapping, + propertyName + ".additionalProperties", + propertyDetails.additionalProperties + ); - if (typeof enumDetails.enum[0] === 'string') { - return enumDetails.enum[0]; - } else { - return `${enumDetails.description} = ${enumDetails.enum[0]}`; - } + if (!additional) { + return undefined; + } + + return { + ...propertyDefaults(propertyName, propertyDetails), + name: propertyName, + headers: ["", ...additional.headers], + schema: additional.schemas, + localTypes: additional.localTypes, + type: `std::unordered_map`, + readerHeaders: [`"DictionaryJsonHandler.h"`, ...additional.readerHeaders], + readerType: `DictionaryJsonHandler<${additional.type}, ${additional.readerType}>` + }; } -module.exports = resolveProperty; \ No newline at end of file +function resolveEnum(schemaCache, nameMapping, propertyName, propertyDetails) { + const enumName = toPascalCase(propertyName); + + return { + ...propertyDefaults(propertyName, propertyDetails), + localTypes: [ + unindent(` + enum class ${toPascalCase(propertyName)} { + ${indent( + propertyDetails.anyOf + .map((e) => createEnum(e)) + .filter((e) => e !== undefined) + .join(",\n\n"), + 8 + )} + }; + `) + ], + type: enumName, + readerLocalTypes: [ + "// TODO: enum handler" + ], + readerType: `${enumName}JsonHandler` + }; +} +module.exports = resolveProperty; From bd1a51cc17a1db64fb6c3066059d411b0ddffe30 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Tue, 5 Jan 2021 23:16:37 +1100 Subject: [PATCH 16/61] Generate reader implementations. --- tools/generate-gltf-classes/generate.js | 49 +++++++++++++++++++++---- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index 319068665..605ec8f01 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -12,12 +12,11 @@ function generate(options, schema) { const name = getNameFromSchema(nameMapping, schema); console.log(`Generating ${name}`); - // let baseSpecifier = ""; - // if (modelSchema.allOf && modelSchema.allOf.length > 0 && modelSchema.allOf[0].$ref) { - // switch (modelSchema.allOf[0].$ref) { - // case "" - // } - // } + + let base = "Extensible"; + if (schema.allOf && schema.allOf.length > 0 && schema.allOf[0].$ref && schema.allOf[0].$ref === "glTFChildOfRootProperty.schema.json") { + base = "Named"; + } const properties = Object.keys(schema.properties) .map((key) => @@ -43,7 +42,7 @@ function generate(options, schema) { /** * @brief ${schema.description} */ - struct ${name} { + struct ${name} final : public ${base}Object { ${indent(localTypes.join("\n\n"), 16)} ${indent( @@ -72,7 +71,7 @@ function generate(options, schema) { ${readerHeaders.map((header) => `#include ${header}`).join("\n")} namespace CesiumGltf { - class ${name}JsonHandler : public ObjectJsonHandler { + class ${name}JsonHandler final : public ${base}ObjectJsonHandler { public: void reset(JsonHandler* pHandler, ${name}* pObject); virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; @@ -94,6 +93,36 @@ function generate(options, schema) { const readerHeaderOutputPath = path.join(readerHeaderOutputDir, name + "JsonHandler.h"); fs.writeFileSync(readerHeaderOutputPath, unindent(readerHeader), "utf-8"); + const readerImpl = ` + #include "${name}JsonHandler.h" + #include + + using namespace CesiumGltf; + + void ${name}JsonHandler::reset(JsonHandler* pParent, ${name}* pObject) { + ${base}JsonHandler::reset(pParent); + this->_pObject = pObject; + } + + JsonHandler* ${name}JsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + ${indent( + properties + .map((property) => formatReaderPropertyImpl(property)) + .join("\n"), + 10 + )} + + return this->${base}ObjectKey(str, *this->_pTextureInfo); + } + `; + + const readerSourceOutputPath = path.join(readerHeaderOutputDir, name + "JsonHandler.cpp"); + fs.writeFileSync(readerSourceOutputPath, unindent(readerImpl), "utf-8"); + return lodash.uniq( lodash.flatten(properties.map((property) => property.schemas)) ); @@ -118,4 +147,8 @@ function formatReaderProperty(property) { return `${property.readerType} _${property.name};` } +function formatReaderPropertyImpl(property) { + return `if ("${property.name}"s == str) return property(this->_${property.name}, this->_pObject->${property.name});`; +} + module.exports = generate; From 33db3a2d4bae8ddecccafeffa3d82bd70e210522 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Tue, 5 Jan 2021 23:51:54 +1100 Subject: [PATCH 17/61] Generate enum readers. --- tools/generate-gltf-classes/generate.js | 19 +++- .../generate-gltf-classes/resolveProperty.js | 101 ++++++++++++++---- 2 files changed, 99 insertions(+), 21 deletions(-) diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index 605ec8f01..0a837efe7 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -20,7 +20,7 @@ function generate(options, schema) { const properties = Object.keys(schema.properties) .map((key) => - resolveProperty(schemaCache, nameMapping, key, schema.properties[key]) + resolveProperty(schemaCache, nameMapping, name, key, schema.properties[key]) ) .filter((property) => property !== undefined); @@ -63,7 +63,11 @@ function generate(options, schema) { const readerHeaders = lodash.uniq( lodash.flatten(properties.map((property) => property.readerHeaders)) ); - headers.sort(); + readerHeaders.sort(); + + const readerLocalTypes = lodash.uniq( + lodash.flatten(properties.map((property) => property.readerLocalTypes)) + ); const readerHeader = ` #pragma once @@ -71,12 +75,16 @@ function generate(options, schema) { ${readerHeaders.map((header) => `#include ${header}`).join("\n")} namespace CesiumGltf { + struct ${name}; + class ${name}JsonHandler final : public ${base}ObjectJsonHandler { public: void reset(JsonHandler* pHandler, ${name}* pObject); virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; private: + ${indent(readerLocalTypes.join("\n\n"), 12)} + ${name}* _pObject; ${indent( properties @@ -93,9 +101,14 @@ function generate(options, schema) { const readerHeaderOutputPath = path.join(readerHeaderOutputDir, name + "JsonHandler.h"); fs.writeFileSync(readerHeaderOutputPath, unindent(readerHeader), "utf-8"); + const readerLocalTypesImpl = lodash.uniq( + lodash.flatten(properties.map((property) => property.readerLocalTypesImpl)) + ); + const readerImpl = ` #include "${name}JsonHandler.h" #include + #include using namespace CesiumGltf; @@ -118,6 +131,8 @@ function generate(options, schema) { return this->${base}ObjectKey(str, *this->_pTextureInfo); } + + ${indent(readerLocalTypesImpl.join("\n\n"), 8)} `; const readerSourceOutputPath = path.join(readerHeaderOutputDir, name + "JsonHandler.cpp"); diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index 9a88a0cfc..5d1ff4722 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -6,6 +6,7 @@ const { result } = require("lodash"); function resolveProperty( schemaCache, nameMapping, + parentName, propertyName, propertyDetails ) { @@ -18,6 +19,7 @@ function resolveProperty( return resolveArray( schemaCache, nameMapping, + parentName, propertyName, propertyDetails ); @@ -58,6 +60,7 @@ function resolveProperty( return resolveDictionary( schemaCache, nameMapping, + parentName, propertyName, propertyDetails ); @@ -69,6 +72,7 @@ function resolveProperty( return resolveEnum( schemaCache, nameMapping, + parentName, propertyName, propertyDetails ); @@ -97,6 +101,7 @@ function resolveProperty( const nested = resolveProperty( schemaCache, nameMapping, + parentName, propertyName, propertyDetails.allOf[0] ); @@ -117,18 +122,6 @@ function toPascalCase(name) { return name[0].toUpperCase() + name.substr(1); } -function createEnum(enumDetails) { - if (!enumDetails.enum || enumDetails.enum.length === 0) { - return undefined; - } - - if (typeof enumDetails.enum[0] === "string") { - return enumDetails.enum[0]; - } else { - return `${enumDetails.description} = ${enumDetails.enum[0]}`; - } -} - function propertyDefaults(propertyName, propertyDetails) { return { name: propertyName, @@ -139,15 +132,17 @@ function propertyDefaults(propertyName, propertyDetails) { schemas: [], localTypes: [], readerLocalTypes: [], + readerLocalTypesImpl: [], briefDoc: propertyDetails.description, fullDoc: propertyDetails.gltf_detailedDescription, }; } -function resolveArray(schemaCache, nameMapping, propertyName, propertyDetails) { +function resolveArray(schemaCache, nameMapping, parentName, propertyName, propertyDetails) { const itemProperty = resolveProperty( schemaCache, nameMapping, + parentName, propertyName + ".items", propertyDetails.items ); @@ -168,10 +163,11 @@ function resolveArray(schemaCache, nameMapping, propertyName, propertyDetails) { }; } -function resolveDictionary(schemaCache, nameMapping, propertyName, propertyDetails) { +function resolveDictionary(schemaCache, nameMapping, parentName, propertyName, propertyDetails) { const additional = resolveProperty( schemaCache, nameMapping, + parentName, propertyName + ".additionalProperties", propertyDetails.additionalProperties ); @@ -192,9 +188,15 @@ function resolveDictionary(schemaCache, nameMapping, propertyName, propertyDetai }; } -function resolveEnum(schemaCache, nameMapping, propertyName, propertyDetails) { +function resolveEnum(schemaCache, nameMapping, parentName, propertyName, propertyDetails) { + if (!propertyDetails.anyOf || propertyDetails.anyOf.length === 0 || !propertyDetails.anyOf[0].enum || propertyDetails.anyOf[0].enum.length === 0) { + return undefined; + } + const enumName = toPascalCase(propertyName); + const readerTypes = createEnumReaderType(enumName, propertyName, propertyDetails); + return { ...propertyDefaults(propertyName, propertyDetails), localTypes: [ @@ -211,10 +213,71 @@ function resolveEnum(schemaCache, nameMapping, propertyName, propertyDetails) { `) ], type: enumName, - readerLocalTypes: [ - "// TODO: enum handler" - ], - readerType: `${enumName}JsonHandler` + readerLocalTypes: readerTypes, + readerLocalTypesImpl: createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDetails), + readerType: readerTypes.length > 0 ? `${enumName}JsonHandler` : "IntegerJsonHandler" }; } + +function createEnum(enumDetails) { + if (!enumDetails.enum || enumDetails.enum.length === 0) { + return undefined; + } + + if (enumDetails.type === "integer") { + return `${enumDetails.description} = ${enumDetails.enum[0]}`; + } else { + return enumDetails.enum[0]; + } +} + +function createEnumReaderType(enumName, propertyName, propertyDetails) { + if (propertyDetails.anyOf[0].type === "integer") { + // No special reader needed for integer enums. + return []; + } + + return unindent(` + class ${enumName}JsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, ${enumName}* pEnum); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + + private: + ${enumName}* _pEnum = nullptr; + }; + `); +} + +function createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDetails) { + if (propertyDetails.anyOf[0].type === "integer") { + // No special reader needed for integer enums. + return []; + } + + return unindent(` + void ${parentName}JsonHandler::${enumName}JsonHandler::reset(JsonHandler* pParent, ${enumName}* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; + } + + JsonHandler* ${parentName}JsonHandler::${enumName}JsonHandler::String(const char* str, size_t length, bool copy) { + using namespace std::string_literals; + + assert(this->_pEnum); + + ${indent( + propertyDetails.anyOf + .map((e) => e.enum && e.enum[0] !== undefined ? `if ("${e.enum[0]}"s == str) *this->_pEnum = ${enumName}::${e.enum[0]};` : undefined) + .filter(s => s !== undefined) + .join("\nelse "), + 6 + )} + else return nullptr; + + return this->parent(); + } + `); +} + module.exports = resolveProperty; From a26418ddeaa3455d41b12038c3f554e3563a949d Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 6 Jan 2021 00:10:04 +1100 Subject: [PATCH 18/61] Fix some code generation problems. --- tools/generate-gltf-classes/generate.js | 9 +++++---- tools/generate-gltf-classes/makeIdentifier.js | 5 +++++ tools/generate-gltf-classes/resolveProperty.js | 14 +++++++------- 3 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 tools/generate-gltf-classes/makeIdentifier.js diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index 0a837efe7..03b2db03d 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -29,7 +29,7 @@ function generate(options, schema) { ); const headers = lodash.uniq( - lodash.flatten(properties.map((property) => property.headers)) + [`"CesiumGltf/${base}Object.h"`, ...lodash.flatten(properties.map((property) => property.headers))] ); headers.sort(); @@ -61,7 +61,7 @@ function generate(options, schema) { fs.writeFileSync(headerOutputPath, unindent(header), "utf-8"); const readerHeaders = lodash.uniq( - lodash.flatten(properties.map((property) => property.readerHeaders)) + [`"${base}ObjectJsonHandler.h"`, ...lodash.flatten(properties.map((property) => property.readerHeaders))] ); readerHeaders.sort(); @@ -107,13 +107,14 @@ function generate(options, schema) { const readerImpl = ` #include "${name}JsonHandler.h" + #include "CesiumGltf/${name}.h" #include #include using namespace CesiumGltf; void ${name}JsonHandler::reset(JsonHandler* pParent, ${name}* pObject) { - ${base}JsonHandler::reset(pParent); + ${base}ObjectJsonHandler::reset(pParent); this->_pObject = pObject; } @@ -129,7 +130,7 @@ function generate(options, schema) { 10 )} - return this->${base}ObjectKey(str, *this->_pTextureInfo); + return this->${base}ObjectKey(str, *this->_pObject); } ${indent(readerLocalTypesImpl.join("\n\n"), 8)} diff --git a/tools/generate-gltf-classes/makeIdentifier.js b/tools/generate-gltf-classes/makeIdentifier.js new file mode 100644 index 000000000..ab541f768 --- /dev/null +++ b/tools/generate-gltf-classes/makeIdentifier.js @@ -0,0 +1,5 @@ +function makeIdentifier(s) { + return s.replace(/\//g, "_"); +} + +module.exports = makeIdentifier; diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index 5d1ff4722..fb97d7720 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -1,7 +1,7 @@ const getNameFromSchema = require("./getNameFromSchema"); const unindent = require("./unindent"); const indent = require("./indent"); -const { result } = require("lodash"); +const makeIdentifier = require("./makeIdentifier"); function resolveProperty( schemaCache, @@ -48,7 +48,7 @@ function resolveProperty( } else if (propertyDetails.type == "string") { return { ...propertyDefaults(propertyName, propertyDetails), - type: "bool", + type: "std::string", headers: [""], readerHeaders: [`"StringJsonHandler.h"`], readerType: "StringJsonHandler", @@ -81,7 +81,7 @@ function resolveProperty( if (itemSchema.title === "glTF Id") { return { ...propertyDefaults(propertyName, propertyDetails), - type: "bool", + type: "int32_t", headers: [""], readerHeaders: [`"IntegerJsonHandler.h"`], readerType: "IntegerJsonHandler", @@ -207,7 +207,7 @@ function resolveEnum(schemaCache, nameMapping, parentName, propertyName, propert .map((e) => createEnum(e)) .filter((e) => e !== undefined) .join(",\n\n"), - 8 + 12 )} }; `) @@ -225,9 +225,9 @@ function createEnum(enumDetails) { } if (enumDetails.type === "integer") { - return `${enumDetails.description} = ${enumDetails.enum[0]}`; + return `${makeIdentifier(enumDetails.description)} = ${enumDetails.enum[0]}`; } else { - return enumDetails.enum[0]; + return makeIdentifier(enumDetails.enum[0]); } } @@ -268,7 +268,7 @@ function createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDe ${indent( propertyDetails.anyOf - .map((e) => e.enum && e.enum[0] !== undefined ? `if ("${e.enum[0]}"s == str) *this->_pEnum = ${enumName}::${e.enum[0]};` : undefined) + .map((e) => e.enum && e.enum[0] !== undefined ? `if ("${e.enum[0]}"s == str) *this->_pEnum = ${enumName}::${makeIdentifier(e.enum[0])};` : undefined) .filter(s => s !== undefined) .join("\nelse "), 6 From 87a030abe3c190da3c11a2faea44ca87fc9d5e7c Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 6 Jan 2021 11:57:32 +1100 Subject: [PATCH 19/61] Generated classes now compiling. --- CesiumGltf/include/CesiumGltf/Accessor.h | 103 +++++++++------ .../include/CesiumGltf/AccessorSparse.h | 33 +++++ .../CesiumGltf/AccessorSparseIndices.h | 38 ++++++ .../include/CesiumGltf/AccessorSparseValues.h | 24 ++++ CesiumGltf/include/CesiumGltf/AlphaMode.h | 9 -- CesiumGltf/include/CesiumGltf/Animation.h | 26 ++++ .../include/CesiumGltf/AnimationChannel.h | 27 ++++ .../CesiumGltf/AnimationChannelTarget.h | 33 +++++ .../include/CesiumGltf/AnimationSampler.h | 42 ++++++ CesiumGltf/include/CesiumGltf/Asset.h | 34 +++++ CesiumGltf/include/CesiumGltf/AttributeType.h | 44 ------- CesiumGltf/include/CesiumGltf/Buffer.h | 27 ++++ CesiumGltf/include/CesiumGltf/BufferView.h | 46 +++++++ CesiumGltf/include/CesiumGltf/Camera.h | 37 ++++++ .../include/CesiumGltf/CameraOrthographic.h | 33 +++++ .../include/CesiumGltf/CameraPerspective.h | 39 ++++++ CesiumGltf/include/CesiumGltf/ComponentType.h | 58 -------- CesiumGltf/include/CesiumGltf/Image.h | 37 ++++++ CesiumGltf/include/CesiumGltf/Material.h | 73 +++++++++-- .../CesiumGltf/MaterialNormalTextureInfo.h | 20 +++ .../CesiumGltf/MaterialOcclusionTextureInfo.h | 20 +++ .../CesiumGltf/MaterialPBRMetallicRoughness.h | 50 +++++++ CesiumGltf/include/CesiumGltf/Mesh.h | 14 +- CesiumGltf/include/CesiumGltf/MeshPrimitive.h | 60 +++++++++ CesiumGltf/include/CesiumGltf/Model.h | 120 +++++++++++++++-- CesiumGltf/include/CesiumGltf/Node.h | 64 +++++++++ .../include/CesiumGltf/NormalTextureInfo.h | 9 -- .../include/CesiumGltf/OcclusionTextureInfo.h | 9 -- .../include/CesiumGltf/PbrMetallicRoughness.h | 15 --- CesiumGltf/include/CesiumGltf/Primitive.h | 55 -------- CesiumGltf/include/CesiumGltf/PrimitiveMode.h | 61 --------- CesiumGltf/include/CesiumGltf/Sampler.h | 76 +++++++++++ CesiumGltf/include/CesiumGltf/Scene.h | 20 +++ CesiumGltf/include/CesiumGltf/Skin.h | 34 +++++ CesiumGltf/include/CesiumGltf/Texture.h | 24 ++++ CesiumGltf/include/CesiumGltf/TextureInfo.h | 20 ++- CesiumGltf/test/TestGltfModel.cpp | 4 +- CesiumGltfReader/src/AccessorJsonHandler.cpp | 53 ++++++-- CesiumGltfReader/src/AccessorJsonHandler.h | 47 ++++--- .../src/AccessorSparseIndicesJsonHandler.cpp | 25 ++++ .../src/AccessorSparseIndicesJsonHandler.h | 24 ++++ .../src/AccessorSparseJsonHandler.cpp | 25 ++++ .../src/AccessorSparseJsonHandler.h | 25 ++++ .../src/AccessorSparseValuesJsonHandler.cpp | 24 ++++ .../src/AccessorSparseValuesJsonHandler.h | 22 ++++ CesiumGltfReader/src/AlphaModeJsonHandler.cpp | 20 --- CesiumGltfReader/src/AlphaModeJsonHandler.h | 15 --- .../src/AnimationChannelJsonHandler.cpp | 24 ++++ .../src/AnimationChannelJsonHandler.h | 23 ++++ .../src/AnimationChannelTargetJsonHandler.cpp | 43 ++++++ .../src/AnimationChannelTargetJsonHandler.h | 31 +++++ CesiumGltfReader/src/AnimationJsonHandler.cpp | 24 ++++ CesiumGltfReader/src/AnimationJsonHandler.h | 24 ++++ .../src/AnimationSamplerJsonHandler.cpp | 43 ++++++ .../src/AnimationSamplerJsonHandler.h | 32 +++++ CesiumGltfReader/src/ArrayJsonHandler.h | 124 ++++++++++++++++++ CesiumGltfReader/src/AssetJsonHandler.cpp | 26 ++++ CesiumGltfReader/src/AssetJsonHandler.h | 24 ++++ CesiumGltfReader/src/AttributeJsonHandler.cpp | 17 --- CesiumGltfReader/src/AttributeJsonHandler.h | 17 --- .../src/AttributeTypeJsonHandler.cpp | 24 ---- .../src/AttributeTypeJsonHandler.h | 15 --- CesiumGltfReader/src/BufferJsonHandler.cpp | 24 ++++ CesiumGltfReader/src/BufferJsonHandler.h | 23 ++++ .../src/BufferViewJsonHandler.cpp | 27 ++++ CesiumGltfReader/src/BufferViewJsonHandler.h | 26 ++++ CesiumGltfReader/src/CameraJsonHandler.cpp | 42 ++++++ CesiumGltfReader/src/CameraJsonHandler.h | 33 +++++ .../src/CameraOrthographicJsonHandler.cpp | 26 ++++ .../src/CameraOrthographicJsonHandler.h | 24 ++++ .../src/CameraPerspectiveJsonHandler.cpp | 26 ++++ .../src/CameraPerspectiveJsonHandler.h | 24 ++++ CesiumGltfReader/src/DictionaryJsonHandler.h | 29 ++++ CesiumGltfReader/src/ImageJsonHandler.cpp | 42 ++++++ CesiumGltfReader/src/ImageJsonHandler.h | 33 +++++ CesiumGltfReader/src/MaterialJsonHandler.cpp | 46 +++++-- CesiumGltfReader/src/MaterialJsonHandler.h | 50 ++++--- .../MaterialNormalTextureInfoJsonHandler.cpp | 23 ++++ .../MaterialNormalTextureInfoJsonHandler.h | 21 +++ ...aterialOcclusionTextureInfoJsonHandler.cpp | 23 ++++ .../MaterialOcclusionTextureInfoJsonHandler.h | 21 +++ ...aterialPBRMetallicRoughnessJsonHandler.cpp | 27 ++++ .../MaterialPBRMetallicRoughnessJsonHandler.h | 27 ++++ CesiumGltfReader/src/MeshJsonHandler.cpp | 21 +-- CesiumGltfReader/src/MeshJsonHandler.h | 31 ++--- .../src/MeshPrimitiveJsonHandler.cpp | 27 ++++ .../src/MeshPrimitiveJsonHandler.h | 28 ++++ CesiumGltfReader/src/ModelJsonHandler.cpp | 35 +++-- CesiumGltfReader/src/ModelJsonHandler.h | 57 ++++++-- CesiumGltfReader/src/NodeJsonHandler.cpp | 31 +++++ CesiumGltfReader/src/NodeJsonHandler.h | 31 +++++ .../src/NormalTextureInfoJsonHandler.cpp | 21 --- .../src/NormalTextureInfoJsonHandler.h | 19 --- CesiumGltfReader/src/ObjectArrayJsonHandler.h | 47 ------- .../src/OcclusionTextureInfoJsonHandler.cpp | 21 --- .../src/OcclusionTextureInfoJsonHandler.h | 19 --- .../src/PbrMetallicRoughnessJsonHandler.cpp | 25 ---- .../src/PbrMetallicRoughnessJsonHandler.h | 25 ---- CesiumGltfReader/src/PrimitiveJsonHandler.cpp | 25 ---- CesiumGltfReader/src/PrimitiveJsonHandler.h | 26 ---- CesiumGltfReader/src/SamplerJsonHandler.cpp | 26 ++++ CesiumGltfReader/src/SamplerJsonHandler.h | 25 ++++ CesiumGltfReader/src/SceneJsonHandler.cpp | 23 ++++ CesiumGltfReader/src/SceneJsonHandler.h | 22 ++++ CesiumGltfReader/src/SkinJsonHandler.cpp | 25 ++++ CesiumGltfReader/src/SkinJsonHandler.h | 24 ++++ .../src/TextureInfoJsonHandler.cpp | 20 +-- CesiumGltfReader/src/TextureInfoJsonHandler.h | 22 ++-- CesiumGltfReader/src/TextureJsonHandler.cpp | 24 ++++ CesiumGltfReader/src/TextureJsonHandler.h | 22 ++++ tools/generate-gltf-classes/generate.js | 6 + .../generate-gltf-classes/resolveProperty.js | 31 +++-- 112 files changed, 2780 insertions(+), 805 deletions(-) create mode 100644 CesiumGltf/include/CesiumGltf/AccessorSparse.h create mode 100644 CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h create mode 100644 CesiumGltf/include/CesiumGltf/AccessorSparseValues.h delete mode 100644 CesiumGltf/include/CesiumGltf/AlphaMode.h create mode 100644 CesiumGltf/include/CesiumGltf/Animation.h create mode 100644 CesiumGltf/include/CesiumGltf/AnimationChannel.h create mode 100644 CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h create mode 100644 CesiumGltf/include/CesiumGltf/AnimationSampler.h create mode 100644 CesiumGltf/include/CesiumGltf/Asset.h delete mode 100644 CesiumGltf/include/CesiumGltf/AttributeType.h create mode 100644 CesiumGltf/include/CesiumGltf/Buffer.h create mode 100644 CesiumGltf/include/CesiumGltf/BufferView.h create mode 100644 CesiumGltf/include/CesiumGltf/Camera.h create mode 100644 CesiumGltf/include/CesiumGltf/CameraOrthographic.h create mode 100644 CesiumGltf/include/CesiumGltf/CameraPerspective.h delete mode 100644 CesiumGltf/include/CesiumGltf/ComponentType.h create mode 100644 CesiumGltf/include/CesiumGltf/Image.h create mode 100644 CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h create mode 100644 CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h create mode 100644 CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h create mode 100644 CesiumGltf/include/CesiumGltf/MeshPrimitive.h create mode 100644 CesiumGltf/include/CesiumGltf/Node.h delete mode 100644 CesiumGltf/include/CesiumGltf/NormalTextureInfo.h delete mode 100644 CesiumGltf/include/CesiumGltf/OcclusionTextureInfo.h delete mode 100644 CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h delete mode 100644 CesiumGltf/include/CesiumGltf/Primitive.h delete mode 100644 CesiumGltf/include/CesiumGltf/PrimitiveMode.h create mode 100644 CesiumGltf/include/CesiumGltf/Sampler.h create mode 100644 CesiumGltf/include/CesiumGltf/Scene.h create mode 100644 CesiumGltf/include/CesiumGltf/Skin.h create mode 100644 CesiumGltf/include/CesiumGltf/Texture.h create mode 100644 CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.h create mode 100644 CesiumGltfReader/src/AccessorSparseJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AccessorSparseJsonHandler.h create mode 100644 CesiumGltfReader/src/AccessorSparseValuesJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AccessorSparseValuesJsonHandler.h delete mode 100644 CesiumGltfReader/src/AlphaModeJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AlphaModeJsonHandler.h create mode 100644 CesiumGltfReader/src/AnimationChannelJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AnimationChannelJsonHandler.h create mode 100644 CesiumGltfReader/src/AnimationChannelTargetJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AnimationChannelTargetJsonHandler.h create mode 100644 CesiumGltfReader/src/AnimationJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AnimationJsonHandler.h create mode 100644 CesiumGltfReader/src/AnimationSamplerJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AnimationSamplerJsonHandler.h create mode 100644 CesiumGltfReader/src/ArrayJsonHandler.h create mode 100644 CesiumGltfReader/src/AssetJsonHandler.cpp create mode 100644 CesiumGltfReader/src/AssetJsonHandler.h delete mode 100644 CesiumGltfReader/src/AttributeJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AttributeJsonHandler.h delete mode 100644 CesiumGltfReader/src/AttributeTypeJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AttributeTypeJsonHandler.h create mode 100644 CesiumGltfReader/src/BufferJsonHandler.cpp create mode 100644 CesiumGltfReader/src/BufferJsonHandler.h create mode 100644 CesiumGltfReader/src/BufferViewJsonHandler.cpp create mode 100644 CesiumGltfReader/src/BufferViewJsonHandler.h create mode 100644 CesiumGltfReader/src/CameraJsonHandler.cpp create mode 100644 CesiumGltfReader/src/CameraJsonHandler.h create mode 100644 CesiumGltfReader/src/CameraOrthographicJsonHandler.cpp create mode 100644 CesiumGltfReader/src/CameraOrthographicJsonHandler.h create mode 100644 CesiumGltfReader/src/CameraPerspectiveJsonHandler.cpp create mode 100644 CesiumGltfReader/src/CameraPerspectiveJsonHandler.h create mode 100644 CesiumGltfReader/src/DictionaryJsonHandler.h create mode 100644 CesiumGltfReader/src/ImageJsonHandler.cpp create mode 100644 CesiumGltfReader/src/ImageJsonHandler.h create mode 100644 CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.cpp create mode 100644 CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.h create mode 100644 CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.cpp create mode 100644 CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.h create mode 100644 CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.cpp create mode 100644 CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.h create mode 100644 CesiumGltfReader/src/MeshPrimitiveJsonHandler.cpp create mode 100644 CesiumGltfReader/src/MeshPrimitiveJsonHandler.h create mode 100644 CesiumGltfReader/src/NodeJsonHandler.cpp create mode 100644 CesiumGltfReader/src/NodeJsonHandler.h delete mode 100644 CesiumGltfReader/src/NormalTextureInfoJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/NormalTextureInfoJsonHandler.h delete mode 100644 CesiumGltfReader/src/ObjectArrayJsonHandler.h delete mode 100644 CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.h delete mode 100644 CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.h delete mode 100644 CesiumGltfReader/src/PrimitiveJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/PrimitiveJsonHandler.h create mode 100644 CesiumGltfReader/src/SamplerJsonHandler.cpp create mode 100644 CesiumGltfReader/src/SamplerJsonHandler.h create mode 100644 CesiumGltfReader/src/SceneJsonHandler.cpp create mode 100644 CesiumGltfReader/src/SceneJsonHandler.h create mode 100644 CesiumGltfReader/src/SkinJsonHandler.cpp create mode 100644 CesiumGltfReader/src/SkinJsonHandler.h create mode 100644 CesiumGltfReader/src/TextureJsonHandler.cpp create mode 100644 CesiumGltfReader/src/TextureJsonHandler.h diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index 28e82ab60..5f786f91d 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -1,85 +1,108 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/AccessorSparse.h" #include "CesiumGltf/NamedObject.h" -#include "AttributeType.h" -#include "ComponentType.h" #include -#include #include namespace CesiumGltf { /** - * @brief A typed view into a {@link BufferView}. - * - * A {@link BufferView} contains raw binary data. An accessor provides a typed view into a - * `BufferView` or a subset of a `BufferView` similar to how WebGL's `vertexAttribPointer()` - * defines an attribute in a buffer. + * @brief A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides a typed view into a bufferView or a subset of a bufferView similar to how WebGL's `vertexAttribPointer()` defines an attribute in a buffer. */ - struct Accessor : public NamedObject { + struct Accessor final : public NamedObject { + enum class ComponentType { + BYTE = 5120, + + UNSIGNED_BYTE = 5121, + + SHORT = 5122, + + UNSIGNED_SHORT = 5123, + + UNSIGNED_INT = 5125, + + FLOAT = 5126 + }; + + enum class Type { + SCALAR, + + VEC2, + + VEC3, + + VEC4, + + MAT2, + + MAT3, + + MAT4 + }; + /** - * @brief The index of the `BufferView` in {@link Model::bufferViews}. - * - * When this value is less than 0, no `BufferView` is associated with this accessor. - * The accessor should be treated as being initialized with all zeros. The `sparse` - * property or extensions may override the zeros with actual values. + * @brief The index of the bufferView. + * + * The index of the bufferView. When not defined, accessor must be initialized with zeros; `sparse` property or extensions could override zeros with actual values. */ - int32_t bufferView = -1; + int32_t bufferView; /** - * @brief The offset relative to the start of the {@link Accessor::bufferView} in bytes. - * - * This must be a multiple of the size of the component datatype. + * @brief The offset relative to the start of the bufferView in bytes. + * + * The offset relative to the start of the bufferView in bytes. This must be a multiple of the size of the component datatype. */ - int64_t byteOffset = 0; + int64_t byteOffset; /** * @brief The datatype of components in the attribute. + * + * The datatype of components in the attribute. All valid values correspond to WebGL enums. The corresponding typed arrays are `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Uint32Array`, and `Float32Array`, respectively. 5125 (UNSIGNED_INT) is only allowed when the accessor contains indices, i.e., the accessor is only referenced by `primitive.indices`. */ - ComponentType componentType = ComponentType::FLOAT; + ComponentType componentType; /** * @brief Specifies whether integer data values should be normalized. - * - * Specifies whether integer data values should be normalized (`true`) to [0, 1] (for unsigned types) or - * [-1, 1] (for signed types), or converted directly (`false`) when they are accessed. This property is - * meaningful only for accessors that contain vertex attributes or animation output data. + * + * Specifies whether integer data values should be normalized (`true`) to [0, 1] (for unsigned types) or [-1, 1] (for signed types), or converted directly (`false`) when they are accessed. This property is defined only for accessors that contain vertex attributes or animation output data. */ - bool normalized = false; + bool normalized; /** * @brief The number of attributes referenced by this accessor. - * - * Not to be confused with the number of bytes or number of components. + * + * The number of attributes referenced by this accessor, not to be confused with the number of bytes or number of components. */ - int64_t count = 0; + int64_t count; /** * @brief Specifies if the attribute is a scalar, vector, or matrix. */ - AttributeType type = AttributeType::SCALAR; + Type type; /** * @brief Maximum value of each component in this attribute. + * + * Maximum value of each component in this attribute. Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. * - * Array elements must be treated as having the same data type as accessor's {@link Accessor::componentType}. Both min - * and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. - * - * The {@link Accessor::normalized} property has no effect on array values: they always correspond to the actual values stored in the buffer. - * When accessor is sparse, this property must contain max values of accessor data with sparse substitution applied. + * `normalized` property has no effect on array values: they always correspond to the actual values stored in the buffer. When accessor is sparse, this property must contain max values of accessor data with sparse substitution applied. */ std::vector max; /** * @brief Minimum value of each component in this attribute. + * + * Minimum value of each component in this attribute. Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. * - * Array elements must be treated as having the same data type as accessor's {@link Accessor::componentType}. Both min - * and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. - * - * The {@link Accessor::normalized} property has no effect on array values: they always correspond to the actual values stored in the buffer. - * When accessor is sparse, this property must contain min values of accessor data with sparse substitution applied. + * `normalized` property has no effect on array values: they always correspond to the actual values stored in the buffer. When accessor is sparse, this property must contain min values of accessor data with sparse substitution applied. */ std::vector min; - // TODO: sparse + /** + * @brief Sparse storage of attributes that deviate from their initialization value. + */ + AccessorSparse sparse; }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparse.h b/CesiumGltf/include/CesiumGltf/AccessorSparse.h new file mode 100644 index 000000000..480a6b158 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AccessorSparse.h @@ -0,0 +1,33 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/AccessorSparseIndices.h" +#include "CesiumGltf/AccessorSparseValues.h" +#include "CesiumGltf/ExtensibleObject.h" +#include + +namespace CesiumGltf { + /** + * @brief Sparse storage of attributes that deviate from their initialization value. + */ + struct AccessorSparse final : public ExtensibleObject { + + /** + * @brief Number of entries stored in the sparse array. + * + * The number of attributes encoded in this sparse accessor. + */ + int64_t count; + + /** + * @brief Index array of size `count` that points to those accessor attributes that deviate from their initialization value. Indices must strictly increase. + */ + AccessorSparseIndices indices; + + /** + * @brief Array of size `count` times number of components, storing the displaced accessor attributes pointed by `indices`. Substituted values must have the same `componentType` and number of components as the base accessor. + */ + AccessorSparseValues values; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h new file mode 100644 index 000000000..465b079d0 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h @@ -0,0 +1,38 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include + +namespace CesiumGltf { + /** + * @brief Indices of those attributes that deviate from their initialization value. + */ + struct AccessorSparseIndices final : public ExtensibleObject { + enum class ComponentType { + UNSIGNED_BYTE = 5121, + + UNSIGNED_SHORT = 5123, + + UNSIGNED_INT = 5125 + }; + + /** + * @brief The index of the bufferView with sparse indices. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target. + */ + int32_t bufferView; + + /** + * @brief The offset relative to the start of the bufferView in bytes. Must be aligned. + */ + int64_t byteOffset; + + /** + * @brief The indices data type. + * + * The indices data type. Valid values correspond to WebGL enums: `5121` (UNSIGNED_BYTE), `5123` (UNSIGNED_SHORT), `5125` (UNSIGNED_INT). + */ + ComponentType componentType; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h new file mode 100644 index 000000000..a5d4e7c93 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include + +namespace CesiumGltf { + /** + * @brief Array of size `accessor.sparse.count` times number of components storing the displaced accessor attributes pointed by `accessor.sparse.indices`. + */ + struct AccessorSparseValues final : public ExtensibleObject { + + /** + * @brief The index of the bufferView with sparse values. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target. + */ + int32_t bufferView; + + /** + * @brief The offset relative to the start of the bufferView in bytes. Must be aligned. + */ + int64_t byteOffset; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/AlphaMode.h b/CesiumGltf/include/CesiumGltf/AlphaMode.h deleted file mode 100644 index 0da91adba..000000000 --- a/CesiumGltf/include/CesiumGltf/AlphaMode.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -namespace CesiumGltf { - enum class AlphaMode { - OPAQUE, - MASK, - BLEND - }; -} \ No newline at end of file diff --git a/CesiumGltf/include/CesiumGltf/Animation.h b/CesiumGltf/include/CesiumGltf/Animation.h new file mode 100644 index 000000000..c3c559f7b --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Animation.h @@ -0,0 +1,26 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/AnimationChannel.h" +#include "CesiumGltf/AnimationSampler.h" +#include "CesiumGltf/NamedObject.h" +#include + +namespace CesiumGltf { + /** + * @brief A keyframe animation. + */ + struct Animation final : public NamedObject { + + /** + * @brief An array of channels, each of which targets an animation's sampler at a node's property. Different channels of the same animation can't have equal targets. + */ + std::vector channels; + + /** + * @brief An array of samplers that combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target). + */ + std::vector samplers; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannel.h b/CesiumGltf/include/CesiumGltf/AnimationChannel.h new file mode 100644 index 000000000..728f10e22 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AnimationChannel.h @@ -0,0 +1,27 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/AnimationChannelTarget.h" +#include "CesiumGltf/ExtensibleObject.h" +#include + +namespace CesiumGltf { + /** + * @brief Targets an animation's sampler at a node's property. + */ + struct AnimationChannel final : public ExtensibleObject { + + /** + * @brief The index of a sampler in this animation used to compute the value for the target. + * + * The index of a sampler in this animation used to compute the value for the target, e.g., a node's translation, rotation, or scale (TRS). + */ + int32_t sampler; + + /** + * @brief The index of the node and TRS property to target. + */ + AnimationChannelTarget target; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h new file mode 100644 index 000000000..7150052a5 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h @@ -0,0 +1,33 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include + +namespace CesiumGltf { + /** + * @brief The index of the node and TRS property that an animation channel targets. + */ + struct AnimationChannelTarget final : public ExtensibleObject { + enum class Path { + translation, + + rotation, + + scale, + + weights + }; + + /** + * @brief The index of the node to target. + */ + int32_t node; + + /** + * @brief The name of the node's TRS property to modify, or the "weights" of the Morph Targets it instantiates. For the "translation" property, the values that are provided by the sampler are the translation along the x, y, and z axes. For the "rotation" property, the values are a quaternion in the order (x, y, z, w), where w is the scalar. For the "scale" property, the values are the scaling factors along the x, y, and z axes. + */ + Path path; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/AnimationSampler.h b/CesiumGltf/include/CesiumGltf/AnimationSampler.h new file mode 100644 index 000000000..adb88bc57 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AnimationSampler.h @@ -0,0 +1,42 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include + +namespace CesiumGltf { + /** + * @brief Combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target). + */ + struct AnimationSampler final : public ExtensibleObject { + enum class Interpolation { + LINEAR, + + STEP, + + CUBICSPLINE + }; + + /** + * @brief The index of an accessor containing keyframe input values, e.g., time. + * + * The index of an accessor containing keyframe input values, e.g., time. That accessor must have componentType `FLOAT`. The values represent time in seconds with `time[0] >= 0.0`, and strictly increasing values, i.e., `time[n + 1] > time[n]`. + */ + int32_t input; + + /** + * @brief Interpolation algorithm. + * + * Interpolation algorithm. + */ + Interpolation interpolation; + + /** + * @brief The index of an accessor, containing keyframe output values. + * + * The index of an accessor containing keyframe output values. When targeting translation or scale paths, the `accessor.componentType` of the output values must be `FLOAT`. When targeting rotation or morph weights, the `accessor.componentType` of the output values must be `FLOAT` or normalized integer. For weights, each output element stores `SCALAR` values with a count equal to the number of morph targets. + */ + int32_t output; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Asset.h b/CesiumGltf/include/CesiumGltf/Asset.h new file mode 100644 index 000000000..ec164ee58 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Asset.h @@ -0,0 +1,34 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include + +namespace CesiumGltf { + /** + * @brief Metadata about the glTF asset. + */ + struct Asset final : public ExtensibleObject { + + /** + * @brief A copyright message suitable for display to credit the content creator. + */ + std::string copyright; + + /** + * @brief Tool that generated this glTF model. Useful for debugging. + */ + std::string generator; + + /** + * @brief The glTF version that this asset targets. + */ + std::string version; + + /** + * @brief The minimum glTF version that this asset targets. + */ + std::string minVersion; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/AttributeType.h b/CesiumGltf/include/CesiumGltf/AttributeType.h deleted file mode 100644 index aa795ea37..000000000 --- a/CesiumGltf/include/CesiumGltf/AttributeType.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -namespace CesiumGltf { - /** - * @brief Specifies if the attribute is a scalar, vector, or matrix. - */ - enum class AttributeType { - /** - * @brief The attribute is a scalar, i.e. a single numeric value. - */ - SCALAR, - - /** - * @brief The attribute is a 2D vector, i.e. two numeric values. - */ - VEC2, - - /** - * @brief The attribute is a 3D vector, i.e. three numeric values. - */ - VEC3, - - /** - * @brief The attribute is a 4D vector, i.e. four numeric values. - */ - VEC4, - - /** - * @brief The attribute is a 2x2 matrix in column-major order, i.e. four numeric values. - */ - MAT2, - - /** - * @brief The attribute is a 3x3 matrix in column-major order, i.e. nine numeric values. - */ - MAT3, - - /** - * @brief The attribute is a 4x4 matrix in column-major order, i.e. sixtreen numeric values. - * - */ - MAT4 - }; -} diff --git a/CesiumGltf/include/CesiumGltf/Buffer.h b/CesiumGltf/include/CesiumGltf/Buffer.h new file mode 100644 index 000000000..35328ec62 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Buffer.h @@ -0,0 +1,27 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" +#include +#include + +namespace CesiumGltf { + /** + * @brief A buffer points to binary geometry, animation, or skins. + */ + struct Buffer final : public NamedObject { + + /** + * @brief The uri of the buffer. + * + * The uri of the buffer. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. + */ + std::string uri; + + /** + * @brief The length of the buffer in bytes. + */ + int64_t byteLength; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/BufferView.h b/CesiumGltf/include/CesiumGltf/BufferView.h new file mode 100644 index 000000000..7dc2354be --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/BufferView.h @@ -0,0 +1,46 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" +#include + +namespace CesiumGltf { + /** + * @brief A view into a buffer generally representing a subset of the buffer. + */ + struct BufferView final : public NamedObject { + enum class Target { + ARRAY_BUFFER = 34962, + + ELEMENT_ARRAY_BUFFER = 34963 + }; + + /** + * @brief The index of the buffer. + */ + int32_t buffer; + + /** + * @brief The offset into the buffer in bytes. + */ + int64_t byteOffset; + + /** + * @brief The length of the bufferView in bytes. + */ + int64_t byteLength; + + /** + * @brief The stride, in bytes. + * + * The stride, in bytes, between vertex attributes. When this is not defined, data is tightly packed. When two or more accessors use the same bufferView, this field must be defined. + */ + int64_t byteStride; + + /** + * @brief The target that the GPU buffer should be bound to. + */ + Target target; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Camera.h b/CesiumGltf/include/CesiumGltf/Camera.h new file mode 100644 index 000000000..6a105e00b --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Camera.h @@ -0,0 +1,37 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/CameraOrthographic.h" +#include "CesiumGltf/CameraPerspective.h" +#include "CesiumGltf/NamedObject.h" + +namespace CesiumGltf { + /** + * @brief A camera's projection. A node can reference a camera to apply a transform to place the camera in the scene. + */ + struct Camera final : public NamedObject { + enum class Type { + perspective, + + orthographic + }; + + /** + * @brief An orthographic camera containing properties to create an orthographic projection matrix. + */ + CameraOrthographic orthographic; + + /** + * @brief A perspective camera containing properties to create a perspective projection matrix. + */ + CameraPerspective perspective; + + /** + * @brief Specifies if the camera uses a perspective or orthographic projection. + * + * Specifies if the camera uses a perspective or orthographic projection. Based on this, either the camera's `perspective` or `orthographic` property will be defined. + */ + Type type; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/CameraOrthographic.h b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h new file mode 100644 index 000000000..2dc403cfe --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h @@ -0,0 +1,33 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" + +namespace CesiumGltf { + /** + * @brief An orthographic camera containing properties to create an orthographic projection matrix. + */ + struct CameraOrthographic final : public ExtensibleObject { + + /** + * @brief The floating-point horizontal magnification of the view. Must not be zero. + */ + double xmag; + + /** + * @brief The floating-point vertical magnification of the view. Must not be zero. + */ + double ymag; + + /** + * @brief The floating-point distance to the far clipping plane. `zfar` must be greater than `znear`. + */ + double zfar; + + /** + * @brief The floating-point distance to the near clipping plane. + */ + double znear; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/CameraPerspective.h b/CesiumGltf/include/CesiumGltf/CameraPerspective.h new file mode 100644 index 000000000..a932592a6 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/CameraPerspective.h @@ -0,0 +1,39 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" + +namespace CesiumGltf { + /** + * @brief A perspective camera containing properties to create a perspective projection matrix. + */ + struct CameraPerspective final : public ExtensibleObject { + + /** + * @brief The floating-point aspect ratio of the field of view. + * + * The floating-point aspect ratio of the field of view. When this is undefined, the aspect ratio of the canvas is used. + */ + double aspectRatio; + + /** + * @brief The floating-point vertical field of view in radians. + */ + double yfov; + + /** + * @brief The floating-point distance to the far clipping plane. + * + * The floating-point distance to the far clipping plane. When defined, `zfar` must be greater than `znear`. If `zfar` is undefined, runtime must use infinite projection matrix. + */ + double zfar; + + /** + * @brief The floating-point distance to the near clipping plane. + * + * The floating-point distance to the near clipping plane. + */ + double znear; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/ComponentType.h b/CesiumGltf/include/CesiumGltf/ComponentType.h deleted file mode 100644 index eddc68af1..000000000 --- a/CesiumGltf/include/CesiumGltf/ComponentType.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -namespace CesiumGltf { - /** - * @brief The datatype of components in the attribute. - * - * The datatype of components in the attribute. All valid values correspond to WebGL enums. - * The corresponding typed arrays are `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Uint32Array`, - * and `Float32Array`, respectively. 5125 (UNSIGNED_INT) is only allowed when the accessor contains - * indices, i.e., the accessor is only referenced by `primitive.indices`. - */ - enum class ComponentType { - /** - * @brief A single-byte (8-bit), signed integer. - * - * Corresponds to C++11's `int8_t` or JavaScript's `Int8Array`. - */ - BYTE = 5120, - - /** - * @brief A single-byte (8-bit), unsigned integer. - * - * Corresponds to C++11's `uint8_t` or JavaScript's `Uint8Array`. - */ - UNSIGNED_BYTE = 5121, - - /** - * @brief A two-byte (16-bit), signed integer. - * - * Corresponds to C++11's `int16_t` or JavaScript's `Int16Array`. - */ - SHORT = 5122, - - /** - * @brief A two-byte (16-bit), unsigned integer. - * - * Corresponds to C++11's `uint16_t` or JavaScript's `Uint16Array`. - */ - UNSIGNED_SHORT = 5123, - - /** - * @brief A four-byte (32-bit), unsigned integer. - * - * Corresponds to C++11's `uint32_t` or JavaScript's `Uint32Array`. - * - * This component type is only allowed for accessors that only contain indices, - * i.e. the accessor is only referenced by `primitive.indices`. - */ - UNSIGNED_INT = 5125, - - /** - * @brief A four-byte (32-bit), floating-point number. - * - * Corresponds to C++'s `float` or JavaScript's `Float32Array`. - */ - FLOAT = 5126 - }; -} diff --git a/CesiumGltf/include/CesiumGltf/Image.h b/CesiumGltf/include/CesiumGltf/Image.h new file mode 100644 index 000000000..66a387d12 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Image.h @@ -0,0 +1,37 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" +#include +#include + +namespace CesiumGltf { + /** + * @brief Image data used to create a texture. Image can be referenced by URI or `bufferView` index. `mimeType` is required in the latter case. + */ + struct Image final : public NamedObject { + enum class MimeType { + image_jpeg, + + image_png + }; + + /** + * @brief The uri of the image. + * + * The uri of the image. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. The image format must be jpg or png. + */ + std::string uri; + + /** + * @brief The image's MIME type. Required if `bufferView` is defined. + */ + MimeType mimeType; + + /** + * @brief The index of the bufferView that contains the image. Use this instead of the image's uri property. + */ + int32_t bufferView; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Material.h b/CesiumGltf/include/CesiumGltf/Material.h index 519eb0bee..4ac2e91ed 100644 --- a/CesiumGltf/include/CesiumGltf/Material.h +++ b/CesiumGltf/include/CesiumGltf/Material.h @@ -1,22 +1,79 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once -#include "CesiumGltf/AlphaMode.h" +#include "CesiumGltf/MaterialNormalTextureInfo.h" +#include "CesiumGltf/MaterialOcclusionTextureInfo.h" +#include "CesiumGltf/MaterialPBRMetallicRoughness.h" #include "CesiumGltf/NamedObject.h" -#include "CesiumGltf/NormalTextureInfo.h" -#include "CesiumGltf/OcclusionTextureInfo.h" -#include "CesiumGltf/PbrMetallicRoughness.h" #include "CesiumGltf/TextureInfo.h" #include namespace CesiumGltf { - struct Material : public NamedObject { - PbrMetallicRoughness pbrMetallicRoughness; - NormalTextureInfo normalTexture; - OcclusionTextureInfo occlusionTexture; + /** + * @brief The material appearance of a primitive. + */ + struct Material final : public NamedObject { + enum class AlphaMode { + OPAQUE, + + MASK, + + BLEND + }; + + /** + * @brief A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology. When not specified, all the default values of `pbrMetallicRoughness` apply. + */ + MaterialPBRMetallicRoughness pbrMetallicRoughness; + + /** + * @brief The normal map texture. + * + * A tangent space normal map. The texture contains RGB components in linear space. Each texel represents the XYZ components of a normal vector in tangent space. Red [0 to 255] maps to X [-1 to 1]. Green [0 to 255] maps to Y [-1 to 1]. Blue [128 to 255] maps to Z [1/255 to 1]. The normal vectors use the convention +X is right and +Y is up. +Z points toward the viewer. In GLSL, this vector would be unpacked like so: `vec3 normalVector = tex2D(, texCoord) * 2 - 1`. Client implementations should normalize the normal vectors before using them in lighting equations. + */ + MaterialNormalTextureInfo normalTexture; + + /** + * @brief The occlusion map texture. + * + * The occlusion map texture. The occlusion values are sampled from the R channel. Higher values indicate areas that should receive full indirect lighting and lower values indicate no indirect lighting. These values are linear. If other channels are present (GBA), they are ignored for occlusion calculations. + */ + MaterialOcclusionTextureInfo occlusionTexture; + + /** + * @brief The emissive map texture. + * + * The emissive map controls the color and intensity of the light being emitted by the material. This texture contains RGB components encoded with the sRGB transfer function. If a fourth component (A) is present, it is ignored. + */ TextureInfo emissiveTexture; + + /** + * @brief The emissive color of the material. + * + * The RGB components of the emissive color of the material. These values are linear. If an emissiveTexture is specified, this value is multiplied with the texel values. + */ std::vector emissiveFactor; + + /** + * @brief The alpha rendering mode of the material. + * + * The material's alpha rendering mode enumeration specifying the interpretation of the alpha value of the main factor and texture. + */ AlphaMode alphaMode; + + /** + * @brief The alpha cutoff value of the material. + * + * Specifies the cutoff threshold when in `MASK` mode. If the alpha value is greater than or equal to this value then it is rendered as fully opaque, otherwise, it is rendered as fully transparent. A value greater than 1.0 will render the entire material as fully transparent. This value is ignored for other modes. + */ double alphaCutoff; + + /** + * @brief Specifies whether the material is double sided. + * + * Specifies whether the material is double sided. When this value is false, back-face culling is enabled. When this value is true, back-face culling is disabled and double sided lighting is enabled. The back-face must have its normals reversed before the lighting equation is evaluated. + */ bool doubleSided; }; } diff --git a/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h new file mode 100644 index 000000000..27e8409c4 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h @@ -0,0 +1,20 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" + +namespace CesiumGltf { + /** + * @brief undefined + */ + struct MaterialNormalTextureInfo final : public ExtensibleObject { + + /** + * @brief The scalar multiplier applied to each normal vector of the normal texture. + * + * The scalar multiplier applied to each normal vector of the texture. This value scales the normal vector using the formula: `scaledNormal = normalize(( * 2.0 - 1.0) * vec3(, , 1.0))`. This value is ignored if normalTexture is not specified. This value is linear. + */ + double scale; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h new file mode 100644 index 000000000..de4bfbd43 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h @@ -0,0 +1,20 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" + +namespace CesiumGltf { + /** + * @brief undefined + */ + struct MaterialOcclusionTextureInfo final : public ExtensibleObject { + + /** + * @brief A scalar multiplier controlling the amount of occlusion applied. + * + * A scalar multiplier controlling the amount of occlusion applied. A value of 0.0 means no occlusion. A value of 1.0 means full occlusion. This value affects the resulting color using the formula: `occludedColor = lerp(color, color * , )`. This value is ignored if the corresponding texture is not specified. This value is linear. + */ + double strength; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h new file mode 100644 index 000000000..5de4ae4dc --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h @@ -0,0 +1,50 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/TextureInfo.h" +#include + +namespace CesiumGltf { + /** + * @brief A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology. + */ + struct MaterialPBRMetallicRoughness final : public ExtensibleObject { + + /** + * @brief The material's base color factor. + * + * The RGBA components of the base color of the material. The fourth component (A) is the alpha coverage of the material. The `alphaMode` property specifies how alpha is interpreted. These values are linear. If a baseColorTexture is specified, this value is multiplied with the texel values. + */ + std::vector baseColorFactor; + + /** + * @brief The base color texture. + * + * The base color texture. The first three components (RGB) are encoded with the sRGB transfer function. They specify the base color of the material. If the fourth component (A) is present, it represents the linear alpha coverage of the material. Otherwise, an alpha of 1.0 is assumed. The `alphaMode` property specifies how alpha is interpreted. The stored texels must not be premultiplied. + */ + TextureInfo baseColorTexture; + + /** + * @brief The metalness of the material. + * + * The metalness of the material. A value of 1.0 means the material is a metal. A value of 0.0 means the material is a dielectric. Values in between are for blending between metals and dielectrics such as dirty metallic surfaces. This value is linear. If a metallicRoughnessTexture is specified, this value is multiplied with the metallic texel values. + */ + double metallicFactor; + + /** + * @brief The roughness of the material. + * + * The roughness of the material. A value of 1.0 means the material is completely rough. A value of 0.0 means the material is completely smooth. This value is linear. If a metallicRoughnessTexture is specified, this value is multiplied with the roughness texel values. + */ + double roughnessFactor; + + /** + * @brief The metallic-roughness texture. + * + * The metallic-roughness texture. The metalness values are sampled from the B channel. The roughness values are sampled from the G channel. These values are linear. If other channels are present (R or A), they are ignored for metallic-roughness calculations. + */ + TextureInfo metallicRoughnessTexture; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Mesh.h b/CesiumGltf/include/CesiumGltf/Mesh.h index 096eb4753..97927b7df 100644 --- a/CesiumGltf/include/CesiumGltf/Mesh.h +++ b/CesiumGltf/include/CesiumGltf/Mesh.h @@ -1,21 +1,21 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/MeshPrimitive.h" #include "CesiumGltf/NamedObject.h" -#include "CesiumGltf/Primitive.h" #include -#include namespace CesiumGltf { /** - * @brief A set of primitives to be rendered. - * - * A {@link Node} can contain one mesh. A node's transform places the mesh in the scene. + * @brief A set of primitives to be rendered. A node can contain one mesh. A node's transform places the mesh in the scene. */ - struct Mesh : public NamedObject { + struct Mesh final : public NamedObject { + /** * @brief An array of primitives, each defining geometry to be rendered with a material. */ - std::vector primitives; + std::vector primitives; /** * @brief Array of weights to be applied to the Morph Targets. diff --git a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h new file mode 100644 index 000000000..13a23a1bd --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h @@ -0,0 +1,60 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include +#include +#include + +namespace CesiumGltf { + /** + * @brief Geometry to be rendered with the given material. + */ + struct MeshPrimitive final : public ExtensibleObject { + enum class Mode { + POINTS = 0, + + LINES = 1, + + LINE_LOOP = 2, + + LINE_STRIP = 3, + + TRIANGLES = 4, + + TRIANGLE_STRIP = 5, + + TRIANGLE_FAN = 6 + }; + + /** + * @brief A dictionary object, where each key corresponds to mesh attribute semantic and each value is the index of the accessor containing attribute's data. + */ + std::unordered_map attributes; + + /** + * @brief The index of the accessor that contains the indices. + * + * The index of the accessor that contains mesh indices. When this is not defined, the primitives should be rendered without indices using `drawArrays()`. When defined, the accessor must contain indices: the `bufferView` referenced by the accessor should have a `target` equal to 34963 (ELEMENT_ARRAY_BUFFER); `componentType` must be 5121 (UNSIGNED_BYTE), 5123 (UNSIGNED_SHORT) or 5125 (UNSIGNED_INT), the latter may require enabling additional hardware support; `type` must be `"SCALAR"`. For triangle primitives, the front face has a counter-clockwise (CCW) winding order. Values of the index accessor must not include the maximum value for the given component type, which triggers primitive restart in several graphics APIs and would require client implementations to rebuild the index buffer. Primitive restart values are disallowed and all index values must refer to actual vertices. As a result, the index accessor's values must not exceed the following maxima: BYTE `< 255`, UNSIGNED_SHORT `< 65535`, UNSIGNED_INT `< 4294967295`. + */ + int32_t indices; + + /** + * @brief The index of the material to apply to this primitive when rendering. + */ + int32_t material; + + /** + * @brief The type of primitives to render. + * + * The type of primitives to render. All valid values correspond to WebGL enums. + */ + Mode mode; + + /** + * @brief An array of Morph Targets, each Morph Target is a dictionary mapping attributes (only `POSITION`, `NORMAL`, and `TANGENT` supported) to their deviations in the Morph Target. + */ + std::vector> targets; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index d63204f81..16f40a8c7 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -1,35 +1,133 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once #include "CesiumGltf/Accessor.h" +#include "CesiumGltf/Animation.h" +#include "CesiumGltf/Asset.h" +#include "CesiumGltf/Buffer.h" +#include "CesiumGltf/BufferView.h" +#include "CesiumGltf/Camera.h" #include "CesiumGltf/ExtensibleObject.h" -#include "CesiumGltf/Mesh.h" +#include "CesiumGltf/Image.h" #include "CesiumGltf/Material.h" +#include "CesiumGltf/Mesh.h" +#include "CesiumGltf/Node.h" +#include "CesiumGltf/Sampler.h" +#include "CesiumGltf/Scene.h" +#include "CesiumGltf/Skin.h" +#include "CesiumGltf/Texture.h" +#include +#include #include namespace CesiumGltf { /** - * @brief A glTF model. + * @brief The root object for a glTF asset. */ - struct Model : public ExtensibleObject { + struct Model final : public ExtensibleObject { + + /** + * @brief Names of glTF extensions used somewhere in this asset. + */ + std::vector extensionsUsed; + + /** + * @brief Names of glTF extensions required to properly load this asset. + */ + std::vector extensionsRequired; + /** * @brief An array of accessors. - * - * An accessor is a typed view into a {@link BufferView}. + * + * An array of accessors. An accessor is a typed view into a bufferView. */ std::vector accessors; /** - * @brief An array of meshes. - * - * A mesh is a set of {@link Primitive} instances to be rendered. + * @brief An array of keyframe animations. */ - std::vector meshes; + std::vector animations; + + /** + * @brief Metadata about the glTF asset. + */ + Asset asset; + + /** + * @brief An array of buffers. + * + * An array of buffers. A buffer points to binary geometry, animation, or skins. + */ + std::vector buffers; + + /** + * @brief An array of bufferViews. + * + * An array of bufferViews. A bufferView is a view into a buffer generally representing a subset of the buffer. + */ + std::vector bufferViews; + + /** + * @brief An array of cameras. + * + * An array of cameras. A camera defines a projection matrix. + */ + std::vector cameras; + + /** + * @brief An array of images. + * + * An array of images. An image defines data used to create a texture. + */ + std::vector images; /** * @brief An array of materials. - * - * A material defines the appearance of a primitive. + * + * An array of materials. A material defines the appearance of a primitive. */ std::vector materials; + + /** + * @brief An array of meshes. + * + * An array of meshes. A mesh is a set of primitives to be rendered. + */ + std::vector meshes; + + /** + * @brief An array of nodes. + */ + std::vector nodes; + + /** + * @brief An array of samplers. + * + * An array of samplers. A sampler contains properties for texture filtering and wrapping modes. + */ + std::vector samplers; + + /** + * @brief The index of the default scene. + */ + int32_t scene; + + /** + * @brief An array of scenes. + */ + std::vector scenes; + + /** + * @brief An array of skins. + * + * An array of skins. A skin is defined by joints and matrices. + */ + std::vector skins; + + /** + * @brief An array of textures. + */ + std::vector textures; }; } diff --git a/CesiumGltf/include/CesiumGltf/Node.h b/CesiumGltf/include/CesiumGltf/Node.h new file mode 100644 index 000000000..6e354a1bb --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Node.h @@ -0,0 +1,64 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" +#include +#include + +namespace CesiumGltf { + /** + * @brief A node in the node hierarchy. When the node contains `skin`, all `mesh.primitives` must contain `JOINTS_0` and `WEIGHTS_0` attributes. A node can have either a `matrix` or any combination of `translation`/`rotation`/`scale` (TRS) properties. TRS properties are converted to matrices and postmultiplied in the `T * R * S` order to compose the transformation matrix; first the scale is applied to the vertices, then the rotation, and then the translation. If none are provided, the transform is the identity. When a node is targeted for animation (referenced by an animation.channel.target), only TRS properties may be present; `matrix` will not be present. + */ + struct Node final : public NamedObject { + + /** + * @brief The index of the camera referenced by this node. + */ + int32_t camera; + + /** + * @brief The indices of this node's children. + */ + std::vector children; + + /** + * @brief The index of the skin referenced by this node. + * + * The index of the skin referenced by this node. When a skin is referenced by a node within a scene, all joints used by the skin must belong to the same scene. + */ + int32_t skin; + + /** + * @brief A floating-point 4x4 transformation matrix stored in column-major order. + * + * A floating-point 4x4 transformation matrix stored in column-major order. + */ + std::vector matrix; + + /** + * @brief The index of the mesh in this node. + */ + int32_t mesh; + + /** + * @brief The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar. + */ + std::vector rotation; + + /** + * @brief The node's non-uniform scale, given as the scaling factors along the x, y, and z axes. + */ + std::vector scale; + + /** + * @brief The node's translation along the x, y, and z axes. + */ + std::vector translation; + + /** + * @brief The weights of the instantiated Morph Target. Number of elements must match number of Morph Targets of used mesh. + */ + std::vector weights; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/NormalTextureInfo.h b/CesiumGltf/include/CesiumGltf/NormalTextureInfo.h deleted file mode 100644 index 21d1e87c7..000000000 --- a/CesiumGltf/include/CesiumGltf/NormalTextureInfo.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "CesiumGltf/TextureInfo.h" - -namespace CesiumGltf { - struct NormalTextureInfo : public TextureInfo { - double scale; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/OcclusionTextureInfo.h b/CesiumGltf/include/CesiumGltf/OcclusionTextureInfo.h deleted file mode 100644 index 72d5d3c13..000000000 --- a/CesiumGltf/include/CesiumGltf/OcclusionTextureInfo.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "CesiumGltf/TextureInfo.h" - -namespace CesiumGltf { - struct OcclusionTextureInfo : public TextureInfo { - double strength; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h deleted file mode 100644 index 216edaa31..000000000 --- a/CesiumGltf/include/CesiumGltf/PbrMetallicRoughness.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "CesiumGltf/ExtensibleObject.h" -#include "CesiumGltf/TextureInfo.h" -#include - -namespace CesiumGltf { - struct PbrMetallicRoughness : public ExtensibleObject { - std::vector baseColorFactor; - TextureInfo baseColorTexture; - double metallicFactor; - double roughnessFactor; - TextureInfo metallicRoughnessTexture; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/Primitive.h b/CesiumGltf/include/CesiumGltf/Primitive.h deleted file mode 100644 index 9492650cd..000000000 --- a/CesiumGltf/include/CesiumGltf/Primitive.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include "CesiumGltf/ExtensibleObject.h" -#include "CesiumGltf/PrimitiveMode.h" -#include -#include -#include -#include - -namespace CesiumGltf { - /** - * @brief Geometry to be rendered with the given material. - */ - struct Primitive : public ExtensibleObject { - /** - * @brief A dictionary object, where each key corresponds to mesh attribute semantic and each value is the index of the accessor containing attribute's data. - */ - std::unordered_map attributes; - - /** - * @brief The index of the accessor that contains the indices. - * - * The index of the accessor in {@link Model::accessors} that contains mesh indices. When this is not defined (-1), the primitives should be - * rendered without indices using `drawArrays()`. When defined, the accessor must contain indices: the {@link BufferView} referenced by the - * accessor should have a {@link BufferView::target} equal to {@link BufferViewTarget::ELEMENT_ARRAY_BUFFER}; componentType must be - * {@link ComponentType::UNSIGNED_BYTE}, {@link ComponentType::UNSIGNED_SHORT} or {@link ComponentType::UNSIGNED_INT}, the latter may - * require enabling additional hardware support; {@link Accessor::type} must be {@link AccessorType::SCALAR}. For triangle primitives, the front face has a - * counter-clockwise (CCW) winding order. - * - * Values of the index accessor must not include the maximum value for the given component type, which triggers primitive restart in several graphics APIs - * and would require client implementations to rebuild the index buffer. Primitive restart values are disallowed and all index values must refer to actual - * vertices. As a result, the index accessor's values must not exceed the following maxima: {@link ComponentType::BYTE} `< 255`, - * {@link ComponentType::UNSIGNED_SHORT} `< 65535`, {@link ComponentType::UNSIGNED_INT} `< 4294967295`. - */ - int32_t indices = -1; - - /** - * @brief The index of the material to apply to this primitive when rendering. - * - * When this value is not defined (-1), the default material is used. - */ - int32_t material = -1; - - /** - * @brief The type of primitives to render. - */ - PrimitiveMode mode = PrimitiveMode::TRIANGLES; - - /** - * @brief An array of Morph Targets, each Morph Target is a dictionary mapping attributes - * (only `POSITION`, `NORMAL`, and `TANGENT` supported) to their deviations in the Morph Target. - */ - std::vector> targets; - }; -} diff --git a/CesiumGltf/include/CesiumGltf/PrimitiveMode.h b/CesiumGltf/include/CesiumGltf/PrimitiveMode.h deleted file mode 100644 index 0566a2f37..000000000 --- a/CesiumGltf/include/CesiumGltf/PrimitiveMode.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -namespace CesiumGltf { - /** - * @brief The type of primitives to render. - * - * All valid values correspond to WebGL enums. - */ - enum class PrimitiveMode { - /** - * @brief Points. - * - * A single dot at each vertex. - */ - POINTS = 0, - - /** - * @brief Lines. - * - * Straight lines between pairs of vertices. - */ - LINES = 1, - - /** - * @brief A line loop. - * - * Straight lines to each vertex in succession, and the last vertex connected back to the rfirst. - */ - LINE_LOOP = 2, - - /** - * @brief A line strip. - * - * Straight lines to each vertex in succession. - */ - LINE_STRIP = 3, - - /** - * @brief Triangles. - * - * A triangle for each group of three vertices. - */ - TRIANGLES = 4, - - /** - * @brief A triangle strip. - * - * The first three vertices define the first triangle, and each single vertex thereafter defines an - * additional triangle by connecting with the previous two vertices. - */ - TRIANGLE_STRIP = 5, - - /** - * @brief A triangle fan. - * - * The first three vertices define the first triangle, and each successive vertex defines another triangle - * fanning around the very first vertex. - */ - TRIANGLE_FAN = 6 - }; -} diff --git a/CesiumGltf/include/CesiumGltf/Sampler.h b/CesiumGltf/include/CesiumGltf/Sampler.h new file mode 100644 index 000000000..9701909a1 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Sampler.h @@ -0,0 +1,76 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" + +namespace CesiumGltf { + /** + * @brief Texture sampler properties for filtering and wrapping modes. + */ + struct Sampler final : public NamedObject { + enum class MagFilter { + NEAREST = 9728, + + LINEAR = 9729 + }; + + enum class MinFilter { + NEAREST = 9728, + + LINEAR = 9729, + + NEAREST_MIPMAP_NEAREST = 9984, + + LINEAR_MIPMAP_NEAREST = 9985, + + NEAREST_MIPMAP_LINEAR = 9986, + + LINEAR_MIPMAP_LINEAR = 9987 + }; + + enum class WrapS { + CLAMP_TO_EDGE = 33071, + + MIRRORED_REPEAT = 33648, + + REPEAT = 10497 + }; + + enum class WrapT { + CLAMP_TO_EDGE = 33071, + + MIRRORED_REPEAT = 33648, + + REPEAT = 10497 + }; + + /** + * @brief Magnification filter. + * + * Magnification filter. Valid values correspond to WebGL enums: `9728` (NEAREST) and `9729` (LINEAR). + */ + MagFilter magFilter; + + /** + * @brief Minification filter. + * + * Minification filter. All valid values correspond to WebGL enums. + */ + MinFilter minFilter; + + /** + * @brief s wrapping mode. + * + * S (U) wrapping mode. All valid values correspond to WebGL enums. + */ + WrapS wrapS; + + /** + * @brief t wrapping mode. + * + * T (V) wrapping mode. All valid values correspond to WebGL enums. + */ + WrapT wrapT; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Scene.h b/CesiumGltf/include/CesiumGltf/Scene.h new file mode 100644 index 000000000..16f7e0a83 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Scene.h @@ -0,0 +1,20 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" +#include +#include + +namespace CesiumGltf { + /** + * @brief The root nodes of a scene. + */ + struct Scene final : public NamedObject { + + /** + * @brief The indices of each root node. + */ + std::vector nodes; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Skin.h b/CesiumGltf/include/CesiumGltf/Skin.h new file mode 100644 index 000000000..c9cb1777d --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Skin.h @@ -0,0 +1,34 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" +#include +#include + +namespace CesiumGltf { + /** + * @brief Joints and matrices defining a skin. + */ + struct Skin final : public NamedObject { + + /** + * @brief The index of the accessor containing the floating-point 4x4 inverse-bind matrices. The default is that each matrix is a 4x4 identity matrix, which implies that inverse-bind matrices were pre-applied. + */ + int32_t inverseBindMatrices; + + /** + * @brief The index of the node used as a skeleton root. + * + * The index of the node used as a skeleton root. The node must be the closest common root of the joints hierarchy or a direct or indirect parent node of the closest common root. + */ + int32_t skeleton; + + /** + * @brief Indices of skeleton nodes, used as joints in this skin. + * + * Indices of skeleton nodes, used as joints in this skin. The array length must be the same as the `count` property of the `inverseBindMatrices` accessor (when defined). + */ + std::vector joints; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Texture.h b/CesiumGltf/include/CesiumGltf/Texture.h new file mode 100644 index 000000000..5c369e26e --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Texture.h @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" +#include + +namespace CesiumGltf { + /** + * @brief A texture and its sampler. + */ + struct Texture final : public NamedObject { + + /** + * @brief The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used. + */ + int32_t sampler; + + /** + * @brief The index of the image used by this texture. When undefined, it is expected that an extension or other mechanism will supply an alternate texture source, otherwise behavior is undefined. + */ + int32_t source; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/TextureInfo.h b/CesiumGltf/include/CesiumGltf/TextureInfo.h index f6d45bfa8..27e7bae2b 100644 --- a/CesiumGltf/include/CesiumGltf/TextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/TextureInfo.h @@ -1,10 +1,26 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include namespace CesiumGltf { - struct TextureInfo : public ExtensibleObject { + /** + * @brief Reference to a texture. + */ + struct TextureInfo final : public ExtensibleObject { + + /** + * @brief The index of the texture. + */ int32_t index; - int32_t texCoord; + + /** + * @brief The set index of texture's TEXCOORD attribute used for texture coordinate mapping. + * + * This integer value is used to construct a string in the format `TEXCOORD_` which is a reference to a key in mesh.primitives.attributes (e.g. A value of `0` corresponds to `TEXCOORD_0`). Mesh must have corresponding texture coordinate attributes for the material to be applicable to it. + */ + int64_t texCoord; }; } diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index 735162720..3bb4f121c 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -37,8 +37,8 @@ TEST_CASE("GltfModel") { Model& model = result.model; REQUIRE(model.accessors.size() == 1); CHECK(model.accessors[0].count == 4); - CHECK(model.accessors[0].componentType == ComponentType::UNSIGNED_BYTE); - CHECK(model.accessors[0].type == AttributeType::VEC2); + CHECK(model.accessors[0].componentType == Accessor::ComponentType::UNSIGNED_BYTE); + CHECK(model.accessors[0].type == Accessor::Type::VEC2); REQUIRE(model.accessors[0].min.size() == 2); CHECK(model.accessors[0].min[0] == 0.0); CHECK(model.accessors[0].min[1] == -1.2); diff --git a/CesiumGltfReader/src/AccessorJsonHandler.cpp b/CesiumGltfReader/src/AccessorJsonHandler.cpp index 5dbf38730..78f03c795 100644 --- a/CesiumGltfReader/src/AccessorJsonHandler.cpp +++ b/CesiumGltfReader/src/AccessorJsonHandler.cpp @@ -1,3 +1,5 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #include "AccessorJsonHandler.h" #include "CesiumGltf/Accessor.h" #include @@ -5,24 +7,47 @@ using namespace CesiumGltf; -void AccessorJsonHandler::reset(JsonHandler* pParent, Accessor* pAccessor) { - ObjectJsonHandler::reset(pParent); - this->_pAccessor = pAccessor; +void AccessorJsonHandler::reset(JsonHandler* pParent, Accessor* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; } JsonHandler* AccessorJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; + using namespace std::string_literals; - assert(this->_pAccessor); + assert(this->_pObject); - if ("bufferView"s == str) return property(this->_bufferView, this->_pAccessor->bufferView); - if ("byteOffset"s == str) return property(this->_byteOffset, this->_pAccessor->byteOffset); - if ("componentType"s == str) return property(this->_componentType, this->_pAccessor->componentType); - if ("normalized"s == str) return property(this->_normalized, this->_pAccessor->normalized); - if ("count"s == str) return property(this->_count, this->_pAccessor->count); - if ("type"s == str) return property(this->_type, this->_pAccessor->type); - if ("max"s == str) return property(this->_max, this->_pAccessor->max); - if ("min"s == str) return property(this->_min, this->_pAccessor->min); + if ("bufferView"s == str) return property(this->_bufferView, this->_pObject->bufferView); + if ("byteOffset"s == str) return property(this->_byteOffset, this->_pObject->byteOffset); + if ("componentType"s == str) return property(this->_componentType, this->_pObject->componentType); + if ("normalized"s == str) return property(this->_normalized, this->_pObject->normalized); + if ("count"s == str) return property(this->_count, this->_pObject->count); + if ("type"s == str) return property(this->_type, this->_pObject->type); + if ("max"s == str) return property(this->_max, this->_pObject->max); + if ("min"s == str) return property(this->_min, this->_pObject->min); + if ("sparse"s == str) return property(this->_sparse, this->_pObject->sparse); - return this->NamedObjectKey(str, *this->_pAccessor); + return this->NamedObjectKey(str, *this->_pObject); +} + +void AccessorJsonHandler::TypeJsonHandler::reset(JsonHandler* pParent, Accessor::Type* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +JsonHandler* AccessorJsonHandler::TypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("SCALAR"s == str) *this->_pEnum = Accessor::Type::SCALAR; + else if ("VEC2"s == str) *this->_pEnum = Accessor::Type::VEC2; + else if ("VEC3"s == str) *this->_pEnum = Accessor::Type::VEC3; + else if ("VEC4"s == str) *this->_pEnum = Accessor::Type::VEC4; + else if ("MAT2"s == str) *this->_pEnum = Accessor::Type::MAT2; + else if ("MAT3"s == str) *this->_pEnum = Accessor::Type::MAT3; + else if ("MAT4"s == str) *this->_pEnum = Accessor::Type::MAT4; + else return nullptr; + + return this->parent(); } diff --git a/CesiumGltfReader/src/AccessorJsonHandler.h b/CesiumGltfReader/src/AccessorJsonHandler.h index b3938cf13..f105a5821 100644 --- a/CesiumGltfReader/src/AccessorJsonHandler.h +++ b/CesiumGltfReader/src/AccessorJsonHandler.h @@ -1,31 +1,42 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once -#include "AttributeTypeJsonHandler.h" +#include "AccessorSparseJsonHandler.h" +#include "ArrayJsonHandler.h" #include "BoolJsonHandler.h" -#include "CesiumGltf/ComponentType.h" -#include "DoubleArrayJsonHandler.h" +#include "CesiumGltf/Accessor.h" +#include "DoubleJsonHandler.h" #include "IntegerJsonHandler.h" #include "NamedObjectJsonHandler.h" -#include namespace CesiumGltf { - struct Accessor; + struct Accessor; - class AccessorJsonHandler : public NamedObjectJsonHandler { - public: - void reset(JsonHandler* pParent, Accessor* pAccessor); + class AccessorJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Accessor* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + private: + class TypeJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, Accessor::Type* pEnum); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; private: - Accessor* _pAccessor = nullptr; - IntegerJsonHandler _bufferView; - IntegerJsonHandler _byteOffset; - IntegerJsonHandler _componentType; - BoolJsonHandler _normalized; - IntegerJsonHandler _count; - AttributeTypeJsonHandler _type; - DoubleArrayJsonHandler _max; - DoubleArrayJsonHandler _min; + Accessor::Type* _pEnum = nullptr; }; + + Accessor* _pObject; + IntegerJsonHandler _bufferView; + IntegerJsonHandler _byteOffset; + IntegerJsonHandler _componentType; + BoolJsonHandler _normalized; + IntegerJsonHandler _count; + TypeJsonHandler _type; + ArrayJsonHandler _max; + ArrayJsonHandler _min; + AccessorSparseJsonHandler _sparse; + }; } diff --git a/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.cpp b/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.cpp new file mode 100644 index 000000000..40affc5ed --- /dev/null +++ b/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.cpp @@ -0,0 +1,25 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AccessorSparseIndicesJsonHandler.h" +#include "CesiumGltf/AccessorSparseIndices.h" +#include +#include + +using namespace CesiumGltf; + +void AccessorSparseIndicesJsonHandler::reset(JsonHandler* pParent, AccessorSparseIndices* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* AccessorSparseIndicesJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("bufferView"s == str) return property(this->_bufferView, this->_pObject->bufferView); + if ("byteOffset"s == str) return property(this->_byteOffset, this->_pObject->byteOffset); + if ("componentType"s == str) return property(this->_componentType, this->_pObject->componentType); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.h b/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.h new file mode 100644 index 000000000..bfd9768dd --- /dev/null +++ b/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.h @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/AccessorSparseIndices.h" +#include "ExtensibleObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct AccessorSparseIndices; + + class AccessorSparseIndicesJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, AccessorSparseIndices* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + AccessorSparseIndices* _pObject; + IntegerJsonHandler _bufferView; + IntegerJsonHandler _byteOffset; + IntegerJsonHandler _componentType; + }; +} diff --git a/CesiumGltfReader/src/AccessorSparseJsonHandler.cpp b/CesiumGltfReader/src/AccessorSparseJsonHandler.cpp new file mode 100644 index 000000000..b83b3e3b9 --- /dev/null +++ b/CesiumGltfReader/src/AccessorSparseJsonHandler.cpp @@ -0,0 +1,25 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AccessorSparseJsonHandler.h" +#include "CesiumGltf/AccessorSparse.h" +#include +#include + +using namespace CesiumGltf; + +void AccessorSparseJsonHandler::reset(JsonHandler* pParent, AccessorSparse* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* AccessorSparseJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("count"s == str) return property(this->_count, this->_pObject->count); + if ("indices"s == str) return property(this->_indices, this->_pObject->indices); + if ("values"s == str) return property(this->_values, this->_pObject->values); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AccessorSparseJsonHandler.h b/CesiumGltfReader/src/AccessorSparseJsonHandler.h new file mode 100644 index 000000000..c10685817 --- /dev/null +++ b/CesiumGltfReader/src/AccessorSparseJsonHandler.h @@ -0,0 +1,25 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "AccessorSparseIndicesJsonHandler.h" +#include "AccessorSparseValuesJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct AccessorSparse; + + class AccessorSparseJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, AccessorSparse* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + AccessorSparse* _pObject; + IntegerJsonHandler _count; + AccessorSparseIndicesJsonHandler _indices; + AccessorSparseValuesJsonHandler _values; + }; +} diff --git a/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.cpp b/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.cpp new file mode 100644 index 000000000..88d9888e5 --- /dev/null +++ b/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.cpp @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AccessorSparseValuesJsonHandler.h" +#include "CesiumGltf/AccessorSparseValues.h" +#include +#include + +using namespace CesiumGltf; + +void AccessorSparseValuesJsonHandler::reset(JsonHandler* pParent, AccessorSparseValues* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* AccessorSparseValuesJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("bufferView"s == str) return property(this->_bufferView, this->_pObject->bufferView); + if ("byteOffset"s == str) return property(this->_byteOffset, this->_pObject->byteOffset); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.h b/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.h new file mode 100644 index 000000000..562c86389 --- /dev/null +++ b/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.h @@ -0,0 +1,22 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "ExtensibleObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct AccessorSparseValues; + + class AccessorSparseValuesJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, AccessorSparseValues* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + AccessorSparseValues* _pObject; + IntegerJsonHandler _bufferView; + IntegerJsonHandler _byteOffset; + }; +} diff --git a/CesiumGltfReader/src/AlphaModeJsonHandler.cpp b/CesiumGltfReader/src/AlphaModeJsonHandler.cpp deleted file mode 100644 index 149d3e3a3..000000000 --- a/CesiumGltfReader/src/AlphaModeJsonHandler.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "AlphaModeJsonHandler.h" -#include - -using namespace CesiumGltf; - -void AlphaModeJsonHandler::reset(JsonHandler* pParent, AlphaMode* pEnum) { - JsonHandler::reset(pParent); - this->_pEnum = pEnum; -} - -JsonHandler* AlphaModeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - if ("OPAQUE"s == str) *this->_pEnum = AlphaMode::OPAQUE; - else if ("MASK"s == str) *this->_pEnum = AlphaMode::MASK; - else if ("BLEND"s == str) *this->_pEnum = AlphaMode::BLEND; - else return nullptr; - - return this->parent(); -} diff --git a/CesiumGltfReader/src/AlphaModeJsonHandler.h b/CesiumGltfReader/src/AlphaModeJsonHandler.h deleted file mode 100644 index 5ecd44ebd..000000000 --- a/CesiumGltfReader/src/AlphaModeJsonHandler.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "JsonHandler.h" -#include "CesiumGltf/AlphaMode.h" - -namespace CesiumGltf { - class AlphaModeJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent, AlphaMode* pEnum); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; - - private: - AlphaMode* _pEnum = nullptr; - }; -} diff --git a/CesiumGltfReader/src/AnimationChannelJsonHandler.cpp b/CesiumGltfReader/src/AnimationChannelJsonHandler.cpp new file mode 100644 index 000000000..3ed7d9b75 --- /dev/null +++ b/CesiumGltfReader/src/AnimationChannelJsonHandler.cpp @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AnimationChannelJsonHandler.h" +#include "CesiumGltf/AnimationChannel.h" +#include +#include + +using namespace CesiumGltf; + +void AnimationChannelJsonHandler::reset(JsonHandler* pParent, AnimationChannel* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* AnimationChannelJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("sampler"s == str) return property(this->_sampler, this->_pObject->sampler); + if ("target"s == str) return property(this->_target, this->_pObject->target); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AnimationChannelJsonHandler.h b/CesiumGltfReader/src/AnimationChannelJsonHandler.h new file mode 100644 index 000000000..eaa02b00b --- /dev/null +++ b/CesiumGltfReader/src/AnimationChannelJsonHandler.h @@ -0,0 +1,23 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "AnimationChannelTargetJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct AnimationChannel; + + class AnimationChannelJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, AnimationChannel* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + AnimationChannel* _pObject; + IntegerJsonHandler _sampler; + AnimationChannelTargetJsonHandler _target; + }; +} diff --git a/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.cpp b/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.cpp new file mode 100644 index 000000000..be88f3451 --- /dev/null +++ b/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.cpp @@ -0,0 +1,43 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AnimationChannelTargetJsonHandler.h" +#include "CesiumGltf/AnimationChannelTarget.h" +#include +#include + +using namespace CesiumGltf; + +void AnimationChannelTargetJsonHandler::reset(JsonHandler* pParent, AnimationChannelTarget* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* AnimationChannelTargetJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("node"s == str) return property(this->_node, this->_pObject->node); + if ("path"s == str) return property(this->_path, this->_pObject->path); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} + +void AnimationChannelTargetJsonHandler::PathJsonHandler::reset(JsonHandler* pParent, AnimationChannelTarget::Path* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +JsonHandler* AnimationChannelTargetJsonHandler::PathJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("translation"s == str) *this->_pEnum = AnimationChannelTarget::Path::translation; + else if ("rotation"s == str) *this->_pEnum = AnimationChannelTarget::Path::rotation; + else if ("scale"s == str) *this->_pEnum = AnimationChannelTarget::Path::scale; + else if ("weights"s == str) *this->_pEnum = AnimationChannelTarget::Path::weights; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.h b/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.h new file mode 100644 index 000000000..5495926bf --- /dev/null +++ b/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.h @@ -0,0 +1,31 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/AnimationChannelTarget.h" +#include "ExtensibleObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct AnimationChannelTarget; + + class AnimationChannelTargetJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, AnimationChannelTarget* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + class PathJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, AnimationChannelTarget::Path* pEnum); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + + private: + AnimationChannelTarget::Path* _pEnum = nullptr; + }; + + AnimationChannelTarget* _pObject; + IntegerJsonHandler _node; + PathJsonHandler _path; + }; +} diff --git a/CesiumGltfReader/src/AnimationJsonHandler.cpp b/CesiumGltfReader/src/AnimationJsonHandler.cpp new file mode 100644 index 000000000..4ae7836c1 --- /dev/null +++ b/CesiumGltfReader/src/AnimationJsonHandler.cpp @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AnimationJsonHandler.h" +#include "CesiumGltf/Animation.h" +#include +#include + +using namespace CesiumGltf; + +void AnimationJsonHandler::reset(JsonHandler* pParent, Animation* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* AnimationJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("channels"s == str) return property(this->_channels, this->_pObject->channels); + if ("samplers"s == str) return property(this->_samplers, this->_pObject->samplers); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AnimationJsonHandler.h b/CesiumGltfReader/src/AnimationJsonHandler.h new file mode 100644 index 000000000..c536562df --- /dev/null +++ b/CesiumGltfReader/src/AnimationJsonHandler.h @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "AnimationChannelJsonHandler.h" +#include "AnimationSamplerJsonHandler.h" +#include "ArrayJsonHandler.h" +#include "NamedObjectJsonHandler.h" + +namespace CesiumGltf { + struct Animation; + + class AnimationJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Animation* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + Animation* _pObject; + ArrayJsonHandler _channels; + ArrayJsonHandler _samplers; + }; +} diff --git a/CesiumGltfReader/src/AnimationSamplerJsonHandler.cpp b/CesiumGltfReader/src/AnimationSamplerJsonHandler.cpp new file mode 100644 index 000000000..ba195cfd5 --- /dev/null +++ b/CesiumGltfReader/src/AnimationSamplerJsonHandler.cpp @@ -0,0 +1,43 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AnimationSamplerJsonHandler.h" +#include "CesiumGltf/AnimationSampler.h" +#include +#include + +using namespace CesiumGltf; + +void AnimationSamplerJsonHandler::reset(JsonHandler* pParent, AnimationSampler* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* AnimationSamplerJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("input"s == str) return property(this->_input, this->_pObject->input); + if ("interpolation"s == str) return property(this->_interpolation, this->_pObject->interpolation); + if ("output"s == str) return property(this->_output, this->_pObject->output); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} + +void AnimationSamplerJsonHandler::InterpolationJsonHandler::reset(JsonHandler* pParent, AnimationSampler::Interpolation* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +JsonHandler* AnimationSamplerJsonHandler::InterpolationJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("LINEAR"s == str) *this->_pEnum = AnimationSampler::Interpolation::LINEAR; + else if ("STEP"s == str) *this->_pEnum = AnimationSampler::Interpolation::STEP; + else if ("CUBICSPLINE"s == str) *this->_pEnum = AnimationSampler::Interpolation::CUBICSPLINE; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/AnimationSamplerJsonHandler.h b/CesiumGltfReader/src/AnimationSamplerJsonHandler.h new file mode 100644 index 000000000..efccba2ca --- /dev/null +++ b/CesiumGltfReader/src/AnimationSamplerJsonHandler.h @@ -0,0 +1,32 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/AnimationSampler.h" +#include "ExtensibleObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct AnimationSampler; + + class AnimationSamplerJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, AnimationSampler* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + class InterpolationJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, AnimationSampler::Interpolation* pEnum); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + + private: + AnimationSampler::Interpolation* _pEnum = nullptr; + }; + + AnimationSampler* _pObject; + IntegerJsonHandler _input; + InterpolationJsonHandler _interpolation; + IntegerJsonHandler _output; + }; +} diff --git a/CesiumGltfReader/src/ArrayJsonHandler.h b/CesiumGltfReader/src/ArrayJsonHandler.h new file mode 100644 index 000000000..a7e600408 --- /dev/null +++ b/CesiumGltfReader/src/ArrayJsonHandler.h @@ -0,0 +1,124 @@ +#pragma once + +#include "JsonHandler.h" +#include "DoubleJsonHandler.h" +#include +#include + +namespace CesiumGltf { + template + class ArrayJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, std::vector* pArray) { + JsonHandler::reset(pParent); + this->_pArray = pArray; + this->_arrayIsOpen = false; + } + + virtual JsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return nullptr; + } + + this->_arrayIsOpen = true; + return this; + } + + virtual JsonHandler* EndArray(size_t) override { + return this->parent(); + } + + virtual JsonHandler* StartObject() override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + T& o = this->_pArray->emplace_back(); + this->_objectHandler.reset(this, &o); + return this->_objectHandler.StartObject(); + } + + private: + std::vector* _pArray = nullptr; + bool _arrayIsOpen = false; + THandler _objectHandler; + }; + + template <> + class ArrayJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, std::vector* pArray) { + JsonHandler::reset(pParent); + this->_pArray = pArray; + this->_arrayIsOpen = false; + } + + virtual JsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return nullptr; + } + + this->_arrayIsOpen = true; + return this; + } + + virtual JsonHandler* EndArray(size_t) override { + return this->parent(); + } + + virtual JsonHandler* Int(int i) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(static_cast(i)); + return this; + } + + virtual JsonHandler* Uint(unsigned i) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(static_cast(i)); + return this; + } + + virtual JsonHandler* Int64(int64_t i) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(static_cast(i)); + return this; + } + + virtual JsonHandler* Uint64(uint64_t i) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(static_cast(i)); + return this; + } + + virtual JsonHandler* Double(double d) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(d); + return this; + } + + private: + std::vector* _pArray = nullptr; + bool _arrayIsOpen = false; + }; +} diff --git a/CesiumGltfReader/src/AssetJsonHandler.cpp b/CesiumGltfReader/src/AssetJsonHandler.cpp new file mode 100644 index 000000000..21e53b177 --- /dev/null +++ b/CesiumGltfReader/src/AssetJsonHandler.cpp @@ -0,0 +1,26 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AssetJsonHandler.h" +#include "CesiumGltf/Asset.h" +#include +#include + +using namespace CesiumGltf; + +void AssetJsonHandler::reset(JsonHandler* pParent, Asset* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* AssetJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("copyright"s == str) return property(this->_copyright, this->_pObject->copyright); + if ("generator"s == str) return property(this->_generator, this->_pObject->generator); + if ("version"s == str) return property(this->_version, this->_pObject->version); + if ("minVersion"s == str) return property(this->_minVersion, this->_pObject->minVersion); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AssetJsonHandler.h b/CesiumGltfReader/src/AssetJsonHandler.h new file mode 100644 index 000000000..0c271578d --- /dev/null +++ b/CesiumGltfReader/src/AssetJsonHandler.h @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "ExtensibleObjectJsonHandler.h" +#include "StringJsonHandler.h" + +namespace CesiumGltf { + struct Asset; + + class AssetJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Asset* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + Asset* _pObject; + StringJsonHandler _copyright; + StringJsonHandler _generator; + StringJsonHandler _version; + StringJsonHandler _minVersion; + }; +} diff --git a/CesiumGltfReader/src/AttributeJsonHandler.cpp b/CesiumGltfReader/src/AttributeJsonHandler.cpp deleted file mode 100644 index d18719f7b..000000000 --- a/CesiumGltfReader/src/AttributeJsonHandler.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AttributeJsonHandler.h" - -using namespace CesiumGltf; - -void AttributeJsonHandler::reset(JsonHandler* pParent, std::unordered_map* pAttributes) { - ObjectJsonHandler::reset(pParent); - this->_pAttributes = pAttributes; -} - -JsonHandler* AttributeJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - assert(this->_pAttributes); - - return this->property( - this->_index, - this->_pAttributes->emplace(str, -1).first->second - ); -} diff --git a/CesiumGltfReader/src/AttributeJsonHandler.h b/CesiumGltfReader/src/AttributeJsonHandler.h deleted file mode 100644 index 57f577efe..000000000 --- a/CesiumGltfReader/src/AttributeJsonHandler.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "ObjectJsonHandler.h" -#include "IntegerJsonHandler.h" -#include - -namespace CesiumGltf { - class AttributeJsonHandler : public ObjectJsonHandler { - public: - void reset(JsonHandler* pParent, std::unordered_map* pAttributes); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; - - private: - std::unordered_map* _pAttributes; - IntegerJsonHandler _index; - }; -} \ No newline at end of file diff --git a/CesiumGltfReader/src/AttributeTypeJsonHandler.cpp b/CesiumGltfReader/src/AttributeTypeJsonHandler.cpp deleted file mode 100644 index d03e6aa44..000000000 --- a/CesiumGltfReader/src/AttributeTypeJsonHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "AttributeTypeJsonHandler.h" -#include - -using namespace CesiumGltf; - -void AttributeTypeJsonHandler::reset(JsonHandler* pParent, AttributeType* pEnum) { - JsonHandler::reset(pParent); - this->_pEnum = pEnum; -} - -JsonHandler* AttributeTypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - if ("SCALAR"s == str) *this->_pEnum = AttributeType::SCALAR; - else if ("VEC2"s == str) *this->_pEnum = AttributeType::VEC2; - else if ("VEC3"s == str) *this->_pEnum = AttributeType::VEC3; - else if ("VEC4"s == str) *this->_pEnum = AttributeType::VEC4; - else if ("MAT2"s == str) *this->_pEnum = AttributeType::MAT2; - else if ("MAT3"s == str) *this->_pEnum = AttributeType::MAT3; - else if ("MAT4"s == str) *this->_pEnum = AttributeType::MAT4; - else return nullptr; - - return this->parent(); -} diff --git a/CesiumGltfReader/src/AttributeTypeJsonHandler.h b/CesiumGltfReader/src/AttributeTypeJsonHandler.h deleted file mode 100644 index 34fceaf7c..000000000 --- a/CesiumGltfReader/src/AttributeTypeJsonHandler.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "JsonHandler.h" -#include "CesiumGltf/AttributeType.h" - -namespace CesiumGltf { - class AttributeTypeJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent, AttributeType* pEnum); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; - - private: - AttributeType* _pEnum = nullptr; - }; -} diff --git a/CesiumGltfReader/src/BufferJsonHandler.cpp b/CesiumGltfReader/src/BufferJsonHandler.cpp new file mode 100644 index 000000000..aa262899d --- /dev/null +++ b/CesiumGltfReader/src/BufferJsonHandler.cpp @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "BufferJsonHandler.h" +#include "CesiumGltf/Buffer.h" +#include +#include + +using namespace CesiumGltf; + +void BufferJsonHandler::reset(JsonHandler* pParent, Buffer* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* BufferJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("uri"s == str) return property(this->_uri, this->_pObject->uri); + if ("byteLength"s == str) return property(this->_byteLength, this->_pObject->byteLength); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/BufferJsonHandler.h b/CesiumGltfReader/src/BufferJsonHandler.h new file mode 100644 index 000000000..8b15fd1a2 --- /dev/null +++ b/CesiumGltfReader/src/BufferJsonHandler.h @@ -0,0 +1,23 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "IntegerJsonHandler.h" +#include "NamedObjectJsonHandler.h" +#include "StringJsonHandler.h" + +namespace CesiumGltf { + struct Buffer; + + class BufferJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Buffer* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + Buffer* _pObject; + StringJsonHandler _uri; + IntegerJsonHandler _byteLength; + }; +} diff --git a/CesiumGltfReader/src/BufferViewJsonHandler.cpp b/CesiumGltfReader/src/BufferViewJsonHandler.cpp new file mode 100644 index 000000000..bbefdc5d4 --- /dev/null +++ b/CesiumGltfReader/src/BufferViewJsonHandler.cpp @@ -0,0 +1,27 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "BufferViewJsonHandler.h" +#include "CesiumGltf/BufferView.h" +#include +#include + +using namespace CesiumGltf; + +void BufferViewJsonHandler::reset(JsonHandler* pParent, BufferView* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* BufferViewJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("buffer"s == str) return property(this->_buffer, this->_pObject->buffer); + if ("byteOffset"s == str) return property(this->_byteOffset, this->_pObject->byteOffset); + if ("byteLength"s == str) return property(this->_byteLength, this->_pObject->byteLength); + if ("byteStride"s == str) return property(this->_byteStride, this->_pObject->byteStride); + if ("target"s == str) return property(this->_target, this->_pObject->target); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/BufferViewJsonHandler.h b/CesiumGltfReader/src/BufferViewJsonHandler.h new file mode 100644 index 000000000..56e7acb9c --- /dev/null +++ b/CesiumGltfReader/src/BufferViewJsonHandler.h @@ -0,0 +1,26 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/BufferView.h" +#include "IntegerJsonHandler.h" +#include "NamedObjectJsonHandler.h" + +namespace CesiumGltf { + struct BufferView; + + class BufferViewJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, BufferView* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + BufferView* _pObject; + IntegerJsonHandler _buffer; + IntegerJsonHandler _byteOffset; + IntegerJsonHandler _byteLength; + IntegerJsonHandler _byteStride; + IntegerJsonHandler _target; + }; +} diff --git a/CesiumGltfReader/src/CameraJsonHandler.cpp b/CesiumGltfReader/src/CameraJsonHandler.cpp new file mode 100644 index 000000000..045de9c68 --- /dev/null +++ b/CesiumGltfReader/src/CameraJsonHandler.cpp @@ -0,0 +1,42 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "CameraJsonHandler.h" +#include "CesiumGltf/Camera.h" +#include +#include + +using namespace CesiumGltf; + +void CameraJsonHandler::reset(JsonHandler* pParent, Camera* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* CameraJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("orthographic"s == str) return property(this->_orthographic, this->_pObject->orthographic); + if ("perspective"s == str) return property(this->_perspective, this->_pObject->perspective); + if ("type"s == str) return property(this->_type, this->_pObject->type); + + return this->NamedObjectKey(str, *this->_pObject); +} + +void CameraJsonHandler::TypeJsonHandler::reset(JsonHandler* pParent, Camera::Type* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +JsonHandler* CameraJsonHandler::TypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("perspective"s == str) *this->_pEnum = Camera::Type::perspective; + else if ("orthographic"s == str) *this->_pEnum = Camera::Type::orthographic; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/CameraJsonHandler.h b/CesiumGltfReader/src/CameraJsonHandler.h new file mode 100644 index 000000000..ad06d569f --- /dev/null +++ b/CesiumGltfReader/src/CameraJsonHandler.h @@ -0,0 +1,33 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CameraOrthographicJsonHandler.h" +#include "CameraPerspectiveJsonHandler.h" +#include "CesiumGltf/Camera.h" +#include "NamedObjectJsonHandler.h" + +namespace CesiumGltf { + struct Camera; + + class CameraJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Camera* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + class TypeJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, Camera::Type* pEnum); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + + private: + Camera::Type* _pEnum = nullptr; + }; + + Camera* _pObject; + CameraOrthographicJsonHandler _orthographic; + CameraPerspectiveJsonHandler _perspective; + TypeJsonHandler _type; + }; +} diff --git a/CesiumGltfReader/src/CameraOrthographicJsonHandler.cpp b/CesiumGltfReader/src/CameraOrthographicJsonHandler.cpp new file mode 100644 index 000000000..0876f476c --- /dev/null +++ b/CesiumGltfReader/src/CameraOrthographicJsonHandler.cpp @@ -0,0 +1,26 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "CameraOrthographicJsonHandler.h" +#include "CesiumGltf/CameraOrthographic.h" +#include +#include + +using namespace CesiumGltf; + +void CameraOrthographicJsonHandler::reset(JsonHandler* pParent, CameraOrthographic* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* CameraOrthographicJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("xmag"s == str) return property(this->_xmag, this->_pObject->xmag); + if ("ymag"s == str) return property(this->_ymag, this->_pObject->ymag); + if ("zfar"s == str) return property(this->_zfar, this->_pObject->zfar); + if ("znear"s == str) return property(this->_znear, this->_pObject->znear); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/CameraOrthographicJsonHandler.h b/CesiumGltfReader/src/CameraOrthographicJsonHandler.h new file mode 100644 index 000000000..8ac746d76 --- /dev/null +++ b/CesiumGltfReader/src/CameraOrthographicJsonHandler.h @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "DoubleJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" + +namespace CesiumGltf { + struct CameraOrthographic; + + class CameraOrthographicJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, CameraOrthographic* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + CameraOrthographic* _pObject; + DoubleJsonHandler _xmag; + DoubleJsonHandler _ymag; + DoubleJsonHandler _zfar; + DoubleJsonHandler _znear; + }; +} diff --git a/CesiumGltfReader/src/CameraPerspectiveJsonHandler.cpp b/CesiumGltfReader/src/CameraPerspectiveJsonHandler.cpp new file mode 100644 index 000000000..8aba48743 --- /dev/null +++ b/CesiumGltfReader/src/CameraPerspectiveJsonHandler.cpp @@ -0,0 +1,26 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "CameraPerspectiveJsonHandler.h" +#include "CesiumGltf/CameraPerspective.h" +#include +#include + +using namespace CesiumGltf; + +void CameraPerspectiveJsonHandler::reset(JsonHandler* pParent, CameraPerspective* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* CameraPerspectiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("aspectRatio"s == str) return property(this->_aspectRatio, this->_pObject->aspectRatio); + if ("yfov"s == str) return property(this->_yfov, this->_pObject->yfov); + if ("zfar"s == str) return property(this->_zfar, this->_pObject->zfar); + if ("znear"s == str) return property(this->_znear, this->_pObject->znear); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/CameraPerspectiveJsonHandler.h b/CesiumGltfReader/src/CameraPerspectiveJsonHandler.h new file mode 100644 index 000000000..6927ee46e --- /dev/null +++ b/CesiumGltfReader/src/CameraPerspectiveJsonHandler.h @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "DoubleJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" + +namespace CesiumGltf { + struct CameraPerspective; + + class CameraPerspectiveJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, CameraPerspective* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + CameraPerspective* _pObject; + DoubleJsonHandler _aspectRatio; + DoubleJsonHandler _yfov; + DoubleJsonHandler _zfar; + DoubleJsonHandler _znear; + }; +} diff --git a/CesiumGltfReader/src/DictionaryJsonHandler.h b/CesiumGltfReader/src/DictionaryJsonHandler.h new file mode 100644 index 000000000..5cca78ddc --- /dev/null +++ b/CesiumGltfReader/src/DictionaryJsonHandler.h @@ -0,0 +1,29 @@ +#pragma once + +#include "ObjectJsonHandler.h" +#include "IntegerJsonHandler.h" +#include + +namespace CesiumGltf { + template + class DictionaryJsonHandler : public ObjectJsonHandler { + public: + void reset(JsonHandler* pParent, std::unordered_map* pDictionary) { + ObjectJsonHandler::reset(pParent); + this->_pDictionary = pDictionary; + } + + virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { + assert(this->_pDictionary); + + return this->property( + this->_item, + this->_pDictionary->emplace(str, -1).first->second + ); + } + + private: + std::unordered_map* _pDictionary; + THandler _item; + }; +} diff --git a/CesiumGltfReader/src/ImageJsonHandler.cpp b/CesiumGltfReader/src/ImageJsonHandler.cpp new file mode 100644 index 000000000..785e6a6ca --- /dev/null +++ b/CesiumGltfReader/src/ImageJsonHandler.cpp @@ -0,0 +1,42 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "ImageJsonHandler.h" +#include "CesiumGltf/Image.h" +#include +#include + +using namespace CesiumGltf; + +void ImageJsonHandler::reset(JsonHandler* pParent, Image* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* ImageJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("uri"s == str) return property(this->_uri, this->_pObject->uri); + if ("mimeType"s == str) return property(this->_mimeType, this->_pObject->mimeType); + if ("bufferView"s == str) return property(this->_bufferView, this->_pObject->bufferView); + + return this->NamedObjectKey(str, *this->_pObject); +} + +void ImageJsonHandler::MimeTypeJsonHandler::reset(JsonHandler* pParent, Image::MimeType* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +JsonHandler* ImageJsonHandler::MimeTypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("image/jpeg"s == str) *this->_pEnum = Image::MimeType::image_jpeg; + else if ("image/png"s == str) *this->_pEnum = Image::MimeType::image_png; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/ImageJsonHandler.h b/CesiumGltfReader/src/ImageJsonHandler.h new file mode 100644 index 000000000..89b9b6b41 --- /dev/null +++ b/CesiumGltfReader/src/ImageJsonHandler.h @@ -0,0 +1,33 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/Image.h" +#include "IntegerJsonHandler.h" +#include "NamedObjectJsonHandler.h" +#include "StringJsonHandler.h" + +namespace CesiumGltf { + struct Image; + + class ImageJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Image* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + class MimeTypeJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, Image::MimeType* pEnum); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + + private: + Image::MimeType* _pEnum = nullptr; + }; + + Image* _pObject; + StringJsonHandler _uri; + MimeTypeJsonHandler _mimeType; + IntegerJsonHandler _bufferView; + }; +} diff --git a/CesiumGltfReader/src/MaterialJsonHandler.cpp b/CesiumGltfReader/src/MaterialJsonHandler.cpp index 2134586af..e0f87c0c9 100644 --- a/CesiumGltfReader/src/MaterialJsonHandler.cpp +++ b/CesiumGltfReader/src/MaterialJsonHandler.cpp @@ -1,3 +1,5 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #include "MaterialJsonHandler.h" #include "CesiumGltf/Material.h" #include @@ -5,22 +7,42 @@ using namespace CesiumGltf; -void MaterialJsonHandler::reset(JsonHandler* pParent, Material* pMaterial) { - ObjectJsonHandler::reset(pParent); - this->_pMaterial = pMaterial; +void MaterialJsonHandler::reset(JsonHandler* pParent, Material* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; } JsonHandler* MaterialJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; + using namespace std::string_literals; - assert(this->_pMaterial); + assert(this->_pObject); - if ("pbrMetallicRoughness"s == str) return property(this->_pbrMetallicRoughness, this->_pMaterial->pbrMetallicRoughness); - if ("emissiveTexture"s == str) return property(this->_emissiveTexture, this->_pMaterial->emissiveTexture); - if ("emissiveFactor"s == str) return property(this->_emissiveFactor, this->_pMaterial->emissiveFactor); - if ("alphaMode"s == str) return property(this->_alphaMode, this->_pMaterial->alphaMode); - if ("alphaCutoff"s == str) return property(this->_alphaCutoff, this->_pMaterial->alphaCutoff); - if ("doubleSided"s == str) return property(this->_doubleSided, this->_pMaterial->doubleSided); + if ("pbrMetallicRoughness"s == str) return property(this->_pbrMetallicRoughness, this->_pObject->pbrMetallicRoughness); + if ("normalTexture"s == str) return property(this->_normalTexture, this->_pObject->normalTexture); + if ("occlusionTexture"s == str) return property(this->_occlusionTexture, this->_pObject->occlusionTexture); + if ("emissiveTexture"s == str) return property(this->_emissiveTexture, this->_pObject->emissiveTexture); + if ("emissiveFactor"s == str) return property(this->_emissiveFactor, this->_pObject->emissiveFactor); + if ("alphaMode"s == str) return property(this->_alphaMode, this->_pObject->alphaMode); + if ("alphaCutoff"s == str) return property(this->_alphaCutoff, this->_pObject->alphaCutoff); + if ("doubleSided"s == str) return property(this->_doubleSided, this->_pObject->doubleSided); - return this->NamedObjectKey(str, *this->_pMaterial); + return this->NamedObjectKey(str, *this->_pObject); +} + +void MaterialJsonHandler::AlphaModeJsonHandler::reset(JsonHandler* pParent, Material::AlphaMode* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +JsonHandler* MaterialJsonHandler::AlphaModeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("OPAQUE"s == str) *this->_pEnum = Material::AlphaMode::OPAQUE; + else if ("MASK"s == str) *this->_pEnum = Material::AlphaMode::MASK; + else if ("BLEND"s == str) *this->_pEnum = Material::AlphaMode::BLEND; + else return nullptr; + + return this->parent(); } diff --git a/CesiumGltfReader/src/MaterialJsonHandler.h b/CesiumGltfReader/src/MaterialJsonHandler.h index ef2510c44..5881795cf 100644 --- a/CesiumGltfReader/src/MaterialJsonHandler.h +++ b/CesiumGltfReader/src/MaterialJsonHandler.h @@ -1,35 +1,43 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once -#include "AlphaModeJsonHandler.h" +#include "ArrayJsonHandler.h" #include "BoolJsonHandler.h" -#include "DoubleArrayJsonHandler.h" +#include "CesiumGltf/Material.h" #include "DoubleJsonHandler.h" +#include "MaterialNormalTextureInfoJsonHandler.h" +#include "MaterialOcclusionTextureInfoJsonHandler.h" +#include "MaterialPBRMetallicRoughnessJsonHandler.h" #include "NamedObjectJsonHandler.h" -#include "NormalTextureInfoJsonHandler.h" -#include "OcclusionTextureInfoJsonHandler.h" -#include "PbrMetallicRoughnessJsonHandler.h" #include "TextureInfoJsonHandler.h" -#include namespace CesiumGltf { - struct Material; + struct Material; - class MaterialJsonHandler : public NamedObjectJsonHandler { - public: - void reset(JsonHandler* pParent, Material* pMaterial); + class MaterialJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Material* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + private: + class AlphaModeJsonHandler : public JsonHandler { + public: + void reset(JsonHandler* pParent, Material::AlphaMode* pEnum); + virtual JsonHandler* String(const char* str, size_t length, bool copy) override; private: - Material* _pMaterial = nullptr; - - PbrMetallicRoughnessJsonHandler _pbrMetallicRoughness; - NormalTextureInfoJsonHandler normalTexture; - OcclusionTextureInfoJsonHandler occlusionTexture; - TextureInfoJsonHandler _emissiveTexture; - DoubleArrayJsonHandler _emissiveFactor; - AlphaModeJsonHandler _alphaMode; - DoubleJsonHandler _alphaCutoff; - BoolJsonHandler _doubleSided; + Material::AlphaMode* _pEnum = nullptr; }; + + Material* _pObject; + MaterialPBRMetallicRoughnessJsonHandler _pbrMetallicRoughness; + MaterialNormalTextureInfoJsonHandler _normalTexture; + MaterialOcclusionTextureInfoJsonHandler _occlusionTexture; + TextureInfoJsonHandler _emissiveTexture; + ArrayJsonHandler _emissiveFactor; + AlphaModeJsonHandler _alphaMode; + DoubleJsonHandler _alphaCutoff; + BoolJsonHandler _doubleSided; + }; } diff --git a/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.cpp b/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.cpp new file mode 100644 index 000000000..f33489ded --- /dev/null +++ b/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.cpp @@ -0,0 +1,23 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MaterialNormalTextureInfoJsonHandler.h" +#include "CesiumGltf/MaterialNormalTextureInfo.h" +#include +#include + +using namespace CesiumGltf; + +void MaterialNormalTextureInfoJsonHandler::reset(JsonHandler* pParent, MaterialNormalTextureInfo* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* MaterialNormalTextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("scale"s == str) return property(this->_scale, this->_pObject->scale); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.h b/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.h new file mode 100644 index 000000000..7e6eddb7c --- /dev/null +++ b/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.h @@ -0,0 +1,21 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "DoubleJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" + +namespace CesiumGltf { + struct MaterialNormalTextureInfo; + + class MaterialNormalTextureInfoJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, MaterialNormalTextureInfo* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + MaterialNormalTextureInfo* _pObject; + DoubleJsonHandler _scale; + }; +} diff --git a/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.cpp b/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.cpp new file mode 100644 index 000000000..f137e160e --- /dev/null +++ b/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.cpp @@ -0,0 +1,23 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MaterialOcclusionTextureInfoJsonHandler.h" +#include "CesiumGltf/MaterialOcclusionTextureInfo.h" +#include +#include + +using namespace CesiumGltf; + +void MaterialOcclusionTextureInfoJsonHandler::reset(JsonHandler* pParent, MaterialOcclusionTextureInfo* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* MaterialOcclusionTextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("strength"s == str) return property(this->_strength, this->_pObject->strength); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.h b/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.h new file mode 100644 index 000000000..46aeed7db --- /dev/null +++ b/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.h @@ -0,0 +1,21 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "DoubleJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" + +namespace CesiumGltf { + struct MaterialOcclusionTextureInfo; + + class MaterialOcclusionTextureInfoJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, MaterialOcclusionTextureInfo* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + MaterialOcclusionTextureInfo* _pObject; + DoubleJsonHandler _strength; + }; +} diff --git a/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.cpp b/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.cpp new file mode 100644 index 000000000..0489533a3 --- /dev/null +++ b/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.cpp @@ -0,0 +1,27 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MaterialPBRMetallicRoughnessJsonHandler.h" +#include "CesiumGltf/MaterialPBRMetallicRoughness.h" +#include +#include + +using namespace CesiumGltf; + +void MaterialPBRMetallicRoughnessJsonHandler::reset(JsonHandler* pParent, MaterialPBRMetallicRoughness* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* MaterialPBRMetallicRoughnessJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("baseColorFactor"s == str) return property(this->_baseColorFactor, this->_pObject->baseColorFactor); + if ("baseColorTexture"s == str) return property(this->_baseColorTexture, this->_pObject->baseColorTexture); + if ("metallicFactor"s == str) return property(this->_metallicFactor, this->_pObject->metallicFactor); + if ("roughnessFactor"s == str) return property(this->_roughnessFactor, this->_pObject->roughnessFactor); + if ("metallicRoughnessTexture"s == str) return property(this->_metallicRoughnessTexture, this->_pObject->metallicRoughnessTexture); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.h b/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.h new file mode 100644 index 000000000..bd4ee86cf --- /dev/null +++ b/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.h @@ -0,0 +1,27 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "ArrayJsonHandler.h" +#include "DoubleJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" +#include "TextureInfoJsonHandler.h" + +namespace CesiumGltf { + struct MaterialPBRMetallicRoughness; + + class MaterialPBRMetallicRoughnessJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, MaterialPBRMetallicRoughness* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + MaterialPBRMetallicRoughness* _pObject; + ArrayJsonHandler _baseColorFactor; + TextureInfoJsonHandler _baseColorTexture; + DoubleJsonHandler _metallicFactor; + DoubleJsonHandler _roughnessFactor; + TextureInfoJsonHandler _metallicRoughnessTexture; + }; +} diff --git a/CesiumGltfReader/src/MeshJsonHandler.cpp b/CesiumGltfReader/src/MeshJsonHandler.cpp index ff777815f..ea3178ae8 100644 --- a/CesiumGltfReader/src/MeshJsonHandler.cpp +++ b/CesiumGltfReader/src/MeshJsonHandler.cpp @@ -1,21 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #include "MeshJsonHandler.h" -#include +#include "CesiumGltf/Mesh.h" #include +#include using namespace CesiumGltf; -void MeshJsonHandler::reset(JsonHandler* pParent, Mesh* pMesh) { - JsonHandler::reset(pParent); - this->_pMesh = pMesh; +void MeshJsonHandler::reset(JsonHandler* pParent, Mesh* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; } JsonHandler* MeshJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; + using namespace std::string_literals; - assert(this->_pMesh); + assert(this->_pObject); - if ("primitives"s == str) return property(this->_primitives, this->_pMesh->primitives); - if ("weights"s == str) return property(this->_weights, this->_pMesh->weights); + if ("primitives"s == str) return property(this->_primitives, this->_pObject->primitives); + if ("weights"s == str) return property(this->_weights, this->_pObject->weights); - return this->NamedObjectKey(str, *this->_pMesh); + return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/src/MeshJsonHandler.h b/CesiumGltfReader/src/MeshJsonHandler.h index 9ee7dcb0e..557177c50 100644 --- a/CesiumGltfReader/src/MeshJsonHandler.h +++ b/CesiumGltfReader/src/MeshJsonHandler.h @@ -1,23 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once -#include "CesiumGltf/Mesh.h" -#include "DoubleArrayJsonHandler.h" +#include "ArrayJsonHandler.h" +#include "DoubleJsonHandler.h" +#include "MeshPrimitiveJsonHandler.h" #include "NamedObjectJsonHandler.h" -#include "ObjectArrayJsonHandler.h" -#include "PrimitiveJsonHandler.h" namespace CesiumGltf { - struct Mesh; - struct Primitive; + struct Mesh; - class MeshJsonHandler : public NamedObjectJsonHandler { - public: - void reset(JsonHandler* pParent, Mesh* pMesh); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + class MeshJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Mesh* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; - private: - Mesh* _pMesh = nullptr; - ObjectArrayJsonHandler _primitives; - DoubleArrayJsonHandler _weights; - }; + private: + + Mesh* _pObject; + ArrayJsonHandler _primitives; + ArrayJsonHandler _weights; + }; } diff --git a/CesiumGltfReader/src/MeshPrimitiveJsonHandler.cpp b/CesiumGltfReader/src/MeshPrimitiveJsonHandler.cpp new file mode 100644 index 000000000..e5e1a14f7 --- /dev/null +++ b/CesiumGltfReader/src/MeshPrimitiveJsonHandler.cpp @@ -0,0 +1,27 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MeshPrimitiveJsonHandler.h" +#include "CesiumGltf/MeshPrimitive.h" +#include +#include + +using namespace CesiumGltf; + +void MeshPrimitiveJsonHandler::reset(JsonHandler* pParent, MeshPrimitive* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* MeshPrimitiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("attributes"s == str) return property(this->_attributes, this->_pObject->attributes); + if ("indices"s == str) return property(this->_indices, this->_pObject->indices); + if ("material"s == str) return property(this->_material, this->_pObject->material); + if ("mode"s == str) return property(this->_mode, this->_pObject->mode); + if ("targets"s == str) return property(this->_targets, this->_pObject->targets); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/MeshPrimitiveJsonHandler.h b/CesiumGltfReader/src/MeshPrimitiveJsonHandler.h new file mode 100644 index 000000000..4faebaff6 --- /dev/null +++ b/CesiumGltfReader/src/MeshPrimitiveJsonHandler.h @@ -0,0 +1,28 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "ArrayJsonHandler.h" +#include "CesiumGltf/MeshPrimitive.h" +#include "DictionaryJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct MeshPrimitive; + + class MeshPrimitiveJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, MeshPrimitive* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + MeshPrimitive* _pObject; + DictionaryJsonHandler> _attributes; + IntegerJsonHandler _indices; + IntegerJsonHandler _material; + IntegerJsonHandler _mode; + ArrayJsonHandler, DictionaryJsonHandler>> _targets; + }; +} diff --git a/CesiumGltfReader/src/ModelJsonHandler.cpp b/CesiumGltfReader/src/ModelJsonHandler.cpp index e36fd0a50..3334361cf 100644 --- a/CesiumGltfReader/src/ModelJsonHandler.cpp +++ b/CesiumGltfReader/src/ModelJsonHandler.cpp @@ -1,20 +1,39 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #include "ModelJsonHandler.h" +#include "CesiumGltf/Model.h" #include #include using namespace CesiumGltf; -void ModelJsonHandler::reset(JsonHandler* pParent, Model* pModel) { - ObjectJsonHandler::reset(pParent); - this->_pModel = pModel; +void ModelJsonHandler::reset(JsonHandler* pParent, Model* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; } JsonHandler* ModelJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; + using namespace std::string_literals; - assert(this->_pModel); - if ("accessors"s == str) return property(this->_accessors, this->_pModel->accessors); - if ("meshes"s == str) return property(this->_meshes, this->_pModel->meshes); + assert(this->_pObject); - return this->ignore(); + if ("extensionsUsed"s == str) return property(this->_extensionsUsed, this->_pObject->extensionsUsed); + if ("extensionsRequired"s == str) return property(this->_extensionsRequired, this->_pObject->extensionsRequired); + if ("accessors"s == str) return property(this->_accessors, this->_pObject->accessors); + if ("animations"s == str) return property(this->_animations, this->_pObject->animations); + if ("asset"s == str) return property(this->_asset, this->_pObject->asset); + if ("buffers"s == str) return property(this->_buffers, this->_pObject->buffers); + if ("bufferViews"s == str) return property(this->_bufferViews, this->_pObject->bufferViews); + if ("cameras"s == str) return property(this->_cameras, this->_pObject->cameras); + if ("images"s == str) return property(this->_images, this->_pObject->images); + if ("materials"s == str) return property(this->_materials, this->_pObject->materials); + if ("meshes"s == str) return property(this->_meshes, this->_pObject->meshes); + if ("nodes"s == str) return property(this->_nodes, this->_pObject->nodes); + if ("samplers"s == str) return property(this->_samplers, this->_pObject->samplers); + if ("scene"s == str) return property(this->_scene, this->_pObject->scene); + if ("scenes"s == str) return property(this->_scenes, this->_pObject->scenes); + if ("skins"s == str) return property(this->_skins, this->_pObject->skins); + if ("textures"s == str) return property(this->_textures, this->_pObject->textures); + + return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/src/ModelJsonHandler.h b/CesiumGltfReader/src/ModelJsonHandler.h index ac8f07952..3968f209a 100644 --- a/CesiumGltfReader/src/ModelJsonHandler.h +++ b/CesiumGltfReader/src/ModelJsonHandler.h @@ -1,20 +1,53 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once -#include "ObjectJsonHandler.h" -#include "ObjectArrayJsonHandler.h" -#include "CesiumGltf/Model.h" #include "AccessorJsonHandler.h" +#include "AnimationJsonHandler.h" +#include "ArrayJsonHandler.h" +#include "AssetJsonHandler.h" +#include "BufferJsonHandler.h" +#include "BufferViewJsonHandler.h" +#include "CameraJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" +#include "ImageJsonHandler.h" +#include "IntegerJsonHandler.h" +#include "MaterialJsonHandler.h" #include "MeshJsonHandler.h" +#include "NodeJsonHandler.h" +#include "SamplerJsonHandler.h" +#include "SceneJsonHandler.h" +#include "SkinJsonHandler.h" +#include "StringJsonHandler.h" +#include "TextureJsonHandler.h" namespace CesiumGltf { - class ModelJsonHandler : public ObjectJsonHandler { - public: - void reset(JsonHandler* pParent, Model* pModel); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + struct Model; - private: - Model* _pModel; - ObjectArrayJsonHandler _accessors; - ObjectArrayJsonHandler _meshes; - }; + class ModelJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Model* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + Model* _pObject; + ArrayJsonHandler _extensionsUsed; + ArrayJsonHandler _extensionsRequired; + ArrayJsonHandler _accessors; + ArrayJsonHandler _animations; + AssetJsonHandler _asset; + ArrayJsonHandler _buffers; + ArrayJsonHandler _bufferViews; + ArrayJsonHandler _cameras; + ArrayJsonHandler _images; + ArrayJsonHandler _materials; + ArrayJsonHandler _meshes; + ArrayJsonHandler _nodes; + ArrayJsonHandler _samplers; + IntegerJsonHandler _scene; + ArrayJsonHandler _scenes; + ArrayJsonHandler _skins; + ArrayJsonHandler _textures; + }; } diff --git a/CesiumGltfReader/src/NodeJsonHandler.cpp b/CesiumGltfReader/src/NodeJsonHandler.cpp new file mode 100644 index 000000000..9bfba6f46 --- /dev/null +++ b/CesiumGltfReader/src/NodeJsonHandler.cpp @@ -0,0 +1,31 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "NodeJsonHandler.h" +#include "CesiumGltf/Node.h" +#include +#include + +using namespace CesiumGltf; + +void NodeJsonHandler::reset(JsonHandler* pParent, Node* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* NodeJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("camera"s == str) return property(this->_camera, this->_pObject->camera); + if ("children"s == str) return property(this->_children, this->_pObject->children); + if ("skin"s == str) return property(this->_skin, this->_pObject->skin); + if ("matrix"s == str) return property(this->_matrix, this->_pObject->matrix); + if ("mesh"s == str) return property(this->_mesh, this->_pObject->mesh); + if ("rotation"s == str) return property(this->_rotation, this->_pObject->rotation); + if ("scale"s == str) return property(this->_scale, this->_pObject->scale); + if ("translation"s == str) return property(this->_translation, this->_pObject->translation); + if ("weights"s == str) return property(this->_weights, this->_pObject->weights); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/NodeJsonHandler.h b/CesiumGltfReader/src/NodeJsonHandler.h new file mode 100644 index 000000000..5d070f5a1 --- /dev/null +++ b/CesiumGltfReader/src/NodeJsonHandler.h @@ -0,0 +1,31 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "ArrayJsonHandler.h" +#include "DoubleJsonHandler.h" +#include "IntegerJsonHandler.h" +#include "NamedObjectJsonHandler.h" + +namespace CesiumGltf { + struct Node; + + class NodeJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Node* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + Node* _pObject; + IntegerJsonHandler _camera; + ArrayJsonHandler> _children; + IntegerJsonHandler _skin; + ArrayJsonHandler _matrix; + IntegerJsonHandler _mesh; + ArrayJsonHandler _rotation; + ArrayJsonHandler _scale; + ArrayJsonHandler _translation; + ArrayJsonHandler _weights; + }; +} diff --git a/CesiumGltfReader/src/NormalTextureInfoJsonHandler.cpp b/CesiumGltfReader/src/NormalTextureInfoJsonHandler.cpp deleted file mode 100644 index 9a151469f..000000000 --- a/CesiumGltfReader/src/NormalTextureInfoJsonHandler.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "NormalTextureInfoJsonHandler.h" -#include "CesiumGltf/NormalTextureInfo.h" -#include -#include - -using namespace CesiumGltf; - -void NormalTextureInfoJsonHandler::reset(JsonHandler* pParent, NormalTextureInfo* pNormalTextureInfo) { - JsonHandler::reset(pParent); - this->_pNormalTextureInfo = pNormalTextureInfo; -} - -JsonHandler* NormalTextureInfoJsonHandler::Key(const char* str, size_t length, bool copy) { - using namespace std::string_literals; - - assert(this->_pNormalTextureInfo); - - if ("scale"s == str) return property(this->_scale, this->_pNormalTextureInfo->scale); - - return TextureInfoJsonHandler::Key(str, length, copy); -} diff --git a/CesiumGltfReader/src/NormalTextureInfoJsonHandler.h b/CesiumGltfReader/src/NormalTextureInfoJsonHandler.h deleted file mode 100644 index 8e20b9988..000000000 --- a/CesiumGltfReader/src/NormalTextureInfoJsonHandler.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "TextureInfoJsonHandler.h" -#include "DoubleJsonHandler.h" - -namespace CesiumGltf { - struct NormalTextureInfo; - - class NormalTextureInfoJsonHandler : public TextureInfoJsonHandler { - public: - void reset(JsonHandler* pParent, NormalTextureInfo* pNormalTextureInfo); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; - - private: - NormalTextureInfo* _pNormalTextureInfo = nullptr; - - DoubleJsonHandler _scale; - }; -} diff --git a/CesiumGltfReader/src/ObjectArrayJsonHandler.h b/CesiumGltfReader/src/ObjectArrayJsonHandler.h deleted file mode 100644 index 25d6fc408..000000000 --- a/CesiumGltfReader/src/ObjectArrayJsonHandler.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "JsonHandler.h" -#include -#include - -namespace CesiumGltf { - template - class ObjectArrayJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent, std::vector* pArray) { - this->_pParent = pParent; - this->_pArray = pArray; - this->_arrayIsOpen = false; - } - - virtual JsonHandler* StartArray() override { - if (this->_arrayIsOpen) { - return nullptr; - } - - this->_arrayIsOpen = true; - return this; - } - - virtual JsonHandler* EndArray(size_t) override { - return this->_pParent; - } - - virtual JsonHandler* StartObject() override { - if (!this->_arrayIsOpen) { - return nullptr; - } - - assert(this->_pArray); - T& o = this->_pArray->emplace_back(); - this->_objectHandler.reset(this, &o); - return this->_objectHandler.StartObject(); - } - - private: - JsonHandler* _pParent = nullptr; - std::vector* _pArray = nullptr; - bool _arrayIsOpen = false; - THandler _objectHandler; - }; -} diff --git a/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.cpp b/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.cpp deleted file mode 100644 index eeb9bdae8..000000000 --- a/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "OcclusionTextureInfoJsonHandler.h" -#include "CesiumGltf/OcclusionTextureInfo.h" -#include -#include - -using namespace CesiumGltf; - -void OcclusionTextureInfoJsonHandler::reset(JsonHandler* pParent, OcclusionTextureInfo* pOcclusionTextureInfo) { - JsonHandler::reset(pParent); - this->_pOcclusionTextureInfo = pOcclusionTextureInfo; -} - -JsonHandler* OcclusionTextureInfoJsonHandler::Key(const char* str, size_t length, bool copy) { - using namespace std::string_literals; - - assert(this->_pOcclusionTextureInfo); - - if ("strength"s == str) return property(this->_strength, this->_pOcclusionTextureInfo->strength); - - return TextureInfoJsonHandler::Key(str, length, copy); -} diff --git a/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.h b/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.h deleted file mode 100644 index 63fd16f6a..000000000 --- a/CesiumGltfReader/src/OcclusionTextureInfoJsonHandler.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "TextureInfoJsonHandler.h" -#include "DoubleJsonHandler.h" - -namespace CesiumGltf { - struct OcclusionTextureInfo; - - class OcclusionTextureInfoJsonHandler : public TextureInfoJsonHandler { - public: - void reset(JsonHandler* pParent, OcclusionTextureInfo* pOcclusionTextureInfo); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; - - private: - OcclusionTextureInfo* _pOcclusionTextureInfo = nullptr; - - DoubleJsonHandler _strength; - }; -} diff --git a/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.cpp b/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.cpp deleted file mode 100644 index 847bf565c..000000000 --- a/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "PbrMetallicRoughnessJsonHandler.h" -#include "CesiumGltf/PbrMetallicRoughness.h" -#include -#include - -using namespace CesiumGltf; - -void PbrMetallicRoughnessJsonHandler::reset(JsonHandler* pParent, PbrMetallicRoughness* pPbr) { - JsonHandler::reset(pParent); - this->_pPbr = pPbr; -} - -JsonHandler* PbrMetallicRoughnessJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pPbr); - - if ("baseColorFactor"s == str) return property(this->_baseColorFactor, this->_pPbr->baseColorFactor); - if ("baseColorTexture"s == str) return property(this->_baseColorTexture, this->_pPbr->baseColorTexture); - if ("metallicFactor"s == str) return property(this->_metallicFactor, this->_pPbr->metallicFactor); - if ("roughnessFactor"s == str) return property(this->_roughnessFactor, this->_pPbr->roughnessFactor); - if ("metallicRoughnessTexture"s == str) return property(this->_metallicRoughnessTexture, this->_pPbr->metallicRoughnessTexture); - - return this->ExtensibleObjectKey(str, *this->_pPbr); -} diff --git a/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.h b/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.h deleted file mode 100644 index 72f4068ef..000000000 --- a/CesiumGltfReader/src/PbrMetallicRoughnessJsonHandler.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "DoubleArrayJsonHandler.h" -#include "DoubleJsonHandler.h" -#include "ExtensibleObjectJsonHandler.h" -#include "TextureInfoJsonHandler.h" - -namespace CesiumGltf { - struct PbrMetallicRoughness; - - class PbrMetallicRoughnessJsonHandler : public ExtensibleObjectJsonHandler { - public: - void reset(JsonHandler* pParent, PbrMetallicRoughness* pPbr); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; - - private: - PbrMetallicRoughness* _pPbr = nullptr; - - DoubleArrayJsonHandler _baseColorFactor; - TextureInfoJsonHandler _baseColorTexture; - DoubleJsonHandler _metallicFactor; - DoubleJsonHandler _roughnessFactor; - TextureInfoJsonHandler _metallicRoughnessTexture; - }; -} diff --git a/CesiumGltfReader/src/PrimitiveJsonHandler.cpp b/CesiumGltfReader/src/PrimitiveJsonHandler.cpp deleted file mode 100644 index 206c47825..000000000 --- a/CesiumGltfReader/src/PrimitiveJsonHandler.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "PrimitiveJsonHandler.h" -#include "CesiumGltf/Primitive.h" -#include -#include - -using namespace CesiumGltf; - -void PrimitiveJsonHandler::reset(JsonHandler* pParent, Primitive* pPrimitive) { - JsonHandler::reset(pParent); - this->_pPrimitive = pPrimitive; -} - -JsonHandler* PrimitiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pPrimitive); - - if ("attributes"s == str) return property(this->_attributes, this->_pPrimitive->attributes); - if ("indices"s == str) return property(this->_indices, this->_pPrimitive->indices); - if ("material"s == str) return property(this->_material, this->_pPrimitive->material); - if ("mode"s == str) return property(this->_mode, this->_pPrimitive->mode); - if ("targets"s == str) return property(this->_targets, this->_pPrimitive->targets); - - return this->ExtensibleObjectKey(str, *this->_pPrimitive); -} diff --git a/CesiumGltfReader/src/PrimitiveJsonHandler.h b/CesiumGltfReader/src/PrimitiveJsonHandler.h deleted file mode 100644 index bc7e50db9..000000000 --- a/CesiumGltfReader/src/PrimitiveJsonHandler.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "AttributeJsonHandler.h" -#include "CesiumGltf/PrimitiveMode.h" -#include "ExtensibleObjectJsonHandler.h" -#include "IntegerJsonHandler.h" -#include "ObjectArrayJsonHandler.h" - -namespace CesiumGltf { - struct Primitive; - - class PrimitiveJsonHandler : public ExtensibleObjectJsonHandler { - public: - void reset(JsonHandler* pParent, Primitive* pPrimitive); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; - - private: - Primitive* _pPrimitive = nullptr; - - AttributeJsonHandler _attributes; - IntegerJsonHandler _indices; - IntegerJsonHandler _material; - IntegerJsonHandler _mode; - ObjectArrayJsonHandler, AttributeJsonHandler> _targets; - }; -} diff --git a/CesiumGltfReader/src/SamplerJsonHandler.cpp b/CesiumGltfReader/src/SamplerJsonHandler.cpp new file mode 100644 index 000000000..c5caec635 --- /dev/null +++ b/CesiumGltfReader/src/SamplerJsonHandler.cpp @@ -0,0 +1,26 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "SamplerJsonHandler.h" +#include "CesiumGltf/Sampler.h" +#include +#include + +using namespace CesiumGltf; + +void SamplerJsonHandler::reset(JsonHandler* pParent, Sampler* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* SamplerJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("magFilter"s == str) return property(this->_magFilter, this->_pObject->magFilter); + if ("minFilter"s == str) return property(this->_minFilter, this->_pObject->minFilter); + if ("wrapS"s == str) return property(this->_wrapS, this->_pObject->wrapS); + if ("wrapT"s == str) return property(this->_wrapT, this->_pObject->wrapT); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/SamplerJsonHandler.h b/CesiumGltfReader/src/SamplerJsonHandler.h new file mode 100644 index 000000000..7fb787432 --- /dev/null +++ b/CesiumGltfReader/src/SamplerJsonHandler.h @@ -0,0 +1,25 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/Sampler.h" +#include "IntegerJsonHandler.h" +#include "NamedObjectJsonHandler.h" + +namespace CesiumGltf { + struct Sampler; + + class SamplerJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Sampler* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + Sampler* _pObject; + IntegerJsonHandler _magFilter; + IntegerJsonHandler _minFilter; + IntegerJsonHandler _wrapS; + IntegerJsonHandler _wrapT; + }; +} diff --git a/CesiumGltfReader/src/SceneJsonHandler.cpp b/CesiumGltfReader/src/SceneJsonHandler.cpp new file mode 100644 index 000000000..1cbc8d9a6 --- /dev/null +++ b/CesiumGltfReader/src/SceneJsonHandler.cpp @@ -0,0 +1,23 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "SceneJsonHandler.h" +#include "CesiumGltf/Scene.h" +#include +#include + +using namespace CesiumGltf; + +void SceneJsonHandler::reset(JsonHandler* pParent, Scene* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* SceneJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("nodes"s == str) return property(this->_nodes, this->_pObject->nodes); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/SceneJsonHandler.h b/CesiumGltfReader/src/SceneJsonHandler.h new file mode 100644 index 000000000..2c0abafc7 --- /dev/null +++ b/CesiumGltfReader/src/SceneJsonHandler.h @@ -0,0 +1,22 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "ArrayJsonHandler.h" +#include "IntegerJsonHandler.h" +#include "NamedObjectJsonHandler.h" + +namespace CesiumGltf { + struct Scene; + + class SceneJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Scene* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + Scene* _pObject; + ArrayJsonHandler> _nodes; + }; +} diff --git a/CesiumGltfReader/src/SkinJsonHandler.cpp b/CesiumGltfReader/src/SkinJsonHandler.cpp new file mode 100644 index 000000000..74773ecf7 --- /dev/null +++ b/CesiumGltfReader/src/SkinJsonHandler.cpp @@ -0,0 +1,25 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "SkinJsonHandler.h" +#include "CesiumGltf/Skin.h" +#include +#include + +using namespace CesiumGltf; + +void SkinJsonHandler::reset(JsonHandler* pParent, Skin* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* SkinJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("inverseBindMatrices"s == str) return property(this->_inverseBindMatrices, this->_pObject->inverseBindMatrices); + if ("skeleton"s == str) return property(this->_skeleton, this->_pObject->skeleton); + if ("joints"s == str) return property(this->_joints, this->_pObject->joints); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/SkinJsonHandler.h b/CesiumGltfReader/src/SkinJsonHandler.h new file mode 100644 index 000000000..e77f871c6 --- /dev/null +++ b/CesiumGltfReader/src/SkinJsonHandler.h @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "ArrayJsonHandler.h" +#include "IntegerJsonHandler.h" +#include "NamedObjectJsonHandler.h" + +namespace CesiumGltf { + struct Skin; + + class SkinJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Skin* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + Skin* _pObject; + IntegerJsonHandler _inverseBindMatrices; + IntegerJsonHandler _skeleton; + ArrayJsonHandler> _joints; + }; +} diff --git a/CesiumGltfReader/src/TextureInfoJsonHandler.cpp b/CesiumGltfReader/src/TextureInfoJsonHandler.cpp index a7aaca0ce..dbca18be9 100644 --- a/CesiumGltfReader/src/TextureInfoJsonHandler.cpp +++ b/CesiumGltfReader/src/TextureInfoJsonHandler.cpp @@ -1,22 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #include "TextureInfoJsonHandler.h" #include "CesiumGltf/TextureInfo.h" -#include #include +#include using namespace CesiumGltf; -void TextureInfoJsonHandler::reset(JsonHandler* pParent, TextureInfo* pTextureInfo) { - JsonHandler::reset(pParent); - this->_pTextureInfo = pTextureInfo; +void TextureInfoJsonHandler::reset(JsonHandler* pParent, TextureInfo* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; } JsonHandler* TextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; + using namespace std::string_literals; - assert(this->_pTextureInfo); + assert(this->_pObject); - if ("index"s == str) return property(this->_index, this->_pTextureInfo->index); - if ("texCoord"s == str) return property(this->_texCoord, this->_pTextureInfo->texCoord); + if ("index"s == str) return property(this->_index, this->_pObject->index); + if ("texCoord"s == str) return property(this->_texCoord, this->_pObject->texCoord); - return this->ExtensibleObjectKey(str, *this->_pTextureInfo); + return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/src/TextureInfoJsonHandler.h b/CesiumGltfReader/src/TextureInfoJsonHandler.h index bbd063378..20b2d5ea8 100644 --- a/CesiumGltfReader/src/TextureInfoJsonHandler.h +++ b/CesiumGltfReader/src/TextureInfoJsonHandler.h @@ -1,20 +1,22 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! #pragma once #include "ExtensibleObjectJsonHandler.h" #include "IntegerJsonHandler.h" namespace CesiumGltf { - struct TextureInfo; + struct TextureInfo; - class TextureInfoJsonHandler : public ExtensibleObjectJsonHandler { - public: - void reset(JsonHandler* pParent, TextureInfo* pTextureInfo); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + class TextureInfoJsonHandler final : public ExtensibleObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, TextureInfo* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; - private: - TextureInfo* _pTextureInfo = nullptr; + private: - IntegerJsonHandler _index; - IntegerJsonHandler _texCoord; - }; + TextureInfo* _pObject; + IntegerJsonHandler _index; + IntegerJsonHandler _texCoord; + }; } diff --git a/CesiumGltfReader/src/TextureJsonHandler.cpp b/CesiumGltfReader/src/TextureJsonHandler.cpp new file mode 100644 index 000000000..32cf10301 --- /dev/null +++ b/CesiumGltfReader/src/TextureJsonHandler.cpp @@ -0,0 +1,24 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "TextureJsonHandler.h" +#include "CesiumGltf/Texture.h" +#include +#include + +using namespace CesiumGltf; + +void TextureJsonHandler::reset(JsonHandler* pParent, Texture* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +JsonHandler* TextureJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("sampler"s == str) return property(this->_sampler, this->_pObject->sampler); + if ("source"s == str) return property(this->_source, this->_pObject->source); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/TextureJsonHandler.h b/CesiumGltfReader/src/TextureJsonHandler.h new file mode 100644 index 000000000..67e480415 --- /dev/null +++ b/CesiumGltfReader/src/TextureJsonHandler.h @@ -0,0 +1,22 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "IntegerJsonHandler.h" +#include "NamedObjectJsonHandler.h" + +namespace CesiumGltf { + struct Texture; + + class TextureJsonHandler final : public NamedObjectJsonHandler { + public: + void reset(JsonHandler* pHandler, Texture* pObject); + virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + + Texture* _pObject; + IntegerJsonHandler _sampler; + IntegerJsonHandler _source; + }; +} diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index 03b2db03d..c59e1cf52 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -34,6 +34,8 @@ function generate(options, schema) { headers.sort(); const header = ` + // This file was generated by generate-gltf-classes. + // DO NOT EDIT THIS FILE! #pragma once ${headers.map((header) => `#include ${header}`).join("\n")} @@ -70,6 +72,8 @@ function generate(options, schema) { ); const readerHeader = ` + // This file was generated by generate-gltf-classes. + // DO NOT EDIT THIS FILE! #pragma once ${readerHeaders.map((header) => `#include ${header}`).join("\n")} @@ -106,6 +110,8 @@ function generate(options, schema) { ); const readerImpl = ` + // This file was generated by generate-gltf-classes. + // DO NOT EDIT THIS FILE! #include "${name}JsonHandler.h" #include "CesiumGltf/${name}.h" #include diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index fb97d7720..2103d8100 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -159,7 +159,7 @@ function resolveArray(schemaCache, nameMapping, parentName, propertyName, proper localTypes: itemProperty.localTypes, type: `std::vector<${itemProperty.type}>`, readerHeaders: [`"ArrayJsonHandler.h"`, ...itemProperty.readerHeaders], - readerType: `ArrayJsonHandler<${itemProperty.type}>` + readerType: `ArrayJsonHandler<${itemProperty.type}, ${itemProperty.readerType}>` }; } @@ -195,9 +195,9 @@ function resolveEnum(schemaCache, nameMapping, parentName, propertyName, propert const enumName = toPascalCase(propertyName); - const readerTypes = createEnumReaderType(enumName, propertyName, propertyDetails); + const readerTypes = createEnumReaderType(parentName, enumName, propertyName, propertyDetails); - return { + const result = { ...propertyDefaults(propertyName, propertyDetails), localTypes: [ unindent(` @@ -213,10 +213,19 @@ function resolveEnum(schemaCache, nameMapping, parentName, propertyName, propert `) ], type: enumName, + readerHeaders: [`"CesiumGltf/${parentName}.h"`], readerLocalTypes: readerTypes, - readerLocalTypesImpl: createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDetails), - readerType: readerTypes.length > 0 ? `${enumName}JsonHandler` : "IntegerJsonHandler" + readerLocalTypesImpl: createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDetails) }; + + if (readerTypes.length > 0) { + result.readerType = `${enumName}JsonHandler`; + } else { + result.readerType = `IntegerJsonHandler<${parentName}::${enumName}>`; + result.readerHeaders.push(`"IntegerJsonHandler.h"`); + } + + return result; } function createEnum(enumDetails) { @@ -231,7 +240,7 @@ function createEnum(enumDetails) { } } -function createEnumReaderType(enumName, propertyName, propertyDetails) { +function createEnumReaderType(parentName, enumName, propertyName, propertyDetails) { if (propertyDetails.anyOf[0].type === "integer") { // No special reader needed for integer enums. return []; @@ -240,11 +249,11 @@ function createEnumReaderType(enumName, propertyName, propertyDetails) { return unindent(` class ${enumName}JsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, ${enumName}* pEnum); + void reset(JsonHandler* pParent, ${parentName}::${enumName}* pEnum); virtual JsonHandler* String(const char* str, size_t length, bool copy) override; private: - ${enumName}* _pEnum = nullptr; + ${parentName}::${enumName}* _pEnum = nullptr; }; `); } @@ -256,19 +265,19 @@ function createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDe } return unindent(` - void ${parentName}JsonHandler::${enumName}JsonHandler::reset(JsonHandler* pParent, ${enumName}* pEnum) { + void ${parentName}JsonHandler::${enumName}JsonHandler::reset(JsonHandler* pParent, ${parentName}::${enumName}* pEnum) { JsonHandler::reset(pParent); this->_pEnum = pEnum; } - JsonHandler* ${parentName}JsonHandler::${enumName}JsonHandler::String(const char* str, size_t length, bool copy) { + JsonHandler* ${parentName}JsonHandler::${enumName}JsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { using namespace std::string_literals; assert(this->_pEnum); ${indent( propertyDetails.anyOf - .map((e) => e.enum && e.enum[0] !== undefined ? `if ("${e.enum[0]}"s == str) *this->_pEnum = ${enumName}::${makeIdentifier(e.enum[0])};` : undefined) + .map((e) => e.enum && e.enum[0] !== undefined ? `if ("${e.enum[0]}"s == str) *this->_pEnum = ${parentName}::${enumName}::${makeIdentifier(e.enum[0])};` : undefined) .filter(s => s !== undefined) .join("\nelse "), 6 From 068df1c3ef2d52b7712ab59eb36ef6989273b261 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 6 Jan 2021 13:00:54 +1100 Subject: [PATCH 20/61] Improve error handling. --- CesiumGltf/test/TestGltfModel.cpp | 5 +- CesiumGltfReader/include/CesiumGltf/Reader.h | 3 +- CesiumGltfReader/src/Reader.cpp | 72 +++++++++++++++++++- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index 3bb4f121c..eaa3bc888 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -34,7 +34,10 @@ TEST_CASE("GltfModel") { " \"surprise\":{\"foo\":true}"s + "}"s; ModelReaderResult result = CesiumGltf::readModel(gsl::span(reinterpret_cast(s.c_str()), s.size())); - Model& model = result.model; + CHECK(result.errors.empty()); + REQUIRE(result.model.has_value()); + + Model& model = result.model.value(); REQUIRE(model.accessors.size() == 1); CHECK(model.accessors[0].count == 4); CHECK(model.accessors[0].componentType == Accessor::ComponentType::UNSIGNED_BYTE); diff --git a/CesiumGltfReader/include/CesiumGltf/Reader.h b/CesiumGltfReader/include/CesiumGltf/Reader.h index 1d445ff62..92bf585c1 100644 --- a/CesiumGltfReader/include/CesiumGltf/Reader.h +++ b/CesiumGltfReader/include/CesiumGltf/Reader.h @@ -2,10 +2,11 @@ #include "CesiumGltf/Model.h" #include +#include namespace CesiumGltf { struct ModelReaderResult { - Model model; + std::optional model; std::string errors; std::string warnings; }; diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 71944fb4e..971a0c351 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -3,6 +3,7 @@ #include "ModelJsonHandler.h" #include "RejectAllJsonHandler.h" #include +#include using namespace CesiumGltf; @@ -45,7 +46,8 @@ ModelReaderResult CesiumGltf::readModel(const gsl::span& data) { RejectAllJsonHandler rejectHandler; Dispatcher dispatcher { &modelHandler }; - modelHandler.reset(&rejectHandler, &result.model); + result.model.emplace(); + modelHandler.reset(&rejectHandler, &result.model.value()); reader.IterativeParseInit(); @@ -54,5 +56,73 @@ ModelReaderResult CesiumGltf::readModel(const gsl::span& data) { success = reader.IterativeParseNext(inputStream, dispatcher); } + if (reader.HasParseError()) { + result.model.reset(); + + std::string s("glTF JSON parsing error at byte offset "); + s += std::to_string(reader.GetErrorOffset()); + s += ": "; + + switch (reader.GetParseErrorCode()) { + case rapidjson::ParseErrorCode::kParseErrorDocumentEmpty: + s += "The document is empty."; + break; + case rapidjson::ParseErrorCode::kParseErrorDocumentRootNotSingular: + s += "The document root must not be followed by other values."; + break; + case rapidjson::ParseErrorCode::kParseErrorValueInvalid: + s += "Invalid value."; + break; + case rapidjson::ParseErrorCode::kParseErrorObjectMissName: + s += "Missing a name for object member."; + break; + case rapidjson::ParseErrorCode::kParseErrorObjectMissColon: + s += "Missing a colon after a name of object member."; + break; + case rapidjson::ParseErrorCode::kParseErrorObjectMissCommaOrCurlyBracket: + s += "Missing a comma or '}' after an object member."; + break; + case rapidjson::ParseErrorCode::kParseErrorArrayMissCommaOrSquareBracket: + s += "Missing a comma or ']' after an array element."; + break; + case rapidjson::ParseErrorCode::kParseErrorStringUnicodeEscapeInvalidHex: + s += "Incorrect hex digit after \\u escape in string."; + break; + case rapidjson::ParseErrorCode::kParseErrorStringUnicodeSurrogateInvalid: + s += "The surrogate pair in string is invalid."; + break; + case rapidjson::ParseErrorCode::kParseErrorStringEscapeInvalid: + s += "Invalid escape character in string."; + break; + case rapidjson::ParseErrorCode::kParseErrorStringMissQuotationMark: + s += "Missing a closing quotation mark in string."; + break; + case rapidjson::ParseErrorCode::kParseErrorStringInvalidEncoding: + s += "Invalid encoding in string."; + break; + case rapidjson::ParseErrorCode::kParseErrorNumberTooBig: + s += "Number too big to be stored in double."; + break; + case rapidjson::ParseErrorCode::kParseErrorNumberMissFraction: + s += "Missing fraction part in number."; + break; + case rapidjson::ParseErrorCode::kParseErrorNumberMissExponent: + s += "Missing exponent in number."; + break; + case rapidjson::ParseErrorCode::kParseErrorTermination: + s += "Parsing was terminated."; + break; + case rapidjson::ParseErrorCode::kParseErrorUnspecificSyntaxError: + default: + s += "Unspecific syntax error."; + break; + } + + if (!result.errors.empty()) { + result.errors.push_back('\n'); + } + result.errors += s; + } + return result; } From 32dca3f5d8d021119f266531358714062ffaff21 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 6 Jan 2021 20:56:53 +1100 Subject: [PATCH 21/61] Improved error reporting. --- CesiumGltf/test/TestGltfModel.cpp | 2 +- CesiumGltfReader/CMakeLists.txt | 3 +- .../generated/AccessorJsonHandler.cpp | 64 +++++++++++++++ .../{src => generated}/AccessorJsonHandler.h | 11 ++- .../AccessorSparseIndicesJsonHandler.cpp | 36 +++++++++ .../AccessorSparseIndicesJsonHandler.h | 7 +- .../generated/AccessorSparseJsonHandler.cpp | 36 +++++++++ .../AccessorSparseJsonHandler.h | 7 +- .../AccessorSparseValuesJsonHandler.cpp | 35 ++++++++ .../AccessorSparseValuesJsonHandler.h | 7 +- .../generated/AnimationChannelJsonHandler.cpp | 35 ++++++++ .../AnimationChannelJsonHandler.h | 7 +- .../AnimationChannelTargetJsonHandler.cpp | 54 +++++++++++++ .../AnimationChannelTargetJsonHandler.h | 11 ++- .../generated/AnimationJsonHandler.cpp | 35 ++++++++ .../{src => generated}/AnimationJsonHandler.h | 7 +- .../generated/AnimationSamplerJsonHandler.cpp | 54 +++++++++++++ .../AnimationSamplerJsonHandler.h | 11 ++- .../generated/AssetJsonHandler.cpp | 37 +++++++++ .../{src => generated}/AssetJsonHandler.h | 7 +- .../generated/BufferJsonHandler.cpp | 35 ++++++++ .../{src => generated}/BufferJsonHandler.h | 7 +- .../generated/BufferViewJsonHandler.cpp | 38 +++++++++ .../BufferViewJsonHandler.h | 7 +- .../generated/CameraJsonHandler.cpp | 53 ++++++++++++ .../{src => generated}/CameraJsonHandler.h | 11 ++- .../CameraOrthographicJsonHandler.cpp | 37 +++++++++ .../CameraOrthographicJsonHandler.h | 7 +- .../CameraPerspectiveJsonHandler.cpp | 37 +++++++++ .../CameraPerspectiveJsonHandler.h | 7 +- .../generated/ImageJsonHandler.cpp | 53 ++++++++++++ .../{src => generated}/ImageJsonHandler.h | 11 ++- .../generated/MaterialJsonHandler.cpp | 59 ++++++++++++++ .../{src => generated}/MaterialJsonHandler.h | 11 ++- .../MaterialNormalTextureInfoJsonHandler.cpp | 34 ++++++++ .../MaterialNormalTextureInfoJsonHandler.h | 7 +- ...aterialOcclusionTextureInfoJsonHandler.cpp | 34 ++++++++ .../MaterialOcclusionTextureInfoJsonHandler.h | 7 +- ...aterialPBRMetallicRoughnessJsonHandler.cpp | 38 +++++++++ .../MaterialPBRMetallicRoughnessJsonHandler.h | 7 +- .../generated/MeshJsonHandler.cpp | 35 ++++++++ .../{src => generated}/MeshJsonHandler.h | 7 +- .../generated/MeshPrimitiveJsonHandler.cpp | 38 +++++++++ .../MeshPrimitiveJsonHandler.h | 7 +- .../generated/ModelJsonHandler.cpp | 50 ++++++++++++ .../{src => generated}/ModelJsonHandler.h | 7 +- .../generated/NodeJsonHandler.cpp | 42 ++++++++++ .../{src => generated}/NodeJsonHandler.h | 7 +- .../generated/SamplerJsonHandler.cpp | 37 +++++++++ .../{src => generated}/SamplerJsonHandler.h | 7 +- .../generated/SceneJsonHandler.cpp | 34 ++++++++ .../{src => generated}/SceneJsonHandler.h | 7 +- .../generated/SkinJsonHandler.cpp | 36 +++++++++ .../{src => generated}/SkinJsonHandler.h | 7 +- .../generated/TextureInfoJsonHandler.cpp | 35 ++++++++ .../TextureInfoJsonHandler.h | 7 +- .../generated/TextureJsonHandler.cpp | 35 ++++++++ .../{src => generated}/TextureJsonHandler.h | 7 +- CesiumGltfReader/src/AccessorJsonHandler.cpp | 53 ------------ .../src/AccessorSparseIndicesJsonHandler.cpp | 25 ------ .../src/AccessorSparseJsonHandler.cpp | 25 ------ .../src/AccessorSparseValuesJsonHandler.cpp | 24 ------ .../src/AnimationChannelJsonHandler.cpp | 24 ------ .../src/AnimationChannelTargetJsonHandler.cpp | 43 ---------- CesiumGltfReader/src/AnimationJsonHandler.cpp | 24 ------ .../src/AnimationSamplerJsonHandler.cpp | 43 ---------- CesiumGltfReader/src/ArrayJsonHandler.h | 31 ++++--- CesiumGltfReader/src/AssetJsonHandler.cpp | 26 ------ CesiumGltfReader/src/BoolJsonHandler.cpp | 4 +- CesiumGltfReader/src/BoolJsonHandler.h | 4 +- CesiumGltfReader/src/BufferJsonHandler.cpp | 24 ------ .../src/BufferViewJsonHandler.cpp | 27 ------- CesiumGltfReader/src/CameraJsonHandler.cpp | 42 ---------- .../src/CameraOrthographicJsonHandler.cpp | 26 ------ .../src/CameraPerspectiveJsonHandler.cpp | 26 ------ CesiumGltfReader/src/DictionaryJsonHandler.h | 11 ++- .../src/DoubleArrayJsonHandler.cpp | 33 -------- CesiumGltfReader/src/DoubleArrayJsonHandler.h | 18 ----- CesiumGltfReader/src/DoubleJsonHandler.cpp | 12 +-- CesiumGltfReader/src/DoubleJsonHandler.h | 12 +-- .../src/ExtensibleObjectJsonHandler.cpp | 4 +- .../src/ExtensibleObjectJsonHandler.h | 2 +- CesiumGltfReader/src/IJsonHandler.h | 27 +++++++ .../src/IgnoreValueJsonHandler.cpp | 41 ++++++---- CesiumGltfReader/src/IgnoreValueJsonHandler.h | 41 +++++----- CesiumGltfReader/src/ImageJsonHandler.cpp | 42 ---------- CesiumGltfReader/src/IntegerJsonHandler.h | 17 ++-- CesiumGltfReader/src/JsonHandler.cpp | 80 +++++++++++++------ CesiumGltfReader/src/JsonHandler.h | 57 +++++++------ CesiumGltfReader/src/MaterialJsonHandler.cpp | 48 ----------- .../MaterialNormalTextureInfoJsonHandler.cpp | 23 ------ ...aterialOcclusionTextureInfoJsonHandler.cpp | 23 ------ ...aterialPBRMetallicRoughnessJsonHandler.cpp | 27 ------- CesiumGltfReader/src/MeshJsonHandler.cpp | 24 ------ .../src/MeshPrimitiveJsonHandler.cpp | 27 ------- CesiumGltfReader/src/ModelJsonHandler.cpp | 39 --------- .../src/NamedObjectJsonHandler.cpp | 4 +- CesiumGltfReader/src/NamedObjectJsonHandler.h | 2 +- CesiumGltfReader/src/NodeJsonHandler.cpp | 31 ------- CesiumGltfReader/src/ObjectJsonHandler.cpp | 15 ++-- CesiumGltfReader/src/ObjectJsonHandler.h | 22 +++-- CesiumGltfReader/src/Reader.cpp | 38 +++++++-- CesiumGltfReader/src/RejectAllJsonHandler.h | 10 --- CesiumGltfReader/src/SamplerJsonHandler.cpp | 26 ------ CesiumGltfReader/src/SceneJsonHandler.cpp | 23 ------ CesiumGltfReader/src/SkinJsonHandler.cpp | 25 ------ CesiumGltfReader/src/StringJsonHandler.cpp | 8 +- CesiumGltfReader/src/StringJsonHandler.h | 5 +- .../src/TextureInfoJsonHandler.cpp | 24 ------ CesiumGltfReader/src/TextureJsonHandler.cpp | 24 ------ tools/generate-gltf-classes/generate.js | 26 ++++-- .../generate-gltf-classes/resolveProperty.js | 8 +- 112 files changed, 1612 insertions(+), 1129 deletions(-) create mode 100644 CesiumGltfReader/generated/AccessorJsonHandler.cpp rename CesiumGltfReader/{src => generated}/AccessorJsonHandler.h (68%) create mode 100644 CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp rename CesiumGltfReader/{src => generated}/AccessorSparseIndicesJsonHandler.h (64%) create mode 100644 CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp rename CesiumGltfReader/{src => generated}/AccessorSparseJsonHandler.h (64%) create mode 100644 CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp rename CesiumGltfReader/{src => generated}/AccessorSparseValuesJsonHandler.h (58%) create mode 100644 CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp rename CesiumGltfReader/{src => generated}/AnimationChannelJsonHandler.h (60%) create mode 100644 CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp rename CesiumGltfReader/{src => generated}/AnimationChannelTargetJsonHandler.h (55%) create mode 100644 CesiumGltfReader/generated/AnimationJsonHandler.cpp rename CesiumGltfReader/{src => generated}/AnimationJsonHandler.h (64%) create mode 100644 CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp rename CesiumGltfReader/{src => generated}/AnimationSamplerJsonHandler.h (58%) create mode 100644 CesiumGltfReader/generated/AssetJsonHandler.cpp rename CesiumGltfReader/{src => generated}/AssetJsonHandler.h (60%) create mode 100644 CesiumGltfReader/generated/BufferJsonHandler.cpp rename CesiumGltfReader/{src => generated}/BufferJsonHandler.h (58%) create mode 100644 CesiumGltfReader/generated/BufferViewJsonHandler.cpp rename CesiumGltfReader/{src => generated}/BufferViewJsonHandler.h (65%) create mode 100644 CesiumGltfReader/generated/CameraJsonHandler.cpp rename CesiumGltfReader/{src => generated}/CameraJsonHandler.h (59%) create mode 100644 CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp rename CesiumGltfReader/{src => generated}/CameraOrthographicJsonHandler.h (59%) create mode 100644 CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp rename CesiumGltfReader/{src => generated}/CameraPerspectiveJsonHandler.h (60%) create mode 100644 CesiumGltfReader/generated/ImageJsonHandler.cpp rename CesiumGltfReader/{src => generated}/ImageJsonHandler.h (57%) create mode 100644 CesiumGltfReader/generated/MaterialJsonHandler.cpp rename CesiumGltfReader/{src => generated}/MaterialJsonHandler.h (71%) create mode 100644 CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp rename CesiumGltfReader/{src => generated}/MaterialNormalTextureInfoJsonHandler.h (55%) create mode 100644 CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp rename CesiumGltfReader/{src => generated}/MaterialOcclusionTextureInfoJsonHandler.h (55%) create mode 100644 CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp rename CesiumGltfReader/{src => generated}/MaterialPBRMetallicRoughnessJsonHandler.h (67%) create mode 100644 CesiumGltfReader/generated/MeshJsonHandler.cpp rename CesiumGltfReader/{src => generated}/MeshJsonHandler.h (63%) create mode 100644 CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp rename CesiumGltfReader/{src => generated}/MeshPrimitiveJsonHandler.h (71%) create mode 100644 CesiumGltfReader/generated/ModelJsonHandler.cpp rename CesiumGltfReader/{src => generated}/ModelJsonHandler.h (85%) create mode 100644 CesiumGltfReader/generated/NodeJsonHandler.cpp rename CesiumGltfReader/{src => generated}/NodeJsonHandler.h (74%) create mode 100644 CesiumGltfReader/generated/SamplerJsonHandler.cpp rename CesiumGltfReader/{src => generated}/SamplerJsonHandler.h (64%) create mode 100644 CesiumGltfReader/generated/SceneJsonHandler.cpp rename CesiumGltfReader/{src => generated}/SceneJsonHandler.h (58%) create mode 100644 CesiumGltfReader/generated/SkinJsonHandler.cpp rename CesiumGltfReader/{src => generated}/SkinJsonHandler.h (63%) create mode 100644 CesiumGltfReader/generated/TextureInfoJsonHandler.cpp rename CesiumGltfReader/{src => generated}/TextureInfoJsonHandler.h (58%) create mode 100644 CesiumGltfReader/generated/TextureJsonHandler.cpp rename CesiumGltfReader/{src => generated}/TextureJsonHandler.h (57%) delete mode 100644 CesiumGltfReader/src/AccessorJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AccessorSparseJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AccessorSparseValuesJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AnimationChannelJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AnimationChannelTargetJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AnimationJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AnimationSamplerJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/AssetJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/BufferJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/BufferViewJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/CameraJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/CameraOrthographicJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/CameraPerspectiveJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/DoubleArrayJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/DoubleArrayJsonHandler.h create mode 100644 CesiumGltfReader/src/IJsonHandler.h delete mode 100644 CesiumGltfReader/src/ImageJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/MaterialJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/MeshJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/MeshPrimitiveJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/ModelJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/NodeJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/RejectAllJsonHandler.h delete mode 100644 CesiumGltfReader/src/SamplerJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/SceneJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/SkinJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/TextureInfoJsonHandler.cpp delete mode 100644 CesiumGltfReader/src/TextureJsonHandler.cpp diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index eaa3bc888..220242b66 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -13,7 +13,7 @@ TEST_CASE("GltfModel") { "{"s + " \"accessors\": ["s + " {"s + - " \"count\": 4,"s + + " \"count\": 4.0,"s + //{\"test\":true},"s + " \"componentType\":5121,"s + " \"type\":\"VEC2\","s + " \"max\":[1.0, 2.2, 3.3],"s + diff --git a/CesiumGltfReader/CMakeLists.txt b/CesiumGltfReader/CMakeLists.txt index 9af4d6105..52c99223c 100644 --- a/CesiumGltfReader/CMakeLists.txt +++ b/CesiumGltfReader/CMakeLists.txt @@ -2,7 +2,7 @@ add_library(CesiumGltfReader "") configure_cesium_library(CesiumGltfReader) -file(GLOB SOURCES include/CesiumGltf/*.h src/*.cpp src/*.h) +file(GLOB SOURCES include/CesiumGltf/*.h src/*.cpp src/*.h generated/*.cpp generated/*.h) file(GLOB PUBLIC_INCLUDES include/CesiumGltf/*.h) target_sources( @@ -21,6 +21,7 @@ target_include_directories( include PRIVATE src + generated ) target_link_libraries(CesiumGltfReader PUBLIC CesiumGltf) diff --git a/CesiumGltfReader/generated/AccessorJsonHandler.cpp b/CesiumGltfReader/generated/AccessorJsonHandler.cpp new file mode 100644 index 000000000..abee605eb --- /dev/null +++ b/CesiumGltfReader/generated/AccessorJsonHandler.cpp @@ -0,0 +1,64 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AccessorJsonHandler.h" +#include "CesiumGltf/Accessor.h" +#include +#include + +using namespace CesiumGltf; + +void AccessorJsonHandler::reset(IJsonHandler* pParent, Accessor* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Accessor* AccessorJsonHandler::getObject() { + return this->_pObject; +} + +void AccessorJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* AccessorJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("bufferView"s == str) return property("bufferView", this->_bufferView, this->_pObject->bufferView); + if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, this->_pObject->byteOffset); + if ("componentType"s == str) return property("componentType", this->_componentType, this->_pObject->componentType); + if ("normalized"s == str) return property("normalized", this->_normalized, this->_pObject->normalized); + if ("count"s == str) return property("count", this->_count, this->_pObject->count); + if ("type"s == str) return property("type", this->_type, this->_pObject->type); + if ("max"s == str) return property("max", this->_max, this->_pObject->max); + if ("min"s == str) return property("min", this->_min, this->_pObject->min); + if ("sparse"s == str) return property("sparse", this->_sparse, this->_pObject->sparse); + + return this->NamedObjectKey(str, *this->_pObject); +} + +void AccessorJsonHandler::TypeJsonHandler::reset(IJsonHandler* pParent, Accessor::Type* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +IJsonHandler* AccessorJsonHandler::TypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("SCALAR"s == str) *this->_pEnum = Accessor::Type::SCALAR; + else if ("VEC2"s == str) *this->_pEnum = Accessor::Type::VEC2; + else if ("VEC3"s == str) *this->_pEnum = Accessor::Type::VEC3; + else if ("VEC4"s == str) *this->_pEnum = Accessor::Type::VEC4; + else if ("MAT2"s == str) *this->_pEnum = Accessor::Type::MAT2; + else if ("MAT3"s == str) *this->_pEnum = Accessor::Type::MAT3; + else if ("MAT4"s == str) *this->_pEnum = Accessor::Type::MAT4; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/AccessorJsonHandler.h b/CesiumGltfReader/generated/AccessorJsonHandler.h similarity index 68% rename from CesiumGltfReader/src/AccessorJsonHandler.h rename to CesiumGltfReader/generated/AccessorJsonHandler.h index f105a5821..7f52c7770 100644 --- a/CesiumGltfReader/src/AccessorJsonHandler.h +++ b/CesiumGltfReader/generated/AccessorJsonHandler.h @@ -15,14 +15,17 @@ namespace CesiumGltf { class AccessorJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Accessor* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Accessor* pObject); + Accessor* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: class TypeJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, Accessor::Type* pEnum); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pParent, Accessor::Type* pEnum); + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; private: Accessor::Type* _pEnum = nullptr; diff --git a/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp new file mode 100644 index 000000000..d46c99f0b --- /dev/null +++ b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp @@ -0,0 +1,36 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AccessorSparseIndicesJsonHandler.h" +#include "CesiumGltf/AccessorSparseIndices.h" +#include +#include + +using namespace CesiumGltf; + +void AccessorSparseIndicesJsonHandler::reset(IJsonHandler* pParent, AccessorSparseIndices* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +AccessorSparseIndices* AccessorSparseIndicesJsonHandler::getObject() { + return this->_pObject; +} + +void AccessorSparseIndicesJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* AccessorSparseIndicesJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("bufferView"s == str) return property("bufferView", this->_bufferView, this->_pObject->bufferView); + if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, this->_pObject->byteOffset); + if ("componentType"s == str) return property("componentType", this->_componentType, this->_pObject->componentType); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.h b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.h similarity index 64% rename from CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.h rename to CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.h index bfd9768dd..d6322f626 100644 --- a/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.h +++ b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.h @@ -11,8 +11,11 @@ namespace CesiumGltf { class AccessorSparseIndicesJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, AccessorSparseIndices* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, AccessorSparseIndices* pObject); + AccessorSparseIndices* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp b/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp new file mode 100644 index 000000000..9b7aa05a8 --- /dev/null +++ b/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp @@ -0,0 +1,36 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AccessorSparseJsonHandler.h" +#include "CesiumGltf/AccessorSparse.h" +#include +#include + +using namespace CesiumGltf; + +void AccessorSparseJsonHandler::reset(IJsonHandler* pParent, AccessorSparse* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +AccessorSparse* AccessorSparseJsonHandler::getObject() { + return this->_pObject; +} + +void AccessorSparseJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* AccessorSparseJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("count"s == str) return property("count", this->_count, this->_pObject->count); + if ("indices"s == str) return property("indices", this->_indices, this->_pObject->indices); + if ("values"s == str) return property("values", this->_values, this->_pObject->values); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AccessorSparseJsonHandler.h b/CesiumGltfReader/generated/AccessorSparseJsonHandler.h similarity index 64% rename from CesiumGltfReader/src/AccessorSparseJsonHandler.h rename to CesiumGltfReader/generated/AccessorSparseJsonHandler.h index c10685817..062834bcd 100644 --- a/CesiumGltfReader/src/AccessorSparseJsonHandler.h +++ b/CesiumGltfReader/generated/AccessorSparseJsonHandler.h @@ -12,8 +12,11 @@ namespace CesiumGltf { class AccessorSparseJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, AccessorSparse* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, AccessorSparse* pObject); + AccessorSparse* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp new file mode 100644 index 000000000..06ac8a665 --- /dev/null +++ b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp @@ -0,0 +1,35 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AccessorSparseValuesJsonHandler.h" +#include "CesiumGltf/AccessorSparseValues.h" +#include +#include + +using namespace CesiumGltf; + +void AccessorSparseValuesJsonHandler::reset(IJsonHandler* pParent, AccessorSparseValues* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +AccessorSparseValues* AccessorSparseValuesJsonHandler::getObject() { + return this->_pObject; +} + +void AccessorSparseValuesJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* AccessorSparseValuesJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("bufferView"s == str) return property("bufferView", this->_bufferView, this->_pObject->bufferView); + if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, this->_pObject->byteOffset); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.h b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.h similarity index 58% rename from CesiumGltfReader/src/AccessorSparseValuesJsonHandler.h rename to CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.h index 562c86389..7856e490e 100644 --- a/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.h +++ b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.h @@ -10,8 +10,11 @@ namespace CesiumGltf { class AccessorSparseValuesJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, AccessorSparseValues* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, AccessorSparseValues* pObject); + AccessorSparseValues* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp b/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp new file mode 100644 index 000000000..c5e4f3948 --- /dev/null +++ b/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp @@ -0,0 +1,35 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AnimationChannelJsonHandler.h" +#include "CesiumGltf/AnimationChannel.h" +#include +#include + +using namespace CesiumGltf; + +void AnimationChannelJsonHandler::reset(IJsonHandler* pParent, AnimationChannel* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +AnimationChannel* AnimationChannelJsonHandler::getObject() { + return this->_pObject; +} + +void AnimationChannelJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* AnimationChannelJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("sampler"s == str) return property("sampler", this->_sampler, this->_pObject->sampler); + if ("target"s == str) return property("target", this->_target, this->_pObject->target); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AnimationChannelJsonHandler.h b/CesiumGltfReader/generated/AnimationChannelJsonHandler.h similarity index 60% rename from CesiumGltfReader/src/AnimationChannelJsonHandler.h rename to CesiumGltfReader/generated/AnimationChannelJsonHandler.h index eaa02b00b..e33eb7a66 100644 --- a/CesiumGltfReader/src/AnimationChannelJsonHandler.h +++ b/CesiumGltfReader/generated/AnimationChannelJsonHandler.h @@ -11,8 +11,11 @@ namespace CesiumGltf { class AnimationChannelJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, AnimationChannel* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, AnimationChannel* pObject); + AnimationChannel* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp new file mode 100644 index 000000000..49c28e0be --- /dev/null +++ b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp @@ -0,0 +1,54 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AnimationChannelTargetJsonHandler.h" +#include "CesiumGltf/AnimationChannelTarget.h" +#include +#include + +using namespace CesiumGltf; + +void AnimationChannelTargetJsonHandler::reset(IJsonHandler* pParent, AnimationChannelTarget* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +AnimationChannelTarget* AnimationChannelTargetJsonHandler::getObject() { + return this->_pObject; +} + +void AnimationChannelTargetJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* AnimationChannelTargetJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("node"s == str) return property("node", this->_node, this->_pObject->node); + if ("path"s == str) return property("path", this->_path, this->_pObject->path); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} + +void AnimationChannelTargetJsonHandler::PathJsonHandler::reset(IJsonHandler* pParent, AnimationChannelTarget::Path* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +IJsonHandler* AnimationChannelTargetJsonHandler::PathJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("translation"s == str) *this->_pEnum = AnimationChannelTarget::Path::translation; + else if ("rotation"s == str) *this->_pEnum = AnimationChannelTarget::Path::rotation; + else if ("scale"s == str) *this->_pEnum = AnimationChannelTarget::Path::scale; + else if ("weights"s == str) *this->_pEnum = AnimationChannelTarget::Path::weights; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.h b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.h similarity index 55% rename from CesiumGltfReader/src/AnimationChannelTargetJsonHandler.h rename to CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.h index 5495926bf..4a48c2ca3 100644 --- a/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.h +++ b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.h @@ -11,14 +11,17 @@ namespace CesiumGltf { class AnimationChannelTargetJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, AnimationChannelTarget* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, AnimationChannelTarget* pObject); + AnimationChannelTarget* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: class PathJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, AnimationChannelTarget::Path* pEnum); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pParent, AnimationChannelTarget::Path* pEnum); + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; private: AnimationChannelTarget::Path* _pEnum = nullptr; diff --git a/CesiumGltfReader/generated/AnimationJsonHandler.cpp b/CesiumGltfReader/generated/AnimationJsonHandler.cpp new file mode 100644 index 000000000..3f3c87099 --- /dev/null +++ b/CesiumGltfReader/generated/AnimationJsonHandler.cpp @@ -0,0 +1,35 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AnimationJsonHandler.h" +#include "CesiumGltf/Animation.h" +#include +#include + +using namespace CesiumGltf; + +void AnimationJsonHandler::reset(IJsonHandler* pParent, Animation* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Animation* AnimationJsonHandler::getObject() { + return this->_pObject; +} + +void AnimationJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* AnimationJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("channels"s == str) return property("channels", this->_channels, this->_pObject->channels); + if ("samplers"s == str) return property("samplers", this->_samplers, this->_pObject->samplers); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AnimationJsonHandler.h b/CesiumGltfReader/generated/AnimationJsonHandler.h similarity index 64% rename from CesiumGltfReader/src/AnimationJsonHandler.h rename to CesiumGltfReader/generated/AnimationJsonHandler.h index c536562df..a6783411f 100644 --- a/CesiumGltfReader/src/AnimationJsonHandler.h +++ b/CesiumGltfReader/generated/AnimationJsonHandler.h @@ -12,8 +12,11 @@ namespace CesiumGltf { class AnimationJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Animation* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Animation* pObject); + Animation* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp new file mode 100644 index 000000000..0d2306d7e --- /dev/null +++ b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp @@ -0,0 +1,54 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AnimationSamplerJsonHandler.h" +#include "CesiumGltf/AnimationSampler.h" +#include +#include + +using namespace CesiumGltf; + +void AnimationSamplerJsonHandler::reset(IJsonHandler* pParent, AnimationSampler* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +AnimationSampler* AnimationSamplerJsonHandler::getObject() { + return this->_pObject; +} + +void AnimationSamplerJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* AnimationSamplerJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("input"s == str) return property("input", this->_input, this->_pObject->input); + if ("interpolation"s == str) return property("interpolation", this->_interpolation, this->_pObject->interpolation); + if ("output"s == str) return property("output", this->_output, this->_pObject->output); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} + +void AnimationSamplerJsonHandler::InterpolationJsonHandler::reset(IJsonHandler* pParent, AnimationSampler::Interpolation* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +IJsonHandler* AnimationSamplerJsonHandler::InterpolationJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("LINEAR"s == str) *this->_pEnum = AnimationSampler::Interpolation::LINEAR; + else if ("STEP"s == str) *this->_pEnum = AnimationSampler::Interpolation::STEP; + else if ("CUBICSPLINE"s == str) *this->_pEnum = AnimationSampler::Interpolation::CUBICSPLINE; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/AnimationSamplerJsonHandler.h b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.h similarity index 58% rename from CesiumGltfReader/src/AnimationSamplerJsonHandler.h rename to CesiumGltfReader/generated/AnimationSamplerJsonHandler.h index efccba2ca..963c9bea2 100644 --- a/CesiumGltfReader/src/AnimationSamplerJsonHandler.h +++ b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.h @@ -11,14 +11,17 @@ namespace CesiumGltf { class AnimationSamplerJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, AnimationSampler* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, AnimationSampler* pObject); + AnimationSampler* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: class InterpolationJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, AnimationSampler::Interpolation* pEnum); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pParent, AnimationSampler::Interpolation* pEnum); + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; private: AnimationSampler::Interpolation* _pEnum = nullptr; diff --git a/CesiumGltfReader/generated/AssetJsonHandler.cpp b/CesiumGltfReader/generated/AssetJsonHandler.cpp new file mode 100644 index 000000000..1baffe8a5 --- /dev/null +++ b/CesiumGltfReader/generated/AssetJsonHandler.cpp @@ -0,0 +1,37 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "AssetJsonHandler.h" +#include "CesiumGltf/Asset.h" +#include +#include + +using namespace CesiumGltf; + +void AssetJsonHandler::reset(IJsonHandler* pParent, Asset* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Asset* AssetJsonHandler::getObject() { + return this->_pObject; +} + +void AssetJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* AssetJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("copyright"s == str) return property("copyright", this->_copyright, this->_pObject->copyright); + if ("generator"s == str) return property("generator", this->_generator, this->_pObject->generator); + if ("version"s == str) return property("version", this->_version, this->_pObject->version); + if ("minVersion"s == str) return property("minVersion", this->_minVersion, this->_pObject->minVersion); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/AssetJsonHandler.h b/CesiumGltfReader/generated/AssetJsonHandler.h similarity index 60% rename from CesiumGltfReader/src/AssetJsonHandler.h rename to CesiumGltfReader/generated/AssetJsonHandler.h index 0c271578d..bcf0af477 100644 --- a/CesiumGltfReader/src/AssetJsonHandler.h +++ b/CesiumGltfReader/generated/AssetJsonHandler.h @@ -10,8 +10,11 @@ namespace CesiumGltf { class AssetJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Asset* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Asset* pObject); + Asset* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/BufferJsonHandler.cpp b/CesiumGltfReader/generated/BufferJsonHandler.cpp new file mode 100644 index 000000000..9096fe5ed --- /dev/null +++ b/CesiumGltfReader/generated/BufferJsonHandler.cpp @@ -0,0 +1,35 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "BufferJsonHandler.h" +#include "CesiumGltf/Buffer.h" +#include +#include + +using namespace CesiumGltf; + +void BufferJsonHandler::reset(IJsonHandler* pParent, Buffer* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Buffer* BufferJsonHandler::getObject() { + return this->_pObject; +} + +void BufferJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* BufferJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("uri"s == str) return property("uri", this->_uri, this->_pObject->uri); + if ("byteLength"s == str) return property("byteLength", this->_byteLength, this->_pObject->byteLength); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/BufferJsonHandler.h b/CesiumGltfReader/generated/BufferJsonHandler.h similarity index 58% rename from CesiumGltfReader/src/BufferJsonHandler.h rename to CesiumGltfReader/generated/BufferJsonHandler.h index 8b15fd1a2..2446c05d7 100644 --- a/CesiumGltfReader/src/BufferJsonHandler.h +++ b/CesiumGltfReader/generated/BufferJsonHandler.h @@ -11,8 +11,11 @@ namespace CesiumGltf { class BufferJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Buffer* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Buffer* pObject); + Buffer* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/BufferViewJsonHandler.cpp b/CesiumGltfReader/generated/BufferViewJsonHandler.cpp new file mode 100644 index 000000000..a7ef76f75 --- /dev/null +++ b/CesiumGltfReader/generated/BufferViewJsonHandler.cpp @@ -0,0 +1,38 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "BufferViewJsonHandler.h" +#include "CesiumGltf/BufferView.h" +#include +#include + +using namespace CesiumGltf; + +void BufferViewJsonHandler::reset(IJsonHandler* pParent, BufferView* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +BufferView* BufferViewJsonHandler::getObject() { + return this->_pObject; +} + +void BufferViewJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* BufferViewJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("buffer"s == str) return property("buffer", this->_buffer, this->_pObject->buffer); + if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, this->_pObject->byteOffset); + if ("byteLength"s == str) return property("byteLength", this->_byteLength, this->_pObject->byteLength); + if ("byteStride"s == str) return property("byteStride", this->_byteStride, this->_pObject->byteStride); + if ("target"s == str) return property("target", this->_target, this->_pObject->target); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/BufferViewJsonHandler.h b/CesiumGltfReader/generated/BufferViewJsonHandler.h similarity index 65% rename from CesiumGltfReader/src/BufferViewJsonHandler.h rename to CesiumGltfReader/generated/BufferViewJsonHandler.h index 56e7acb9c..df515eaa3 100644 --- a/CesiumGltfReader/src/BufferViewJsonHandler.h +++ b/CesiumGltfReader/generated/BufferViewJsonHandler.h @@ -11,8 +11,11 @@ namespace CesiumGltf { class BufferViewJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, BufferView* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, BufferView* pObject); + BufferView* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/CameraJsonHandler.cpp b/CesiumGltfReader/generated/CameraJsonHandler.cpp new file mode 100644 index 000000000..38d9cc9a5 --- /dev/null +++ b/CesiumGltfReader/generated/CameraJsonHandler.cpp @@ -0,0 +1,53 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "CameraJsonHandler.h" +#include "CesiumGltf/Camera.h" +#include +#include + +using namespace CesiumGltf; + +void CameraJsonHandler::reset(IJsonHandler* pParent, Camera* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Camera* CameraJsonHandler::getObject() { + return this->_pObject; +} + +void CameraJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* CameraJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("orthographic"s == str) return property("orthographic", this->_orthographic, this->_pObject->orthographic); + if ("perspective"s == str) return property("perspective", this->_perspective, this->_pObject->perspective); + if ("type"s == str) return property("type", this->_type, this->_pObject->type); + + return this->NamedObjectKey(str, *this->_pObject); +} + +void CameraJsonHandler::TypeJsonHandler::reset(IJsonHandler* pParent, Camera::Type* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +IJsonHandler* CameraJsonHandler::TypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("perspective"s == str) *this->_pEnum = Camera::Type::perspective; + else if ("orthographic"s == str) *this->_pEnum = Camera::Type::orthographic; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/CameraJsonHandler.h b/CesiumGltfReader/generated/CameraJsonHandler.h similarity index 59% rename from CesiumGltfReader/src/CameraJsonHandler.h rename to CesiumGltfReader/generated/CameraJsonHandler.h index ad06d569f..eb09810d5 100644 --- a/CesiumGltfReader/src/CameraJsonHandler.h +++ b/CesiumGltfReader/generated/CameraJsonHandler.h @@ -12,14 +12,17 @@ namespace CesiumGltf { class CameraJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Camera* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Camera* pObject); + Camera* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: class TypeJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, Camera::Type* pEnum); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pParent, Camera::Type* pEnum); + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; private: Camera::Type* _pEnum = nullptr; diff --git a/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp new file mode 100644 index 000000000..47b8e7113 --- /dev/null +++ b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp @@ -0,0 +1,37 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "CameraOrthographicJsonHandler.h" +#include "CesiumGltf/CameraOrthographic.h" +#include +#include + +using namespace CesiumGltf; + +void CameraOrthographicJsonHandler::reset(IJsonHandler* pParent, CameraOrthographic* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +CameraOrthographic* CameraOrthographicJsonHandler::getObject() { + return this->_pObject; +} + +void CameraOrthographicJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* CameraOrthographicJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("xmag"s == str) return property("xmag", this->_xmag, this->_pObject->xmag); + if ("ymag"s == str) return property("ymag", this->_ymag, this->_pObject->ymag); + if ("zfar"s == str) return property("zfar", this->_zfar, this->_pObject->zfar); + if ("znear"s == str) return property("znear", this->_znear, this->_pObject->znear); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/CameraOrthographicJsonHandler.h b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.h similarity index 59% rename from CesiumGltfReader/src/CameraOrthographicJsonHandler.h rename to CesiumGltfReader/generated/CameraOrthographicJsonHandler.h index 8ac746d76..8e4c09a28 100644 --- a/CesiumGltfReader/src/CameraOrthographicJsonHandler.h +++ b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.h @@ -10,8 +10,11 @@ namespace CesiumGltf { class CameraOrthographicJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, CameraOrthographic* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, CameraOrthographic* pObject); + CameraOrthographic* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp new file mode 100644 index 000000000..40fd48ee6 --- /dev/null +++ b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp @@ -0,0 +1,37 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "CameraPerspectiveJsonHandler.h" +#include "CesiumGltf/CameraPerspective.h" +#include +#include + +using namespace CesiumGltf; + +void CameraPerspectiveJsonHandler::reset(IJsonHandler* pParent, CameraPerspective* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +CameraPerspective* CameraPerspectiveJsonHandler::getObject() { + return this->_pObject; +} + +void CameraPerspectiveJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* CameraPerspectiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("aspectRatio"s == str) return property("aspectRatio", this->_aspectRatio, this->_pObject->aspectRatio); + if ("yfov"s == str) return property("yfov", this->_yfov, this->_pObject->yfov); + if ("zfar"s == str) return property("zfar", this->_zfar, this->_pObject->zfar); + if ("znear"s == str) return property("znear", this->_znear, this->_pObject->znear); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/CameraPerspectiveJsonHandler.h b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.h similarity index 60% rename from CesiumGltfReader/src/CameraPerspectiveJsonHandler.h rename to CesiumGltfReader/generated/CameraPerspectiveJsonHandler.h index 6927ee46e..d72a0c8df 100644 --- a/CesiumGltfReader/src/CameraPerspectiveJsonHandler.h +++ b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.h @@ -10,8 +10,11 @@ namespace CesiumGltf { class CameraPerspectiveJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, CameraPerspective* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, CameraPerspective* pObject); + CameraPerspective* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/ImageJsonHandler.cpp b/CesiumGltfReader/generated/ImageJsonHandler.cpp new file mode 100644 index 000000000..67fd1bcff --- /dev/null +++ b/CesiumGltfReader/generated/ImageJsonHandler.cpp @@ -0,0 +1,53 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "ImageJsonHandler.h" +#include "CesiumGltf/Image.h" +#include +#include + +using namespace CesiumGltf; + +void ImageJsonHandler::reset(IJsonHandler* pParent, Image* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Image* ImageJsonHandler::getObject() { + return this->_pObject; +} + +void ImageJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* ImageJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("uri"s == str) return property("uri", this->_uri, this->_pObject->uri); + if ("mimeType"s == str) return property("mimeType", this->_mimeType, this->_pObject->mimeType); + if ("bufferView"s == str) return property("bufferView", this->_bufferView, this->_pObject->bufferView); + + return this->NamedObjectKey(str, *this->_pObject); +} + +void ImageJsonHandler::MimeTypeJsonHandler::reset(IJsonHandler* pParent, Image::MimeType* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +IJsonHandler* ImageJsonHandler::MimeTypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("image/jpeg"s == str) *this->_pEnum = Image::MimeType::image_jpeg; + else if ("image/png"s == str) *this->_pEnum = Image::MimeType::image_png; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/ImageJsonHandler.h b/CesiumGltfReader/generated/ImageJsonHandler.h similarity index 57% rename from CesiumGltfReader/src/ImageJsonHandler.h rename to CesiumGltfReader/generated/ImageJsonHandler.h index 89b9b6b41..b8803a4f1 100644 --- a/CesiumGltfReader/src/ImageJsonHandler.h +++ b/CesiumGltfReader/generated/ImageJsonHandler.h @@ -12,14 +12,17 @@ namespace CesiumGltf { class ImageJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Image* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Image* pObject); + Image* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: class MimeTypeJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, Image::MimeType* pEnum); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pParent, Image::MimeType* pEnum); + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; private: Image::MimeType* _pEnum = nullptr; diff --git a/CesiumGltfReader/generated/MaterialJsonHandler.cpp b/CesiumGltfReader/generated/MaterialJsonHandler.cpp new file mode 100644 index 000000000..30edac81a --- /dev/null +++ b/CesiumGltfReader/generated/MaterialJsonHandler.cpp @@ -0,0 +1,59 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MaterialJsonHandler.h" +#include "CesiumGltf/Material.h" +#include +#include + +using namespace CesiumGltf; + +void MaterialJsonHandler::reset(IJsonHandler* pParent, Material* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Material* MaterialJsonHandler::getObject() { + return this->_pObject; +} + +void MaterialJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* MaterialJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("pbrMetallicRoughness"s == str) return property("pbrMetallicRoughness", this->_pbrMetallicRoughness, this->_pObject->pbrMetallicRoughness); + if ("normalTexture"s == str) return property("normalTexture", this->_normalTexture, this->_pObject->normalTexture); + if ("occlusionTexture"s == str) return property("occlusionTexture", this->_occlusionTexture, this->_pObject->occlusionTexture); + if ("emissiveTexture"s == str) return property("emissiveTexture", this->_emissiveTexture, this->_pObject->emissiveTexture); + if ("emissiveFactor"s == str) return property("emissiveFactor", this->_emissiveFactor, this->_pObject->emissiveFactor); + if ("alphaMode"s == str) return property("alphaMode", this->_alphaMode, this->_pObject->alphaMode); + if ("alphaCutoff"s == str) return property("alphaCutoff", this->_alphaCutoff, this->_pObject->alphaCutoff); + if ("doubleSided"s == str) return property("doubleSided", this->_doubleSided, this->_pObject->doubleSided); + + return this->NamedObjectKey(str, *this->_pObject); +} + +void MaterialJsonHandler::AlphaModeJsonHandler::reset(IJsonHandler* pParent, Material::AlphaMode* pEnum) { + JsonHandler::reset(pParent); + this->_pEnum = pEnum; +} + +IJsonHandler* MaterialJsonHandler::AlphaModeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pEnum); + + if ("OPAQUE"s == str) *this->_pEnum = Material::AlphaMode::OPAQUE; + else if ("MASK"s == str) *this->_pEnum = Material::AlphaMode::MASK; + else if ("BLEND"s == str) *this->_pEnum = Material::AlphaMode::BLEND; + else return nullptr; + + return this->parent(); +} diff --git a/CesiumGltfReader/src/MaterialJsonHandler.h b/CesiumGltfReader/generated/MaterialJsonHandler.h similarity index 71% rename from CesiumGltfReader/src/MaterialJsonHandler.h rename to CesiumGltfReader/generated/MaterialJsonHandler.h index 5881795cf..2525d7a49 100644 --- a/CesiumGltfReader/src/MaterialJsonHandler.h +++ b/CesiumGltfReader/generated/MaterialJsonHandler.h @@ -17,14 +17,17 @@ namespace CesiumGltf { class MaterialJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Material* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Material* pObject); + Material* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: class AlphaModeJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, Material::AlphaMode* pEnum); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pParent, Material::AlphaMode* pEnum); + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; private: Material::AlphaMode* _pEnum = nullptr; diff --git a/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp new file mode 100644 index 000000000..e533e4b67 --- /dev/null +++ b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp @@ -0,0 +1,34 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MaterialNormalTextureInfoJsonHandler.h" +#include "CesiumGltf/MaterialNormalTextureInfo.h" +#include +#include + +using namespace CesiumGltf; + +void MaterialNormalTextureInfoJsonHandler::reset(IJsonHandler* pParent, MaterialNormalTextureInfo* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +MaterialNormalTextureInfo* MaterialNormalTextureInfoJsonHandler::getObject() { + return this->_pObject; +} + +void MaterialNormalTextureInfoJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* MaterialNormalTextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("scale"s == str) return property("scale", this->_scale, this->_pObject->scale); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.h b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.h similarity index 55% rename from CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.h rename to CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.h index 7e6eddb7c..718acd19d 100644 --- a/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.h +++ b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.h @@ -10,8 +10,11 @@ namespace CesiumGltf { class MaterialNormalTextureInfoJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, MaterialNormalTextureInfo* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, MaterialNormalTextureInfo* pObject); + MaterialNormalTextureInfo* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp new file mode 100644 index 000000000..f8b986f15 --- /dev/null +++ b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp @@ -0,0 +1,34 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MaterialOcclusionTextureInfoJsonHandler.h" +#include "CesiumGltf/MaterialOcclusionTextureInfo.h" +#include +#include + +using namespace CesiumGltf; + +void MaterialOcclusionTextureInfoJsonHandler::reset(IJsonHandler* pParent, MaterialOcclusionTextureInfo* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +MaterialOcclusionTextureInfo* MaterialOcclusionTextureInfoJsonHandler::getObject() { + return this->_pObject; +} + +void MaterialOcclusionTextureInfoJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* MaterialOcclusionTextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("strength"s == str) return property("strength", this->_strength, this->_pObject->strength); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.h b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.h similarity index 55% rename from CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.h rename to CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.h index 46aeed7db..ddb42adce 100644 --- a/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.h +++ b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.h @@ -10,8 +10,11 @@ namespace CesiumGltf { class MaterialOcclusionTextureInfoJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, MaterialOcclusionTextureInfo* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, MaterialOcclusionTextureInfo* pObject); + MaterialOcclusionTextureInfo* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp new file mode 100644 index 000000000..75f2200a5 --- /dev/null +++ b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp @@ -0,0 +1,38 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MaterialPBRMetallicRoughnessJsonHandler.h" +#include "CesiumGltf/MaterialPBRMetallicRoughness.h" +#include +#include + +using namespace CesiumGltf; + +void MaterialPBRMetallicRoughnessJsonHandler::reset(IJsonHandler* pParent, MaterialPBRMetallicRoughness* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +MaterialPBRMetallicRoughness* MaterialPBRMetallicRoughnessJsonHandler::getObject() { + return this->_pObject; +} + +void MaterialPBRMetallicRoughnessJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* MaterialPBRMetallicRoughnessJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("baseColorFactor"s == str) return property("baseColorFactor", this->_baseColorFactor, this->_pObject->baseColorFactor); + if ("baseColorTexture"s == str) return property("baseColorTexture", this->_baseColorTexture, this->_pObject->baseColorTexture); + if ("metallicFactor"s == str) return property("metallicFactor", this->_metallicFactor, this->_pObject->metallicFactor); + if ("roughnessFactor"s == str) return property("roughnessFactor", this->_roughnessFactor, this->_pObject->roughnessFactor); + if ("metallicRoughnessTexture"s == str) return property("metallicRoughnessTexture", this->_metallicRoughnessTexture, this->_pObject->metallicRoughnessTexture); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.h b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.h similarity index 67% rename from CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.h rename to CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.h index bd4ee86cf..f6c99d28c 100644 --- a/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.h +++ b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.h @@ -12,8 +12,11 @@ namespace CesiumGltf { class MaterialPBRMetallicRoughnessJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, MaterialPBRMetallicRoughness* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, MaterialPBRMetallicRoughness* pObject); + MaterialPBRMetallicRoughness* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/MeshJsonHandler.cpp b/CesiumGltfReader/generated/MeshJsonHandler.cpp new file mode 100644 index 000000000..f5a8537d9 --- /dev/null +++ b/CesiumGltfReader/generated/MeshJsonHandler.cpp @@ -0,0 +1,35 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MeshJsonHandler.h" +#include "CesiumGltf/Mesh.h" +#include +#include + +using namespace CesiumGltf; + +void MeshJsonHandler::reset(IJsonHandler* pParent, Mesh* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Mesh* MeshJsonHandler::getObject() { + return this->_pObject; +} + +void MeshJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* MeshJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("primitives"s == str) return property("primitives", this->_primitives, this->_pObject->primitives); + if ("weights"s == str) return property("weights", this->_weights, this->_pObject->weights); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/MeshJsonHandler.h b/CesiumGltfReader/generated/MeshJsonHandler.h similarity index 63% rename from CesiumGltfReader/src/MeshJsonHandler.h rename to CesiumGltfReader/generated/MeshJsonHandler.h index 557177c50..d517aa478 100644 --- a/CesiumGltfReader/src/MeshJsonHandler.h +++ b/CesiumGltfReader/generated/MeshJsonHandler.h @@ -12,8 +12,11 @@ namespace CesiumGltf { class MeshJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Mesh* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Mesh* pObject); + Mesh* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp new file mode 100644 index 000000000..f902dfb0d --- /dev/null +++ b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp @@ -0,0 +1,38 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "MeshPrimitiveJsonHandler.h" +#include "CesiumGltf/MeshPrimitive.h" +#include +#include + +using namespace CesiumGltf; + +void MeshPrimitiveJsonHandler::reset(IJsonHandler* pParent, MeshPrimitive* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +MeshPrimitive* MeshPrimitiveJsonHandler::getObject() { + return this->_pObject; +} + +void MeshPrimitiveJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* MeshPrimitiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("attributes"s == str) return property("attributes", this->_attributes, this->_pObject->attributes); + if ("indices"s == str) return property("indices", this->_indices, this->_pObject->indices); + if ("material"s == str) return property("material", this->_material, this->_pObject->material); + if ("mode"s == str) return property("mode", this->_mode, this->_pObject->mode); + if ("targets"s == str) return property("targets", this->_targets, this->_pObject->targets); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/MeshPrimitiveJsonHandler.h b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h similarity index 71% rename from CesiumGltfReader/src/MeshPrimitiveJsonHandler.h rename to CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h index 4faebaff6..8a6acaeba 100644 --- a/CesiumGltfReader/src/MeshPrimitiveJsonHandler.h +++ b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h @@ -13,8 +13,11 @@ namespace CesiumGltf { class MeshPrimitiveJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, MeshPrimitive* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, MeshPrimitive* pObject); + MeshPrimitive* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/ModelJsonHandler.cpp b/CesiumGltfReader/generated/ModelJsonHandler.cpp new file mode 100644 index 000000000..35909a4b1 --- /dev/null +++ b/CesiumGltfReader/generated/ModelJsonHandler.cpp @@ -0,0 +1,50 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "ModelJsonHandler.h" +#include "CesiumGltf/Model.h" +#include +#include + +using namespace CesiumGltf; + +void ModelJsonHandler::reset(IJsonHandler* pParent, Model* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Model* ModelJsonHandler::getObject() { + return this->_pObject; +} + +void ModelJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* ModelJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("extensionsUsed"s == str) return property("extensionsUsed", this->_extensionsUsed, this->_pObject->extensionsUsed); + if ("extensionsRequired"s == str) return property("extensionsRequired", this->_extensionsRequired, this->_pObject->extensionsRequired); + if ("accessors"s == str) return property("accessors", this->_accessors, this->_pObject->accessors); + if ("animations"s == str) return property("animations", this->_animations, this->_pObject->animations); + if ("asset"s == str) return property("asset", this->_asset, this->_pObject->asset); + if ("buffers"s == str) return property("buffers", this->_buffers, this->_pObject->buffers); + if ("bufferViews"s == str) return property("bufferViews", this->_bufferViews, this->_pObject->bufferViews); + if ("cameras"s == str) return property("cameras", this->_cameras, this->_pObject->cameras); + if ("images"s == str) return property("images", this->_images, this->_pObject->images); + if ("materials"s == str) return property("materials", this->_materials, this->_pObject->materials); + if ("meshes"s == str) return property("meshes", this->_meshes, this->_pObject->meshes); + if ("nodes"s == str) return property("nodes", this->_nodes, this->_pObject->nodes); + if ("samplers"s == str) return property("samplers", this->_samplers, this->_pObject->samplers); + if ("scene"s == str) return property("scene", this->_scene, this->_pObject->scene); + if ("scenes"s == str) return property("scenes", this->_scenes, this->_pObject->scenes); + if ("skins"s == str) return property("skins", this->_skins, this->_pObject->skins); + if ("textures"s == str) return property("textures", this->_textures, this->_pObject->textures); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/ModelJsonHandler.h b/CesiumGltfReader/generated/ModelJsonHandler.h similarity index 85% rename from CesiumGltfReader/src/ModelJsonHandler.h rename to CesiumGltfReader/generated/ModelJsonHandler.h index 3968f209a..fe3e3c6ec 100644 --- a/CesiumGltfReader/src/ModelJsonHandler.h +++ b/CesiumGltfReader/generated/ModelJsonHandler.h @@ -26,8 +26,11 @@ namespace CesiumGltf { class ModelJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Model* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Model* pObject); + Model* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/NodeJsonHandler.cpp b/CesiumGltfReader/generated/NodeJsonHandler.cpp new file mode 100644 index 000000000..3d730d707 --- /dev/null +++ b/CesiumGltfReader/generated/NodeJsonHandler.cpp @@ -0,0 +1,42 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "NodeJsonHandler.h" +#include "CesiumGltf/Node.h" +#include +#include + +using namespace CesiumGltf; + +void NodeJsonHandler::reset(IJsonHandler* pParent, Node* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Node* NodeJsonHandler::getObject() { + return this->_pObject; +} + +void NodeJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* NodeJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("camera"s == str) return property("camera", this->_camera, this->_pObject->camera); + if ("children"s == str) return property("children", this->_children, this->_pObject->children); + if ("skin"s == str) return property("skin", this->_skin, this->_pObject->skin); + if ("matrix"s == str) return property("matrix", this->_matrix, this->_pObject->matrix); + if ("mesh"s == str) return property("mesh", this->_mesh, this->_pObject->mesh); + if ("rotation"s == str) return property("rotation", this->_rotation, this->_pObject->rotation); + if ("scale"s == str) return property("scale", this->_scale, this->_pObject->scale); + if ("translation"s == str) return property("translation", this->_translation, this->_pObject->translation); + if ("weights"s == str) return property("weights", this->_weights, this->_pObject->weights); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/NodeJsonHandler.h b/CesiumGltfReader/generated/NodeJsonHandler.h similarity index 74% rename from CesiumGltfReader/src/NodeJsonHandler.h rename to CesiumGltfReader/generated/NodeJsonHandler.h index 5d070f5a1..57a2ff4c5 100644 --- a/CesiumGltfReader/src/NodeJsonHandler.h +++ b/CesiumGltfReader/generated/NodeJsonHandler.h @@ -12,8 +12,11 @@ namespace CesiumGltf { class NodeJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Node* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Node* pObject); + Node* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/SamplerJsonHandler.cpp b/CesiumGltfReader/generated/SamplerJsonHandler.cpp new file mode 100644 index 000000000..e6f88bd02 --- /dev/null +++ b/CesiumGltfReader/generated/SamplerJsonHandler.cpp @@ -0,0 +1,37 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "SamplerJsonHandler.h" +#include "CesiumGltf/Sampler.h" +#include +#include + +using namespace CesiumGltf; + +void SamplerJsonHandler::reset(IJsonHandler* pParent, Sampler* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Sampler* SamplerJsonHandler::getObject() { + return this->_pObject; +} + +void SamplerJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* SamplerJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("magFilter"s == str) return property("magFilter", this->_magFilter, this->_pObject->magFilter); + if ("minFilter"s == str) return property("minFilter", this->_minFilter, this->_pObject->minFilter); + if ("wrapS"s == str) return property("wrapS", this->_wrapS, this->_pObject->wrapS); + if ("wrapT"s == str) return property("wrapT", this->_wrapT, this->_pObject->wrapT); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/SamplerJsonHandler.h b/CesiumGltfReader/generated/SamplerJsonHandler.h similarity index 64% rename from CesiumGltfReader/src/SamplerJsonHandler.h rename to CesiumGltfReader/generated/SamplerJsonHandler.h index 7fb787432..5af8fa942 100644 --- a/CesiumGltfReader/src/SamplerJsonHandler.h +++ b/CesiumGltfReader/generated/SamplerJsonHandler.h @@ -11,8 +11,11 @@ namespace CesiumGltf { class SamplerJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Sampler* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Sampler* pObject); + Sampler* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/SceneJsonHandler.cpp b/CesiumGltfReader/generated/SceneJsonHandler.cpp new file mode 100644 index 000000000..8fe525d5d --- /dev/null +++ b/CesiumGltfReader/generated/SceneJsonHandler.cpp @@ -0,0 +1,34 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "SceneJsonHandler.h" +#include "CesiumGltf/Scene.h" +#include +#include + +using namespace CesiumGltf; + +void SceneJsonHandler::reset(IJsonHandler* pParent, Scene* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Scene* SceneJsonHandler::getObject() { + return this->_pObject; +} + +void SceneJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* SceneJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("nodes"s == str) return property("nodes", this->_nodes, this->_pObject->nodes); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/SceneJsonHandler.h b/CesiumGltfReader/generated/SceneJsonHandler.h similarity index 58% rename from CesiumGltfReader/src/SceneJsonHandler.h rename to CesiumGltfReader/generated/SceneJsonHandler.h index 2c0abafc7..c6b5514dc 100644 --- a/CesiumGltfReader/src/SceneJsonHandler.h +++ b/CesiumGltfReader/generated/SceneJsonHandler.h @@ -11,8 +11,11 @@ namespace CesiumGltf { class SceneJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Scene* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Scene* pObject); + Scene* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/SkinJsonHandler.cpp b/CesiumGltfReader/generated/SkinJsonHandler.cpp new file mode 100644 index 000000000..9c4a69606 --- /dev/null +++ b/CesiumGltfReader/generated/SkinJsonHandler.cpp @@ -0,0 +1,36 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "SkinJsonHandler.h" +#include "CesiumGltf/Skin.h" +#include +#include + +using namespace CesiumGltf; + +void SkinJsonHandler::reset(IJsonHandler* pParent, Skin* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Skin* SkinJsonHandler::getObject() { + return this->_pObject; +} + +void SkinJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* SkinJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("inverseBindMatrices"s == str) return property("inverseBindMatrices", this->_inverseBindMatrices, this->_pObject->inverseBindMatrices); + if ("skeleton"s == str) return property("skeleton", this->_skeleton, this->_pObject->skeleton); + if ("joints"s == str) return property("joints", this->_joints, this->_pObject->joints); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/SkinJsonHandler.h b/CesiumGltfReader/generated/SkinJsonHandler.h similarity index 63% rename from CesiumGltfReader/src/SkinJsonHandler.h rename to CesiumGltfReader/generated/SkinJsonHandler.h index e77f871c6..1234d131c 100644 --- a/CesiumGltfReader/src/SkinJsonHandler.h +++ b/CesiumGltfReader/generated/SkinJsonHandler.h @@ -11,8 +11,11 @@ namespace CesiumGltf { class SkinJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Skin* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Skin* pObject); + Skin* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp b/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp new file mode 100644 index 000000000..7637d5385 --- /dev/null +++ b/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp @@ -0,0 +1,35 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "TextureInfoJsonHandler.h" +#include "CesiumGltf/TextureInfo.h" +#include +#include + +using namespace CesiumGltf; + +void TextureInfoJsonHandler::reset(IJsonHandler* pParent, TextureInfo* pObject) { + ExtensibleObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +TextureInfo* TextureInfoJsonHandler::getObject() { + return this->_pObject; +} + +void TextureInfoJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* TextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("index"s == str) return property("index", this->_index, this->_pObject->index); + if ("texCoord"s == str) return property("texCoord", this->_texCoord, this->_pObject->texCoord); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/TextureInfoJsonHandler.h b/CesiumGltfReader/generated/TextureInfoJsonHandler.h similarity index 58% rename from CesiumGltfReader/src/TextureInfoJsonHandler.h rename to CesiumGltfReader/generated/TextureInfoJsonHandler.h index 20b2d5ea8..7c1e3fde8 100644 --- a/CesiumGltfReader/src/TextureInfoJsonHandler.h +++ b/CesiumGltfReader/generated/TextureInfoJsonHandler.h @@ -10,8 +10,11 @@ namespace CesiumGltf { class TextureInfoJsonHandler final : public ExtensibleObjectJsonHandler { public: - void reset(JsonHandler* pHandler, TextureInfo* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, TextureInfo* pObject); + TextureInfo* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/generated/TextureJsonHandler.cpp b/CesiumGltfReader/generated/TextureJsonHandler.cpp new file mode 100644 index 000000000..c1b17edc2 --- /dev/null +++ b/CesiumGltfReader/generated/TextureJsonHandler.cpp @@ -0,0 +1,35 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "TextureJsonHandler.h" +#include "CesiumGltf/Texture.h" +#include +#include + +using namespace CesiumGltf; + +void TextureJsonHandler::reset(IJsonHandler* pParent, Texture* pObject) { + NamedObjectJsonHandler::reset(pParent); + this->_pObject = pObject; +} + +Texture* TextureJsonHandler::getObject() { + return this->_pObject; +} + +void TextureJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* TextureJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + using namespace std::string_literals; + + assert(this->_pObject); + + if ("sampler"s == str) return property("sampler", this->_sampler, this->_pObject->sampler); + if ("source"s == str) return property("source", this->_source, this->_pObject->source); + + return this->NamedObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/src/TextureJsonHandler.h b/CesiumGltfReader/generated/TextureJsonHandler.h similarity index 57% rename from CesiumGltfReader/src/TextureJsonHandler.h rename to CesiumGltfReader/generated/TextureJsonHandler.h index 67e480415..14f85eca3 100644 --- a/CesiumGltfReader/src/TextureJsonHandler.h +++ b/CesiumGltfReader/generated/TextureJsonHandler.h @@ -10,8 +10,11 @@ namespace CesiumGltf { class TextureJsonHandler final : public NamedObjectJsonHandler { public: - void reset(JsonHandler* pHandler, Texture* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, Texture* pObject); + Texture* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: diff --git a/CesiumGltfReader/src/AccessorJsonHandler.cpp b/CesiumGltfReader/src/AccessorJsonHandler.cpp deleted file mode 100644 index 78f03c795..000000000 --- a/CesiumGltfReader/src/AccessorJsonHandler.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "AccessorJsonHandler.h" -#include "CesiumGltf/Accessor.h" -#include -#include - -using namespace CesiumGltf; - -void AccessorJsonHandler::reset(JsonHandler* pParent, Accessor* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* AccessorJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("bufferView"s == str) return property(this->_bufferView, this->_pObject->bufferView); - if ("byteOffset"s == str) return property(this->_byteOffset, this->_pObject->byteOffset); - if ("componentType"s == str) return property(this->_componentType, this->_pObject->componentType); - if ("normalized"s == str) return property(this->_normalized, this->_pObject->normalized); - if ("count"s == str) return property(this->_count, this->_pObject->count); - if ("type"s == str) return property(this->_type, this->_pObject->type); - if ("max"s == str) return property(this->_max, this->_pObject->max); - if ("min"s == str) return property(this->_min, this->_pObject->min); - if ("sparse"s == str) return property(this->_sparse, this->_pObject->sparse); - - return this->NamedObjectKey(str, *this->_pObject); -} - -void AccessorJsonHandler::TypeJsonHandler::reset(JsonHandler* pParent, Accessor::Type* pEnum) { - JsonHandler::reset(pParent); - this->_pEnum = pEnum; -} - -JsonHandler* AccessorJsonHandler::TypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pEnum); - - if ("SCALAR"s == str) *this->_pEnum = Accessor::Type::SCALAR; - else if ("VEC2"s == str) *this->_pEnum = Accessor::Type::VEC2; - else if ("VEC3"s == str) *this->_pEnum = Accessor::Type::VEC3; - else if ("VEC4"s == str) *this->_pEnum = Accessor::Type::VEC4; - else if ("MAT2"s == str) *this->_pEnum = Accessor::Type::MAT2; - else if ("MAT3"s == str) *this->_pEnum = Accessor::Type::MAT3; - else if ("MAT4"s == str) *this->_pEnum = Accessor::Type::MAT4; - else return nullptr; - - return this->parent(); -} diff --git a/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.cpp b/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.cpp deleted file mode 100644 index 40affc5ed..000000000 --- a/CesiumGltfReader/src/AccessorSparseIndicesJsonHandler.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "AccessorSparseIndicesJsonHandler.h" -#include "CesiumGltf/AccessorSparseIndices.h" -#include -#include - -using namespace CesiumGltf; - -void AccessorSparseIndicesJsonHandler::reset(JsonHandler* pParent, AccessorSparseIndices* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* AccessorSparseIndicesJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("bufferView"s == str) return property(this->_bufferView, this->_pObject->bufferView); - if ("byteOffset"s == str) return property(this->_byteOffset, this->_pObject->byteOffset); - if ("componentType"s == str) return property(this->_componentType, this->_pObject->componentType); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/AccessorSparseJsonHandler.cpp b/CesiumGltfReader/src/AccessorSparseJsonHandler.cpp deleted file mode 100644 index b83b3e3b9..000000000 --- a/CesiumGltfReader/src/AccessorSparseJsonHandler.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "AccessorSparseJsonHandler.h" -#include "CesiumGltf/AccessorSparse.h" -#include -#include - -using namespace CesiumGltf; - -void AccessorSparseJsonHandler::reset(JsonHandler* pParent, AccessorSparse* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* AccessorSparseJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("count"s == str) return property(this->_count, this->_pObject->count); - if ("indices"s == str) return property(this->_indices, this->_pObject->indices); - if ("values"s == str) return property(this->_values, this->_pObject->values); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.cpp b/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.cpp deleted file mode 100644 index 88d9888e5..000000000 --- a/CesiumGltfReader/src/AccessorSparseValuesJsonHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "AccessorSparseValuesJsonHandler.h" -#include "CesiumGltf/AccessorSparseValues.h" -#include -#include - -using namespace CesiumGltf; - -void AccessorSparseValuesJsonHandler::reset(JsonHandler* pParent, AccessorSparseValues* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* AccessorSparseValuesJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("bufferView"s == str) return property(this->_bufferView, this->_pObject->bufferView); - if ("byteOffset"s == str) return property(this->_byteOffset, this->_pObject->byteOffset); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/AnimationChannelJsonHandler.cpp b/CesiumGltfReader/src/AnimationChannelJsonHandler.cpp deleted file mode 100644 index 3ed7d9b75..000000000 --- a/CesiumGltfReader/src/AnimationChannelJsonHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "AnimationChannelJsonHandler.h" -#include "CesiumGltf/AnimationChannel.h" -#include -#include - -using namespace CesiumGltf; - -void AnimationChannelJsonHandler::reset(JsonHandler* pParent, AnimationChannel* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* AnimationChannelJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("sampler"s == str) return property(this->_sampler, this->_pObject->sampler); - if ("target"s == str) return property(this->_target, this->_pObject->target); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.cpp b/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.cpp deleted file mode 100644 index be88f3451..000000000 --- a/CesiumGltfReader/src/AnimationChannelTargetJsonHandler.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "AnimationChannelTargetJsonHandler.h" -#include "CesiumGltf/AnimationChannelTarget.h" -#include -#include - -using namespace CesiumGltf; - -void AnimationChannelTargetJsonHandler::reset(JsonHandler* pParent, AnimationChannelTarget* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* AnimationChannelTargetJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("node"s == str) return property(this->_node, this->_pObject->node); - if ("path"s == str) return property(this->_path, this->_pObject->path); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} - -void AnimationChannelTargetJsonHandler::PathJsonHandler::reset(JsonHandler* pParent, AnimationChannelTarget::Path* pEnum) { - JsonHandler::reset(pParent); - this->_pEnum = pEnum; -} - -JsonHandler* AnimationChannelTargetJsonHandler::PathJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pEnum); - - if ("translation"s == str) *this->_pEnum = AnimationChannelTarget::Path::translation; - else if ("rotation"s == str) *this->_pEnum = AnimationChannelTarget::Path::rotation; - else if ("scale"s == str) *this->_pEnum = AnimationChannelTarget::Path::scale; - else if ("weights"s == str) *this->_pEnum = AnimationChannelTarget::Path::weights; - else return nullptr; - - return this->parent(); -} diff --git a/CesiumGltfReader/src/AnimationJsonHandler.cpp b/CesiumGltfReader/src/AnimationJsonHandler.cpp deleted file mode 100644 index 4ae7836c1..000000000 --- a/CesiumGltfReader/src/AnimationJsonHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "AnimationJsonHandler.h" -#include "CesiumGltf/Animation.h" -#include -#include - -using namespace CesiumGltf; - -void AnimationJsonHandler::reset(JsonHandler* pParent, Animation* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* AnimationJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("channels"s == str) return property(this->_channels, this->_pObject->channels); - if ("samplers"s == str) return property(this->_samplers, this->_pObject->samplers); - - return this->NamedObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/AnimationSamplerJsonHandler.cpp b/CesiumGltfReader/src/AnimationSamplerJsonHandler.cpp deleted file mode 100644 index ba195cfd5..000000000 --- a/CesiumGltfReader/src/AnimationSamplerJsonHandler.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "AnimationSamplerJsonHandler.h" -#include "CesiumGltf/AnimationSampler.h" -#include -#include - -using namespace CesiumGltf; - -void AnimationSamplerJsonHandler::reset(JsonHandler* pParent, AnimationSampler* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* AnimationSamplerJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("input"s == str) return property(this->_input, this->_pObject->input); - if ("interpolation"s == str) return property(this->_interpolation, this->_pObject->interpolation); - if ("output"s == str) return property(this->_output, this->_pObject->output); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} - -void AnimationSamplerJsonHandler::InterpolationJsonHandler::reset(JsonHandler* pParent, AnimationSampler::Interpolation* pEnum) { - JsonHandler::reset(pParent); - this->_pEnum = pEnum; -} - -JsonHandler* AnimationSamplerJsonHandler::InterpolationJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pEnum); - - if ("LINEAR"s == str) *this->_pEnum = AnimationSampler::Interpolation::LINEAR; - else if ("STEP"s == str) *this->_pEnum = AnimationSampler::Interpolation::STEP; - else if ("CUBICSPLINE"s == str) *this->_pEnum = AnimationSampler::Interpolation::CUBICSPLINE; - else return nullptr; - - return this->parent(); -} diff --git a/CesiumGltfReader/src/ArrayJsonHandler.h b/CesiumGltfReader/src/ArrayJsonHandler.h index a7e600408..e627c8601 100644 --- a/CesiumGltfReader/src/ArrayJsonHandler.h +++ b/CesiumGltfReader/src/ArrayJsonHandler.h @@ -9,13 +9,13 @@ namespace CesiumGltf { template class ArrayJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, std::vector* pArray) { + void reset(IJsonHandler* pParent, std::vector* pArray) { JsonHandler::reset(pParent); this->_pArray = pArray; this->_arrayIsOpen = false; } - virtual JsonHandler* StartArray() override { + virtual IJsonHandler* StartArray() override { if (this->_arrayIsOpen) { return nullptr; } @@ -24,11 +24,11 @@ namespace CesiumGltf { return this; } - virtual JsonHandler* EndArray(size_t) override { + virtual IJsonHandler* EndArray(size_t) override { return this->parent(); } - virtual JsonHandler* StartObject() override { + virtual IJsonHandler* StartObject() override { if (!this->_arrayIsOpen) { return nullptr; } @@ -39,6 +39,13 @@ namespace CesiumGltf { return this->_objectHandler.StartObject(); } + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override { + T* pObject = this->_objectHandler.getObject(); + int64_t index = pObject - this->_pArray->data(); + context.push_back(std::string("[") + std::to_string(index) + "]"); + this->parent()->reportWarning(warning, std::move(context)); + } + private: std::vector* _pArray = nullptr; bool _arrayIsOpen = false; @@ -48,13 +55,13 @@ namespace CesiumGltf { template <> class ArrayJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, std::vector* pArray) { + void reset(IJsonHandler* pParent, std::vector* pArray) { JsonHandler::reset(pParent); this->_pArray = pArray; this->_arrayIsOpen = false; } - virtual JsonHandler* StartArray() override { + virtual IJsonHandler* StartArray() override { if (this->_arrayIsOpen) { return nullptr; } @@ -63,11 +70,11 @@ namespace CesiumGltf { return this; } - virtual JsonHandler* EndArray(size_t) override { + virtual IJsonHandler* EndArray(size_t) override { return this->parent(); } - virtual JsonHandler* Int(int i) override { + virtual IJsonHandler* Int(int i) override { if (!this->_arrayIsOpen) { return nullptr; } @@ -77,7 +84,7 @@ namespace CesiumGltf { return this; } - virtual JsonHandler* Uint(unsigned i) override { + virtual IJsonHandler* Uint(unsigned i) override { if (!this->_arrayIsOpen) { return nullptr; } @@ -87,7 +94,7 @@ namespace CesiumGltf { return this; } - virtual JsonHandler* Int64(int64_t i) override { + virtual IJsonHandler* Int64(int64_t i) override { if (!this->_arrayIsOpen) { return nullptr; } @@ -97,7 +104,7 @@ namespace CesiumGltf { return this; } - virtual JsonHandler* Uint64(uint64_t i) override { + virtual IJsonHandler* Uint64(uint64_t i) override { if (!this->_arrayIsOpen) { return nullptr; } @@ -107,7 +114,7 @@ namespace CesiumGltf { return this; } - virtual JsonHandler* Double(double d) override { + virtual IJsonHandler* Double(double d) override { if (!this->_arrayIsOpen) { return nullptr; } diff --git a/CesiumGltfReader/src/AssetJsonHandler.cpp b/CesiumGltfReader/src/AssetJsonHandler.cpp deleted file mode 100644 index 21e53b177..000000000 --- a/CesiumGltfReader/src/AssetJsonHandler.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "AssetJsonHandler.h" -#include "CesiumGltf/Asset.h" -#include -#include - -using namespace CesiumGltf; - -void AssetJsonHandler::reset(JsonHandler* pParent, Asset* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* AssetJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("copyright"s == str) return property(this->_copyright, this->_pObject->copyright); - if ("generator"s == str) return property(this->_generator, this->_pObject->generator); - if ("version"s == str) return property(this->_version, this->_pObject->version); - if ("minVersion"s == str) return property(this->_minVersion, this->_pObject->minVersion); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/BoolJsonHandler.cpp b/CesiumGltfReader/src/BoolJsonHandler.cpp index 0afb1572b..3a2292a32 100644 --- a/CesiumGltfReader/src/BoolJsonHandler.cpp +++ b/CesiumGltfReader/src/BoolJsonHandler.cpp @@ -3,12 +3,12 @@ using namespace CesiumGltf; -void BoolJsonHandler::reset(JsonHandler* pParent, bool* pBool) { +void BoolJsonHandler::reset(IJsonHandler* pParent, bool* pBool) { JsonHandler::reset(pParent); this->_pBool = pBool; } -JsonHandler* BoolJsonHandler::Bool(bool b) { +IJsonHandler* BoolJsonHandler::Bool(bool b) { assert(this->_pBool); *this->_pBool = b; return this->parent(); diff --git a/CesiumGltfReader/src/BoolJsonHandler.h b/CesiumGltfReader/src/BoolJsonHandler.h index e58935e3b..c6eb81dd6 100644 --- a/CesiumGltfReader/src/BoolJsonHandler.h +++ b/CesiumGltfReader/src/BoolJsonHandler.h @@ -5,9 +5,9 @@ namespace CesiumGltf { class BoolJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, bool* pBool); + void reset(IJsonHandler* pParent, bool* pBool); - virtual JsonHandler* Bool(bool b) override; + virtual IJsonHandler* Bool(bool b) override; private: bool* _pBool = nullptr; diff --git a/CesiumGltfReader/src/BufferJsonHandler.cpp b/CesiumGltfReader/src/BufferJsonHandler.cpp deleted file mode 100644 index aa262899d..000000000 --- a/CesiumGltfReader/src/BufferJsonHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "BufferJsonHandler.h" -#include "CesiumGltf/Buffer.h" -#include -#include - -using namespace CesiumGltf; - -void BufferJsonHandler::reset(JsonHandler* pParent, Buffer* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* BufferJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("uri"s == str) return property(this->_uri, this->_pObject->uri); - if ("byteLength"s == str) return property(this->_byteLength, this->_pObject->byteLength); - - return this->NamedObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/BufferViewJsonHandler.cpp b/CesiumGltfReader/src/BufferViewJsonHandler.cpp deleted file mode 100644 index bbefdc5d4..000000000 --- a/CesiumGltfReader/src/BufferViewJsonHandler.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "BufferViewJsonHandler.h" -#include "CesiumGltf/BufferView.h" -#include -#include - -using namespace CesiumGltf; - -void BufferViewJsonHandler::reset(JsonHandler* pParent, BufferView* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* BufferViewJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("buffer"s == str) return property(this->_buffer, this->_pObject->buffer); - if ("byteOffset"s == str) return property(this->_byteOffset, this->_pObject->byteOffset); - if ("byteLength"s == str) return property(this->_byteLength, this->_pObject->byteLength); - if ("byteStride"s == str) return property(this->_byteStride, this->_pObject->byteStride); - if ("target"s == str) return property(this->_target, this->_pObject->target); - - return this->NamedObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/CameraJsonHandler.cpp b/CesiumGltfReader/src/CameraJsonHandler.cpp deleted file mode 100644 index 045de9c68..000000000 --- a/CesiumGltfReader/src/CameraJsonHandler.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "CameraJsonHandler.h" -#include "CesiumGltf/Camera.h" -#include -#include - -using namespace CesiumGltf; - -void CameraJsonHandler::reset(JsonHandler* pParent, Camera* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* CameraJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("orthographic"s == str) return property(this->_orthographic, this->_pObject->orthographic); - if ("perspective"s == str) return property(this->_perspective, this->_pObject->perspective); - if ("type"s == str) return property(this->_type, this->_pObject->type); - - return this->NamedObjectKey(str, *this->_pObject); -} - -void CameraJsonHandler::TypeJsonHandler::reset(JsonHandler* pParent, Camera::Type* pEnum) { - JsonHandler::reset(pParent); - this->_pEnum = pEnum; -} - -JsonHandler* CameraJsonHandler::TypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pEnum); - - if ("perspective"s == str) *this->_pEnum = Camera::Type::perspective; - else if ("orthographic"s == str) *this->_pEnum = Camera::Type::orthographic; - else return nullptr; - - return this->parent(); -} diff --git a/CesiumGltfReader/src/CameraOrthographicJsonHandler.cpp b/CesiumGltfReader/src/CameraOrthographicJsonHandler.cpp deleted file mode 100644 index 0876f476c..000000000 --- a/CesiumGltfReader/src/CameraOrthographicJsonHandler.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "CameraOrthographicJsonHandler.h" -#include "CesiumGltf/CameraOrthographic.h" -#include -#include - -using namespace CesiumGltf; - -void CameraOrthographicJsonHandler::reset(JsonHandler* pParent, CameraOrthographic* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* CameraOrthographicJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("xmag"s == str) return property(this->_xmag, this->_pObject->xmag); - if ("ymag"s == str) return property(this->_ymag, this->_pObject->ymag); - if ("zfar"s == str) return property(this->_zfar, this->_pObject->zfar); - if ("znear"s == str) return property(this->_znear, this->_pObject->znear); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/CameraPerspectiveJsonHandler.cpp b/CesiumGltfReader/src/CameraPerspectiveJsonHandler.cpp deleted file mode 100644 index 8aba48743..000000000 --- a/CesiumGltfReader/src/CameraPerspectiveJsonHandler.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "CameraPerspectiveJsonHandler.h" -#include "CesiumGltf/CameraPerspective.h" -#include -#include - -using namespace CesiumGltf; - -void CameraPerspectiveJsonHandler::reset(JsonHandler* pParent, CameraPerspective* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* CameraPerspectiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("aspectRatio"s == str) return property(this->_aspectRatio, this->_pObject->aspectRatio); - if ("yfov"s == str) return property(this->_yfov, this->_pObject->yfov); - if ("zfar"s == str) return property(this->_zfar, this->_pObject->zfar); - if ("znear"s == str) return property(this->_znear, this->_pObject->znear); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/DictionaryJsonHandler.h b/CesiumGltfReader/src/DictionaryJsonHandler.h index 5cca78ddc..6863c9593 100644 --- a/CesiumGltfReader/src/DictionaryJsonHandler.h +++ b/CesiumGltfReader/src/DictionaryJsonHandler.h @@ -8,17 +8,22 @@ namespace CesiumGltf { template class DictionaryJsonHandler : public ObjectJsonHandler { public: - void reset(JsonHandler* pParent, std::unordered_map* pDictionary) { + void reset(IJsonHandler* pParent, std::unordered_map* pDictionary) { ObjectJsonHandler::reset(pParent); this->_pDictionary = pDictionary; } - virtual JsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { + std::unordered_map* getObject() { return this->_pDictionary; } + + virtual IJsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { assert(this->_pDictionary); + auto it = this->_pDictionary->emplace(str, -1).first; + return this->property( + it->first.c_str(), this->_item, - this->_pDictionary->emplace(str, -1).first->second + it->second ); } diff --git a/CesiumGltfReader/src/DoubleArrayJsonHandler.cpp b/CesiumGltfReader/src/DoubleArrayJsonHandler.cpp deleted file mode 100644 index 82d967bc3..000000000 --- a/CesiumGltfReader/src/DoubleArrayJsonHandler.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "DoubleArrayJsonHandler.h" -#include - -using namespace CesiumGltf; - -void DoubleArrayJsonHandler::reset(JsonHandler* pParent, std::vector* pArray) { - JsonHandler::reset(pParent); - this->_pArray = pArray; - this->_arrayIsOpen = false; -} - -JsonHandler* DoubleArrayJsonHandler::StartArray() { - if (this->_arrayIsOpen) { - return nullptr; - } - - this->_arrayIsOpen = true; - return this; -} - -JsonHandler* DoubleArrayJsonHandler::EndArray(size_t) { - return this->parent(); -} - -JsonHandler* DoubleArrayJsonHandler::Double(double d) { - if (!this->_arrayIsOpen) { - return nullptr; - } - - assert(this->_pArray); - this->_pArray->emplace_back(d); - return this; -} diff --git a/CesiumGltfReader/src/DoubleArrayJsonHandler.h b/CesiumGltfReader/src/DoubleArrayJsonHandler.h deleted file mode 100644 index 4b998632b..000000000 --- a/CesiumGltfReader/src/DoubleArrayJsonHandler.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "JsonHandler.h" -#include - -namespace CesiumGltf { - class DoubleArrayJsonHandler : public JsonHandler { - public: - void reset(JsonHandler* pParent, std::vector* pArray); - virtual JsonHandler* StartArray() override; - virtual JsonHandler* EndArray(size_t count) override; - virtual JsonHandler* Double(double d) override; - - private: - std::vector* _pArray = nullptr; - bool _arrayIsOpen = false; - }; -} diff --git a/CesiumGltfReader/src/DoubleJsonHandler.cpp b/CesiumGltfReader/src/DoubleJsonHandler.cpp index d3a7b2f46..a6b2a1252 100644 --- a/CesiumGltfReader/src/DoubleJsonHandler.cpp +++ b/CesiumGltfReader/src/DoubleJsonHandler.cpp @@ -2,36 +2,36 @@ using namespace CesiumGltf; -void DoubleJsonHandler::reset(JsonHandler* pParent, double* pDouble) { +void DoubleJsonHandler::reset(IJsonHandler* pParent, double* pDouble) { JsonHandler::reset(pParent); this->_pDouble = pDouble; } -JsonHandler* DoubleJsonHandler::Int(int i) { +IJsonHandler* DoubleJsonHandler::Int(int i) { assert(this->_pDouble); *this->_pDouble = static_cast(i); return this->parent(); } -JsonHandler* DoubleJsonHandler::Uint(unsigned i) { +IJsonHandler* DoubleJsonHandler::Uint(unsigned i) { assert(this->_pDouble); *this->_pDouble = static_cast(i); return this->parent(); } -JsonHandler* DoubleJsonHandler::Int64(int64_t i) { +IJsonHandler* DoubleJsonHandler::Int64(int64_t i) { assert(this->_pDouble); *this->_pDouble = static_cast(i); return this->parent(); } -JsonHandler* DoubleJsonHandler::Uint64(uint64_t i) { +IJsonHandler* DoubleJsonHandler::Uint64(uint64_t i) { assert(this->_pDouble); *this->_pDouble = static_cast(i); return this->parent(); } -JsonHandler* DoubleJsonHandler::Double(double d) { +IJsonHandler* DoubleJsonHandler::Double(double d) { assert(this->_pDouble); *this->_pDouble = d; return this->parent(); diff --git a/CesiumGltfReader/src/DoubleJsonHandler.h b/CesiumGltfReader/src/DoubleJsonHandler.h index 8b1175e87..ee24de2cd 100644 --- a/CesiumGltfReader/src/DoubleJsonHandler.h +++ b/CesiumGltfReader/src/DoubleJsonHandler.h @@ -6,13 +6,13 @@ namespace CesiumGltf { class DoubleJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, double* pDouble); + void reset(IJsonHandler* pParent, double* pDouble); - virtual JsonHandler* Int(int i) override; - virtual JsonHandler* Uint(unsigned i) override; - virtual JsonHandler* Int64(int64_t i) override; - virtual JsonHandler* Uint64(uint64_t i) override; - virtual JsonHandler* Double(double d) override; + virtual IJsonHandler* Int(int i) override; + virtual IJsonHandler* Uint(unsigned i) override; + virtual IJsonHandler* Int64(int64_t i) override; + virtual IJsonHandler* Uint64(uint64_t i) override; + virtual IJsonHandler* Double(double d) override; private: double* _pDouble = nullptr; diff --git a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp index 15eb483ba..f4e24d3bc 100644 --- a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp +++ b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp @@ -2,7 +2,7 @@ using namespace CesiumGltf; -JsonHandler* ExtensibleObjectJsonHandler::ExtensibleObjectKey(const char* /*str*/, ExtensibleObject& /*o*/) { +IJsonHandler* ExtensibleObjectJsonHandler::ExtensibleObjectKey(const char* /*str*/, ExtensibleObject& /*o*/) { // TODO: handle extensions and extras. - return this->ignore(); + return this->ignoreAndContinue(); } \ No newline at end of file diff --git a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h index 2fbe240aa..4e2967ad7 100644 --- a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h +++ b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h @@ -7,6 +7,6 @@ namespace CesiumGltf { class ExtensibleObjectJsonHandler : public ObjectJsonHandler { protected: - JsonHandler* ExtensibleObjectKey(const char* str, ExtensibleObject& o); + IJsonHandler* ExtensibleObjectKey(const char* str, ExtensibleObject& o); }; } diff --git a/CesiumGltfReader/src/IJsonHandler.h b/CesiumGltfReader/src/IJsonHandler.h new file mode 100644 index 000000000..e93ff5314 --- /dev/null +++ b/CesiumGltfReader/src/IJsonHandler.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +namespace CesiumGltf { + class IJsonHandler { + public: + virtual IJsonHandler* Null() = 0; + virtual IJsonHandler* Bool(bool b) = 0; + virtual IJsonHandler* Int(int i) = 0; + virtual IJsonHandler* Uint(unsigned i) = 0; + virtual IJsonHandler* Int64(int64_t i) = 0; + virtual IJsonHandler* Uint64(uint64_t i) = 0; + virtual IJsonHandler* Double(double d) = 0; + virtual IJsonHandler* RawNumber(const char* str, size_t length, bool copy) = 0; + virtual IJsonHandler* String(const char* str, size_t length, bool copy) = 0; + virtual IJsonHandler* StartObject() = 0; + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) = 0; + virtual IJsonHandler* EndObject(size_t memberCount) = 0; + virtual IJsonHandler* StartArray() = 0; + virtual IJsonHandler* EndArray(size_t elementCount) = 0; + + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) = 0; + }; +} diff --git a/CesiumGltfReader/src/IgnoreValueJsonHandler.cpp b/CesiumGltfReader/src/IgnoreValueJsonHandler.cpp index f677b2618..9f8bb72d0 100644 --- a/CesiumGltfReader/src/IgnoreValueJsonHandler.cpp +++ b/CesiumGltfReader/src/IgnoreValueJsonHandler.cpp @@ -2,63 +2,72 @@ using namespace CesiumGltf; -void IgnoreValueJsonHandler::reset(JsonHandler* pParent) { - JsonHandler::reset(pParent); +void IgnoreValueJsonHandler::reset(IJsonHandler* pParent) { + this->_pParent = pParent; this->_depth = 0; } -CesiumGltf::JsonHandler* IgnoreValueJsonHandler::Null() { +IJsonHandler* IgnoreValueJsonHandler::Null() { return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::Bool(bool /*b*/) { +IJsonHandler* IgnoreValueJsonHandler::Bool(bool /*b*/) { return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::Int(int /*i*/) { +IJsonHandler* IgnoreValueJsonHandler::Int(int /*i*/) { return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::Uint(unsigned /*i*/) { +IJsonHandler* IgnoreValueJsonHandler::Uint(unsigned /*i*/) { return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::Int64(int64_t /*i*/) { +IJsonHandler* IgnoreValueJsonHandler::Int64(int64_t /*i*/) { return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::Uint64(uint64_t /*i*/) { +IJsonHandler* IgnoreValueJsonHandler::Uint64(uint64_t /*i*/) { return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::Double(double /*d*/) { +IJsonHandler* IgnoreValueJsonHandler::Double(double /*d*/) { return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { +IJsonHandler* IgnoreValueJsonHandler::RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { +IJsonHandler* IgnoreValueJsonHandler::String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::StartObject() { +IJsonHandler* IgnoreValueJsonHandler::StartObject() { ++this->_depth; return this; } -JsonHandler* IgnoreValueJsonHandler::Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { +IJsonHandler* IgnoreValueJsonHandler::Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return this; } -JsonHandler* IgnoreValueJsonHandler::EndObject(size_t /*memberCount*/) { +IJsonHandler* IgnoreValueJsonHandler::EndObject(size_t /*memberCount*/) { --this->_depth; return this->_depth == 0 ? this->parent() : this; } -JsonHandler* IgnoreValueJsonHandler::StartArray() { +IJsonHandler* IgnoreValueJsonHandler::StartArray() { ++this->_depth; return this; } -JsonHandler* IgnoreValueJsonHandler::EndArray(size_t /*elementCount*/) { +IJsonHandler* IgnoreValueJsonHandler::EndArray(size_t /*elementCount*/) { --this->_depth; return this->_depth == 0 ? this->parent() : this; } + +void IgnoreValueJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + context.push_back("Ignoring a value"); + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* IgnoreValueJsonHandler::parent() { + return this->_pParent; +} \ No newline at end of file diff --git a/CesiumGltfReader/src/IgnoreValueJsonHandler.h b/CesiumGltfReader/src/IgnoreValueJsonHandler.h index 6109b0945..0e62e9175 100644 --- a/CesiumGltfReader/src/IgnoreValueJsonHandler.h +++ b/CesiumGltfReader/src/IgnoreValueJsonHandler.h @@ -1,29 +1,34 @@ #pragma once -#include "JsonHandler.h" +#include "IJsonHandler.h" #include namespace CesiumGltf { - class IgnoreValueJsonHandler : public JsonHandler { + class IgnoreValueJsonHandler : public IJsonHandler { public: - void reset(JsonHandler* pParent); + void reset(IJsonHandler* pParent); - virtual JsonHandler* Null() override; - virtual JsonHandler* Bool(bool /*b*/) override; - virtual JsonHandler* Int(int /*i*/) override; - virtual JsonHandler* Uint(unsigned /*i*/) override; - virtual JsonHandler* Int64(int64_t /*i*/) override; - virtual JsonHandler* Uint64(uint64_t /*i*/) override; - virtual JsonHandler* Double(double /*d*/) override; - virtual JsonHandler* RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) override; - virtual JsonHandler* String(const char* /*str*/, size_t /*length*/, bool /*copy*/) override; - virtual JsonHandler* StartObject() override; - virtual JsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) override; - virtual JsonHandler* EndObject(size_t /*memberCount*/) override; - virtual JsonHandler* StartArray() override; - virtual JsonHandler* EndArray(size_t /*elementCount*/) override; + virtual IJsonHandler* Null() override; + virtual IJsonHandler* Bool(bool b) override; + virtual IJsonHandler* Int(int i) override; + virtual IJsonHandler* Uint(unsigned i) override; + virtual IJsonHandler* Int64(int64_t i) override; + virtual IJsonHandler* Uint64(uint64_t i) override; + virtual IJsonHandler* Double(double d) override; + virtual IJsonHandler* RawNumber(const char* str, size_t length, bool copy) override; + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; + virtual IJsonHandler* StartObject() override; + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + virtual IJsonHandler* EndObject(size_t memberCount) override; + virtual IJsonHandler* StartArray() override; + virtual IJsonHandler* EndArray(size_t elementCount) override; + + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + IJsonHandler* parent(); private: - size_t _depth = 0; + IJsonHandler* _pParent = nullptr; + int32_t _depth = 0; }; } diff --git a/CesiumGltfReader/src/ImageJsonHandler.cpp b/CesiumGltfReader/src/ImageJsonHandler.cpp deleted file mode 100644 index 785e6a6ca..000000000 --- a/CesiumGltfReader/src/ImageJsonHandler.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "ImageJsonHandler.h" -#include "CesiumGltf/Image.h" -#include -#include - -using namespace CesiumGltf; - -void ImageJsonHandler::reset(JsonHandler* pParent, Image* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* ImageJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("uri"s == str) return property(this->_uri, this->_pObject->uri); - if ("mimeType"s == str) return property(this->_mimeType, this->_pObject->mimeType); - if ("bufferView"s == str) return property(this->_bufferView, this->_pObject->bufferView); - - return this->NamedObjectKey(str, *this->_pObject); -} - -void ImageJsonHandler::MimeTypeJsonHandler::reset(JsonHandler* pParent, Image::MimeType* pEnum) { - JsonHandler::reset(pParent); - this->_pEnum = pEnum; -} - -JsonHandler* ImageJsonHandler::MimeTypeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pEnum); - - if ("image/jpeg"s == str) *this->_pEnum = Image::MimeType::image_jpeg; - else if ("image/png"s == str) *this->_pEnum = Image::MimeType::image_png; - else return nullptr; - - return this->parent(); -} diff --git a/CesiumGltfReader/src/IntegerJsonHandler.h b/CesiumGltfReader/src/IntegerJsonHandler.h index 7f0e957f3..05c5d0905 100644 --- a/CesiumGltfReader/src/IntegerJsonHandler.h +++ b/CesiumGltfReader/src/IntegerJsonHandler.h @@ -7,32 +7,39 @@ namespace CesiumGltf { template class IntegerJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, T* pInteger) { + void reset(IJsonHandler* pParent, T* pInteger) { JsonHandler::reset(pParent); this->_pInteger = pInteger; } - virtual JsonHandler* Int(int i) override { + T* getObject() { return this->_pInteger; } + + virtual IJsonHandler* Int(int i) override { assert(this->_pInteger); *this->_pInteger = static_cast(i); return this->parent(); } - virtual JsonHandler* Uint(unsigned i) override { + virtual IJsonHandler* Uint(unsigned i) override { assert(this->_pInteger); *this->_pInteger = static_cast(i); return this->parent(); } - virtual JsonHandler* Int64(int64_t i) override { + virtual IJsonHandler* Int64(int64_t i) override { assert(this->_pInteger); *this->_pInteger = static_cast(i); return this->parent(); } - virtual JsonHandler* Uint64(uint64_t i) override { + virtual IJsonHandler* Uint64(uint64_t i) override { assert(this->_pInteger); *this->_pInteger = static_cast(i); return this->parent(); } + virtual void reportWarning(const std::string& warning, std::vector&& context) override { + context.push_back("(expecting an integer)"); + this->parent()->reportWarning(warning, std::move(context)); + } + private: T* _pInteger = nullptr; }; diff --git a/CesiumGltfReader/src/JsonHandler.cpp b/CesiumGltfReader/src/JsonHandler.cpp index 33271b4e0..9335e525b 100644 --- a/CesiumGltfReader/src/JsonHandler.cpp +++ b/CesiumGltfReader/src/JsonHandler.cpp @@ -2,63 +2,91 @@ using namespace CesiumGltf; -JsonHandler* JsonHandler::Null() { - return nullptr; +IJsonHandler* JsonHandler::Null() { + this->reportWarning("A null value is not allowed and has been ignored."); + return this->parent(); } -JsonHandler* JsonHandler::Bool(bool /*b*/) { - return nullptr; +IJsonHandler* JsonHandler::Bool(bool /*b*/) { + this->reportWarning("A boolean value is not allowed and has been ignored."); + return this->parent(); } -JsonHandler* JsonHandler::Int(int /*i*/) { - return nullptr; +IJsonHandler* JsonHandler::Int(int /*i*/) { + this->reportWarning("An integer value is not allowed and has been ignored."); + return this->parent(); } -JsonHandler* JsonHandler::Uint(unsigned /*i*/) { - return nullptr; +IJsonHandler* JsonHandler::Uint(unsigned /*i*/) { + this->reportWarning("An integer value is not allowed and has been ignored."); + return this->parent(); } -JsonHandler* JsonHandler::Int64(int64_t /*i*/) { - return nullptr; +IJsonHandler* JsonHandler::Int64(int64_t /*i*/) { + this->reportWarning("An integer value is not allowed and has been ignored."); + return this->parent(); } -JsonHandler* JsonHandler::Uint64(uint64_t /*i*/) { - return nullptr; +IJsonHandler* JsonHandler::Uint64(uint64_t /*i*/) { + this->reportWarning("An integer value is not allowed and has been ignored."); + return this->parent(); } -JsonHandler* JsonHandler::Double(double /*d*/) { - return nullptr; +IJsonHandler* JsonHandler::Double(double /*d*/) { + this->reportWarning("A double value is not allowed and has been ignored."); + return this->parent(); } -JsonHandler* JsonHandler::RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { - return nullptr; +IJsonHandler* JsonHandler::RawNumber(const char* /*str*/, size_t /*length*/, bool /*copy*/) { + this->reportWarning("A numeric value is not allowed and has been ignored."); + return this->parent(); } -JsonHandler* JsonHandler::String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { - return nullptr; +IJsonHandler* JsonHandler::String(const char* /*str*/, size_t /*length*/, bool /*copy*/) { + this->reportWarning("A string value is not allowed and has been ignored."); + return this->parent(); } -JsonHandler* JsonHandler::StartObject() { return nullptr; } -JsonHandler* JsonHandler::Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { - return nullptr; +IJsonHandler* JsonHandler::StartObject() { + this->reportWarning("An object value is not allowed and has been ignored."); + return this->ignoreAndReturnToParent()->StartObject(); } -JsonHandler* JsonHandler::EndObject(size_t /*memberCount*/) { +IJsonHandler* JsonHandler::Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) { return nullptr; } -JsonHandler* JsonHandler::StartArray() { +IJsonHandler* JsonHandler::EndObject(size_t /*memberCount*/) { return nullptr; } -JsonHandler* JsonHandler::EndArray(size_t /*elementCount*/) { +IJsonHandler* JsonHandler::StartArray() { + this->reportWarning("An array value is not allowed and has been ignored."); + return this->ignoreAndReturnToParent()->StartArray(); +} + +IJsonHandler* JsonHandler::EndArray(size_t /*elementCount*/) { return nullptr; } -JsonHandler* JsonHandler::parent() { +IJsonHandler* JsonHandler::parent() { return this->_pParent; } -void JsonHandler::reset(JsonHandler* pParent) { +IJsonHandler* JsonHandler::ignoreAndReturnToParent() { + this->_ignore.reset(this->parent()); + return &this->_ignore; +} + +IJsonHandler* JsonHandler::ignoreAndContinue() { + this->_ignore.reset(this); + return &this->_ignore; +} + +void JsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + this->parent()->reportWarning(warning, std::move(context)); +} + +void JsonHandler::reset(IJsonHandler* pParent) { this->_pParent = pParent; } diff --git a/CesiumGltfReader/src/JsonHandler.h b/CesiumGltfReader/src/JsonHandler.h index 18a612acd..eb31bc01b 100644 --- a/CesiumGltfReader/src/JsonHandler.h +++ b/CesiumGltfReader/src/JsonHandler.h @@ -1,39 +1,48 @@ #pragma once +#include "IJsonHandler.h" +#include "IgnoreValueJsonHandler.h" #include +#include namespace CesiumGltf { - - class JsonHandler { + class JsonHandler : public IJsonHandler { public: - virtual JsonHandler* Null(); - virtual JsonHandler* Bool(bool b); - virtual JsonHandler* Int(int i); - virtual JsonHandler* Uint(unsigned i); - virtual JsonHandler* Int64(int64_t i); - virtual JsonHandler* Uint64(uint64_t i); - virtual JsonHandler* Double(double d); - virtual JsonHandler* RawNumber(const char* str, size_t length, bool copy); - virtual JsonHandler* String(const char* str, size_t length, bool copy); - virtual JsonHandler* StartObject(); - virtual JsonHandler* Key(const char* str, size_t length, bool copy); - virtual JsonHandler* EndObject(size_t memberCount); - virtual JsonHandler* StartArray(); - virtual JsonHandler* EndArray(size_t elementCount); + virtual IJsonHandler* Null() override; + virtual IJsonHandler* Bool(bool b) override; + virtual IJsonHandler* Int(int i) override; + virtual IJsonHandler* Uint(unsigned i) override; + virtual IJsonHandler* Int64(int64_t i) override; + virtual IJsonHandler* Uint64(uint64_t i) override; + virtual IJsonHandler* Double(double d) override; + virtual IJsonHandler* RawNumber(const char* str, size_t length, bool copy) override; + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; + virtual IJsonHandler* StartObject() override; + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + virtual IJsonHandler* EndObject(size_t memberCount) override; + virtual IJsonHandler* StartArray() override; + virtual IJsonHandler* EndArray(size_t elementCount) override; + + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; protected: - void reset(JsonHandler* pParent); + void reset(IJsonHandler* pParent); - template - JsonHandler* property(TAccessor& accessor, TProperty& value) { - accessor.reset(this, &value); - return &accessor; - } + IJsonHandler* parent(); + + /** + * @brief Ignore a single value and then return to the parent handler. + */ + IJsonHandler* ignoreAndReturnToParent(); - JsonHandler* parent(); + /** + * @brief Ignore a single value and the continue processing more tokens with this handler. + */ + IJsonHandler* ignoreAndContinue(); private: - JsonHandler* _pParent = nullptr; + IJsonHandler* _pParent = nullptr; + IgnoreValueJsonHandler _ignore; }; } diff --git a/CesiumGltfReader/src/MaterialJsonHandler.cpp b/CesiumGltfReader/src/MaterialJsonHandler.cpp deleted file mode 100644 index e0f87c0c9..000000000 --- a/CesiumGltfReader/src/MaterialJsonHandler.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "MaterialJsonHandler.h" -#include "CesiumGltf/Material.h" -#include -#include - -using namespace CesiumGltf; - -void MaterialJsonHandler::reset(JsonHandler* pParent, Material* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* MaterialJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("pbrMetallicRoughness"s == str) return property(this->_pbrMetallicRoughness, this->_pObject->pbrMetallicRoughness); - if ("normalTexture"s == str) return property(this->_normalTexture, this->_pObject->normalTexture); - if ("occlusionTexture"s == str) return property(this->_occlusionTexture, this->_pObject->occlusionTexture); - if ("emissiveTexture"s == str) return property(this->_emissiveTexture, this->_pObject->emissiveTexture); - if ("emissiveFactor"s == str) return property(this->_emissiveFactor, this->_pObject->emissiveFactor); - if ("alphaMode"s == str) return property(this->_alphaMode, this->_pObject->alphaMode); - if ("alphaCutoff"s == str) return property(this->_alphaCutoff, this->_pObject->alphaCutoff); - if ("doubleSided"s == str) return property(this->_doubleSided, this->_pObject->doubleSided); - - return this->NamedObjectKey(str, *this->_pObject); -} - -void MaterialJsonHandler::AlphaModeJsonHandler::reset(JsonHandler* pParent, Material::AlphaMode* pEnum) { - JsonHandler::reset(pParent); - this->_pEnum = pEnum; -} - -JsonHandler* MaterialJsonHandler::AlphaModeJsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pEnum); - - if ("OPAQUE"s == str) *this->_pEnum = Material::AlphaMode::OPAQUE; - else if ("MASK"s == str) *this->_pEnum = Material::AlphaMode::MASK; - else if ("BLEND"s == str) *this->_pEnum = Material::AlphaMode::BLEND; - else return nullptr; - - return this->parent(); -} diff --git a/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.cpp b/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.cpp deleted file mode 100644 index f33489ded..000000000 --- a/CesiumGltfReader/src/MaterialNormalTextureInfoJsonHandler.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "MaterialNormalTextureInfoJsonHandler.h" -#include "CesiumGltf/MaterialNormalTextureInfo.h" -#include -#include - -using namespace CesiumGltf; - -void MaterialNormalTextureInfoJsonHandler::reset(JsonHandler* pParent, MaterialNormalTextureInfo* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* MaterialNormalTextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("scale"s == str) return property(this->_scale, this->_pObject->scale); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.cpp b/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.cpp deleted file mode 100644 index f137e160e..000000000 --- a/CesiumGltfReader/src/MaterialOcclusionTextureInfoJsonHandler.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "MaterialOcclusionTextureInfoJsonHandler.h" -#include "CesiumGltf/MaterialOcclusionTextureInfo.h" -#include -#include - -using namespace CesiumGltf; - -void MaterialOcclusionTextureInfoJsonHandler::reset(JsonHandler* pParent, MaterialOcclusionTextureInfo* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* MaterialOcclusionTextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("strength"s == str) return property(this->_strength, this->_pObject->strength); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.cpp b/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.cpp deleted file mode 100644 index 0489533a3..000000000 --- a/CesiumGltfReader/src/MaterialPBRMetallicRoughnessJsonHandler.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "MaterialPBRMetallicRoughnessJsonHandler.h" -#include "CesiumGltf/MaterialPBRMetallicRoughness.h" -#include -#include - -using namespace CesiumGltf; - -void MaterialPBRMetallicRoughnessJsonHandler::reset(JsonHandler* pParent, MaterialPBRMetallicRoughness* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* MaterialPBRMetallicRoughnessJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("baseColorFactor"s == str) return property(this->_baseColorFactor, this->_pObject->baseColorFactor); - if ("baseColorTexture"s == str) return property(this->_baseColorTexture, this->_pObject->baseColorTexture); - if ("metallicFactor"s == str) return property(this->_metallicFactor, this->_pObject->metallicFactor); - if ("roughnessFactor"s == str) return property(this->_roughnessFactor, this->_pObject->roughnessFactor); - if ("metallicRoughnessTexture"s == str) return property(this->_metallicRoughnessTexture, this->_pObject->metallicRoughnessTexture); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/MeshJsonHandler.cpp b/CesiumGltfReader/src/MeshJsonHandler.cpp deleted file mode 100644 index ea3178ae8..000000000 --- a/CesiumGltfReader/src/MeshJsonHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "MeshJsonHandler.h" -#include "CesiumGltf/Mesh.h" -#include -#include - -using namespace CesiumGltf; - -void MeshJsonHandler::reset(JsonHandler* pParent, Mesh* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* MeshJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("primitives"s == str) return property(this->_primitives, this->_pObject->primitives); - if ("weights"s == str) return property(this->_weights, this->_pObject->weights); - - return this->NamedObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/MeshPrimitiveJsonHandler.cpp b/CesiumGltfReader/src/MeshPrimitiveJsonHandler.cpp deleted file mode 100644 index e5e1a14f7..000000000 --- a/CesiumGltfReader/src/MeshPrimitiveJsonHandler.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "MeshPrimitiveJsonHandler.h" -#include "CesiumGltf/MeshPrimitive.h" -#include -#include - -using namespace CesiumGltf; - -void MeshPrimitiveJsonHandler::reset(JsonHandler* pParent, MeshPrimitive* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* MeshPrimitiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("attributes"s == str) return property(this->_attributes, this->_pObject->attributes); - if ("indices"s == str) return property(this->_indices, this->_pObject->indices); - if ("material"s == str) return property(this->_material, this->_pObject->material); - if ("mode"s == str) return property(this->_mode, this->_pObject->mode); - if ("targets"s == str) return property(this->_targets, this->_pObject->targets); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/ModelJsonHandler.cpp b/CesiumGltfReader/src/ModelJsonHandler.cpp deleted file mode 100644 index 3334361cf..000000000 --- a/CesiumGltfReader/src/ModelJsonHandler.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "ModelJsonHandler.h" -#include "CesiumGltf/Model.h" -#include -#include - -using namespace CesiumGltf; - -void ModelJsonHandler::reset(JsonHandler* pParent, Model* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* ModelJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("extensionsUsed"s == str) return property(this->_extensionsUsed, this->_pObject->extensionsUsed); - if ("extensionsRequired"s == str) return property(this->_extensionsRequired, this->_pObject->extensionsRequired); - if ("accessors"s == str) return property(this->_accessors, this->_pObject->accessors); - if ("animations"s == str) return property(this->_animations, this->_pObject->animations); - if ("asset"s == str) return property(this->_asset, this->_pObject->asset); - if ("buffers"s == str) return property(this->_buffers, this->_pObject->buffers); - if ("bufferViews"s == str) return property(this->_bufferViews, this->_pObject->bufferViews); - if ("cameras"s == str) return property(this->_cameras, this->_pObject->cameras); - if ("images"s == str) return property(this->_images, this->_pObject->images); - if ("materials"s == str) return property(this->_materials, this->_pObject->materials); - if ("meshes"s == str) return property(this->_meshes, this->_pObject->meshes); - if ("nodes"s == str) return property(this->_nodes, this->_pObject->nodes); - if ("samplers"s == str) return property(this->_samplers, this->_pObject->samplers); - if ("scene"s == str) return property(this->_scene, this->_pObject->scene); - if ("scenes"s == str) return property(this->_scenes, this->_pObject->scenes); - if ("skins"s == str) return property(this->_skins, this->_pObject->skins); - if ("textures"s == str) return property(this->_textures, this->_pObject->textures); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/NamedObjectJsonHandler.cpp b/CesiumGltfReader/src/NamedObjectJsonHandler.cpp index b586e37b6..06fb2116c 100644 --- a/CesiumGltfReader/src/NamedObjectJsonHandler.cpp +++ b/CesiumGltfReader/src/NamedObjectJsonHandler.cpp @@ -4,8 +4,8 @@ using namespace CesiumGltf; -JsonHandler* NamedObjectJsonHandler::NamedObjectKey(const char* str, NamedObject& o) { +IJsonHandler* NamedObjectJsonHandler::NamedObjectKey(const char* str, NamedObject& o) { using namespace std::string_literals; - if ("name"s == str) return property(this->_name, o.name); + if ("name"s == str) return property("name", this->_name, o.name); return this->ExtensibleObjectKey(str, o); } diff --git a/CesiumGltfReader/src/NamedObjectJsonHandler.h b/CesiumGltfReader/src/NamedObjectJsonHandler.h index 66237ef6d..3f42cb42e 100644 --- a/CesiumGltfReader/src/NamedObjectJsonHandler.h +++ b/CesiumGltfReader/src/NamedObjectJsonHandler.h @@ -8,7 +8,7 @@ namespace CesiumGltf { class NamedObjectJsonHandler : public ExtensibleObjectJsonHandler { protected: - JsonHandler* NamedObjectKey(const char* str, NamedObject& o); + IJsonHandler* NamedObjectKey(const char* str, NamedObject& o); private: StringJsonHandler _name; diff --git a/CesiumGltfReader/src/NodeJsonHandler.cpp b/CesiumGltfReader/src/NodeJsonHandler.cpp deleted file mode 100644 index 9bfba6f46..000000000 --- a/CesiumGltfReader/src/NodeJsonHandler.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "NodeJsonHandler.h" -#include "CesiumGltf/Node.h" -#include -#include - -using namespace CesiumGltf; - -void NodeJsonHandler::reset(JsonHandler* pParent, Node* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* NodeJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("camera"s == str) return property(this->_camera, this->_pObject->camera); - if ("children"s == str) return property(this->_children, this->_pObject->children); - if ("skin"s == str) return property(this->_skin, this->_pObject->skin); - if ("matrix"s == str) return property(this->_matrix, this->_pObject->matrix); - if ("mesh"s == str) return property(this->_mesh, this->_pObject->mesh); - if ("rotation"s == str) return property(this->_rotation, this->_pObject->rotation); - if ("scale"s == str) return property(this->_scale, this->_pObject->scale); - if ("translation"s == str) return property(this->_translation, this->_pObject->translation); - if ("weights"s == str) return property(this->_weights, this->_pObject->weights); - - return this->NamedObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/ObjectJsonHandler.cpp b/CesiumGltfReader/src/ObjectJsonHandler.cpp index 7c04a64c9..098b3732f 100644 --- a/CesiumGltfReader/src/ObjectJsonHandler.cpp +++ b/CesiumGltfReader/src/ObjectJsonHandler.cpp @@ -2,7 +2,7 @@ using namespace CesiumGltf; -JsonHandler* ObjectJsonHandler::StartObject() { +IJsonHandler* ObjectJsonHandler::StartObject() { ++this->_depth; if (this->_depth > 1) { return this->StartSubObject(); @@ -10,7 +10,9 @@ JsonHandler* ObjectJsonHandler::StartObject() { return this; } -JsonHandler* ObjectJsonHandler::EndObject(size_t memberCount) { +IJsonHandler* ObjectJsonHandler::EndObject(size_t memberCount) { + this->_currentKey = nullptr; + --this->_depth; if (this->_depth > 0) @@ -19,15 +21,14 @@ JsonHandler* ObjectJsonHandler::EndObject(size_t memberCount) { return this->parent(); } -JsonHandler* ObjectJsonHandler::StartSubObject() { +IJsonHandler* ObjectJsonHandler::StartSubObject() { return nullptr; } -JsonHandler* ObjectJsonHandler::EndSubObject(size_t /*memberCount*/) { +IJsonHandler* ObjectJsonHandler::EndSubObject(size_t /*memberCount*/) { return nullptr; } -JsonHandler* ObjectJsonHandler::ignore() { - this->_ignoreHandler.reset(this); - return &this->_ignoreHandler; +const char* ObjectJsonHandler::getCurrentKey() const { + return this->_currentKey; } diff --git a/CesiumGltfReader/src/ObjectJsonHandler.h b/CesiumGltfReader/src/ObjectJsonHandler.h index 8a41834b2..10827f6ee 100644 --- a/CesiumGltfReader/src/ObjectJsonHandler.h +++ b/CesiumGltfReader/src/ObjectJsonHandler.h @@ -1,22 +1,28 @@ #pragma once #include "JsonHandler.h" -#include "IgnoreValueJsonHandler.h" namespace CesiumGltf { class ObjectJsonHandler : public JsonHandler { public: - virtual JsonHandler* StartObject() override final; - virtual JsonHandler* EndObject(size_t memberCount) override final; + virtual IJsonHandler* StartObject() override final; + virtual IJsonHandler* EndObject(size_t memberCount) override final; protected: - virtual JsonHandler* StartSubObject(); - virtual JsonHandler* EndSubObject(size_t memberCount); + virtual IJsonHandler* StartSubObject(); + virtual IJsonHandler* EndSubObject(size_t memberCount); - JsonHandler* ignore(); + template + IJsonHandler* property(const char* currentKey, TAccessor& accessor, TProperty& value) { + this->_currentKey = currentKey; + accessor.reset(this, &value); + return &accessor; + } + + const char* getCurrentKey() const; private: - IgnoreValueJsonHandler _ignoreHandler; int32_t _depth = 0; - }; + const char* _currentKey; + }; } diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 971a0c351..5070fe060 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -1,7 +1,6 @@ #include "CesiumGltf/Reader.h" #include "JsonHandler.h" #include "ModelJsonHandler.h" -#include "RejectAllJsonHandler.h" #include #include @@ -9,9 +8,9 @@ using namespace CesiumGltf; namespace { struct Dispatcher { - JsonHandler* pCurrent; + IJsonHandler* pCurrent; - bool update(JsonHandler* pNext) { + bool update(IJsonHandler* pNext) { if (pNext == nullptr) { return false; } @@ -35,6 +34,35 @@ namespace { bool StartArray() { return update(pCurrent->StartArray()); } bool EndArray(size_t elementCount) { return update(pCurrent->EndArray(elementCount)); } }; + + class FinalJsonHandler : public ObjectJsonHandler { + public: + FinalJsonHandler(ModelReaderResult& result, rapidjson::MemoryStream& inputStream) : + _result(result), + _inputStream(inputStream) + { + reset(this); + } + + virtual void reportWarning(const std::string& warning, std::vector&& context) override { + if (!this->_result.warnings.empty()) { + this->_result.warnings.push_back('\n'); + } + + this->_result.warnings += warning; + this->_result.warnings += "\n While parsing: "; + for (auto it = context.rbegin(); it != context.rend(); ++it) { + this->_result.warnings += *it; + } + + this->_result.warnings += "\n From byte offset: "; + this->_result.warnings += std::to_string(this->_inputStream.Tell()); + } + + private: + ModelReaderResult& _result; + rapidjson::MemoryStream& _inputStream; + }; } ModelReaderResult CesiumGltf::readModel(const gsl::span& data) { @@ -43,11 +71,11 @@ ModelReaderResult CesiumGltf::readModel(const gsl::span& data) { ModelReaderResult result; ModelJsonHandler modelHandler; - RejectAllJsonHandler rejectHandler; + FinalJsonHandler finalHandler(result, inputStream); Dispatcher dispatcher { &modelHandler }; result.model.emplace(); - modelHandler.reset(&rejectHandler, &result.model.value()); + modelHandler.reset(&finalHandler, &result.model.value()); reader.IterativeParseInit(); diff --git a/CesiumGltfReader/src/RejectAllJsonHandler.h b/CesiumGltfReader/src/RejectAllJsonHandler.h deleted file mode 100644 index 064edf35d..000000000 --- a/CesiumGltfReader/src/RejectAllJsonHandler.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace CesiumGltf { - class RejectAllJsonHandler : public JsonHandler { - public: - RejectAllJsonHandler() { - reset(this); - } - }; -} diff --git a/CesiumGltfReader/src/SamplerJsonHandler.cpp b/CesiumGltfReader/src/SamplerJsonHandler.cpp deleted file mode 100644 index c5caec635..000000000 --- a/CesiumGltfReader/src/SamplerJsonHandler.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "SamplerJsonHandler.h" -#include "CesiumGltf/Sampler.h" -#include -#include - -using namespace CesiumGltf; - -void SamplerJsonHandler::reset(JsonHandler* pParent, Sampler* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* SamplerJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("magFilter"s == str) return property(this->_magFilter, this->_pObject->magFilter); - if ("minFilter"s == str) return property(this->_minFilter, this->_pObject->minFilter); - if ("wrapS"s == str) return property(this->_wrapS, this->_pObject->wrapS); - if ("wrapT"s == str) return property(this->_wrapT, this->_pObject->wrapT); - - return this->NamedObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/SceneJsonHandler.cpp b/CesiumGltfReader/src/SceneJsonHandler.cpp deleted file mode 100644 index 1cbc8d9a6..000000000 --- a/CesiumGltfReader/src/SceneJsonHandler.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "SceneJsonHandler.h" -#include "CesiumGltf/Scene.h" -#include -#include - -using namespace CesiumGltf; - -void SceneJsonHandler::reset(JsonHandler* pParent, Scene* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* SceneJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("nodes"s == str) return property(this->_nodes, this->_pObject->nodes); - - return this->NamedObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/SkinJsonHandler.cpp b/CesiumGltfReader/src/SkinJsonHandler.cpp deleted file mode 100644 index 74773ecf7..000000000 --- a/CesiumGltfReader/src/SkinJsonHandler.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "SkinJsonHandler.h" -#include "CesiumGltf/Skin.h" -#include -#include - -using namespace CesiumGltf; - -void SkinJsonHandler::reset(JsonHandler* pParent, Skin* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* SkinJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("inverseBindMatrices"s == str) return property(this->_inverseBindMatrices, this->_pObject->inverseBindMatrices); - if ("skeleton"s == str) return property(this->_skeleton, this->_pObject->skeleton); - if ("joints"s == str) return property(this->_joints, this->_pObject->joints); - - return this->NamedObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/StringJsonHandler.cpp b/CesiumGltfReader/src/StringJsonHandler.cpp index 0cc0bfa56..42bb95b14 100644 --- a/CesiumGltfReader/src/StringJsonHandler.cpp +++ b/CesiumGltfReader/src/StringJsonHandler.cpp @@ -2,12 +2,16 @@ using namespace CesiumGltf; -void StringJsonHandler::reset(JsonHandler* pParent, std::string* pString) { +void StringJsonHandler::reset(IJsonHandler* pParent, std::string* pString) { JsonHandler::reset(pParent); this->_pString = pString; } -JsonHandler* StringJsonHandler::String(const char* str, size_t length, bool /*copy*/) { +std::string* StringJsonHandler::getObject() { + return this->_pString; +} + +IJsonHandler* StringJsonHandler::String(const char* str, size_t length, bool /*copy*/) { *this->_pString = std::string(str, length); return this->parent(); } diff --git a/CesiumGltfReader/src/StringJsonHandler.h b/CesiumGltfReader/src/StringJsonHandler.h index 29df3f70f..cd05b5816 100644 --- a/CesiumGltfReader/src/StringJsonHandler.h +++ b/CesiumGltfReader/src/StringJsonHandler.h @@ -6,8 +6,9 @@ namespace CesiumGltf { class StringJsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, std::string* pString); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pParent, std::string* pString); + std::string* getObject(); + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; private: std::string* _pString = nullptr; diff --git a/CesiumGltfReader/src/TextureInfoJsonHandler.cpp b/CesiumGltfReader/src/TextureInfoJsonHandler.cpp deleted file mode 100644 index dbca18be9..000000000 --- a/CesiumGltfReader/src/TextureInfoJsonHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "TextureInfoJsonHandler.h" -#include "CesiumGltf/TextureInfo.h" -#include -#include - -using namespace CesiumGltf; - -void TextureInfoJsonHandler::reset(JsonHandler* pParent, TextureInfo* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* TextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("index"s == str) return property(this->_index, this->_pObject->index); - if ("texCoord"s == str) return property(this->_texCoord, this->_pObject->texCoord); - - return this->ExtensibleObjectKey(str, *this->_pObject); -} diff --git a/CesiumGltfReader/src/TextureJsonHandler.cpp b/CesiumGltfReader/src/TextureJsonHandler.cpp deleted file mode 100644 index 32cf10301..000000000 --- a/CesiumGltfReader/src/TextureJsonHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! -#include "TextureJsonHandler.h" -#include "CesiumGltf/Texture.h" -#include -#include - -using namespace CesiumGltf; - -void TextureJsonHandler::reset(JsonHandler* pParent, Texture* pObject) { - NamedObjectJsonHandler::reset(pParent); - this->_pObject = pObject; -} - -JsonHandler* TextureJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - - assert(this->_pObject); - - if ("sampler"s == str) return property(this->_sampler, this->_pObject->sampler); - if ("source"s == str) return property(this->_source, this->_pObject->source); - - return this->NamedObjectKey(str, *this->_pObject); -} diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index c59e1cf52..d7733cb1c 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -83,8 +83,11 @@ function generate(options, schema) { class ${name}JsonHandler final : public ${base}ObjectJsonHandler { public: - void reset(JsonHandler* pHandler, ${name}* pObject); - virtual JsonHandler* Key(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pHandler, ${name}* pObject); + ${name}* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; private: ${indent(readerLocalTypes.join("\n\n"), 12)} @@ -100,7 +103,7 @@ function generate(options, schema) { } `; - const readerHeaderOutputDir = path.join(readerOutputDir, "src"); + const readerHeaderOutputDir = path.join(readerOutputDir, "generated"); fs.mkdirSync(readerHeaderOutputDir, { recursive: true }); const readerHeaderOutputPath = path.join(readerHeaderOutputDir, name + "JsonHandler.h"); fs.writeFileSync(readerHeaderOutputPath, unindent(readerHeader), "utf-8"); @@ -119,12 +122,23 @@ function generate(options, schema) { using namespace CesiumGltf; - void ${name}JsonHandler::reset(JsonHandler* pParent, ${name}* pObject) { + void ${name}JsonHandler::reset(IJsonHandler* pParent, ${name}* pObject) { ${base}ObjectJsonHandler::reset(pParent); this->_pObject = pObject; } - JsonHandler* ${name}JsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + ${name}* ${name}JsonHandler::getObject() { + return this->_pObject; + } + + void ${name}JsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); + } + + IJsonHandler* ${name}JsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { using namespace std::string_literals; assert(this->_pObject); @@ -170,7 +184,7 @@ function formatReaderProperty(property) { } function formatReaderPropertyImpl(property) { - return `if ("${property.name}"s == str) return property(this->_${property.name}, this->_pObject->${property.name});`; + return `if ("${property.name}"s == str) return property("${property.name}", this->_${property.name}, this->_pObject->${property.name});`; } module.exports = generate; diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index 2103d8100..8d1701b3d 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -249,8 +249,8 @@ function createEnumReaderType(parentName, enumName, propertyName, propertyDetail return unindent(` class ${enumName}JsonHandler : public JsonHandler { public: - void reset(JsonHandler* pParent, ${parentName}::${enumName}* pEnum); - virtual JsonHandler* String(const char* str, size_t length, bool copy) override; + void reset(IJsonHandler* pParent, ${parentName}::${enumName}* pEnum); + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; private: ${parentName}::${enumName}* _pEnum = nullptr; @@ -265,12 +265,12 @@ function createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDe } return unindent(` - void ${parentName}JsonHandler::${enumName}JsonHandler::reset(JsonHandler* pParent, ${parentName}::${enumName}* pEnum) { + void ${parentName}JsonHandler::${enumName}JsonHandler::reset(IJsonHandler* pParent, ${parentName}::${enumName}* pEnum) { JsonHandler::reset(pParent); this->_pEnum = pEnum; } - JsonHandler* ${parentName}JsonHandler::${enumName}JsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { + IJsonHandler* ${parentName}JsonHandler::${enumName}JsonHandler::String(const char* str, size_t /*length*/, bool /*copy*/) { using namespace std::string_literals; assert(this->_pEnum); From 1c8bdac5eced9fab003182501c6b48ca6d050d3f Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 6 Jan 2021 21:54:59 +1100 Subject: [PATCH 22/61] Remove unused submodules. --- extern/cgltf | 1 - extern/simdjson | 1 - 2 files changed, 2 deletions(-) delete mode 160000 extern/cgltf delete mode 160000 extern/simdjson diff --git a/extern/cgltf b/extern/cgltf deleted file mode 160000 index c878edca3..000000000 --- a/extern/cgltf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c878edca3c025784ae103e1faadd4d1432dcd367 diff --git a/extern/simdjson b/extern/simdjson deleted file mode 160000 index f785f76d9..000000000 --- a/extern/simdjson +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f785f76d983d778befbed3730c3e7d0c3a6983de From c153c4c0bb361b88c494d5a8af18c5d80402c534 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 6 Jan 2021 22:44:42 +1100 Subject: [PATCH 23/61] Fix test failure. --- CesiumGltf/test/TestGltfModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltf/test/TestGltfModel.cpp index 220242b66..20953869d 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltf/test/TestGltfModel.cpp @@ -13,7 +13,7 @@ TEST_CASE("GltfModel") { "{"s + " \"accessors\": ["s + " {"s + - " \"count\": 4.0,"s + //{\"test\":true},"s + + " \"count\": 4,"s + //{\"test\":true},"s + " \"componentType\":5121,"s + " \"type\":\"VEC2\","s + " \"max\":[1.0, 2.2, 3.3],"s + From bd0290bec8f96311bcee14ea2576840a7bd7b3ba Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 7 Jan 2021 13:54:25 +1100 Subject: [PATCH 24/61] Generated doc improvements. --- CesiumGltf/include/CesiumGltf/Accessor.h | 10 +- .../CesiumGltf/AccessorSparseIndices.h | 2 +- .../include/CesiumGltf/AnimationSampler.h | 4 +- CesiumGltf/include/CesiumGltf/Buffer.h | 2 +- CesiumGltf/include/CesiumGltf/Camera.h | 2 +- .../include/CesiumGltf/CameraPerspective.h | 6 +- CesiumGltf/include/CesiumGltf/Image.h | 2 +- CesiumGltf/include/CesiumGltf/Material.h | 4 +- .../CesiumGltf/MaterialOcclusionTextureInfo.h | 2 +- .../CesiumGltf/MaterialPBRMetallicRoughness.h | 8 +- CesiumGltf/include/CesiumGltf/MeshPrimitive.h | 2 +- CesiumGltf/include/CesiumGltf/Model.h | 18 +-- CesiumGltf/include/CesiumGltf/Node.h | 4 +- CesiumGltf/include/CesiumGltf/Sampler.h | 4 +- CesiumGltf/include/CesiumGltf/Skin.h | 4 +- doc/CMakeLists.txt | 10 +- .../generate-gltf-classes/resolveProperty.js | 105 ++++++++++++++---- 17 files changed, 127 insertions(+), 62 deletions(-) diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index 5f786f91d..6faff6a0f 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -45,21 +45,21 @@ namespace CesiumGltf { /** * @brief The index of the bufferView. * - * The index of the bufferView. When not defined, accessor must be initialized with zeros; `sparse` property or extensions could override zeros with actual values. + * When not defined, accessor must be initialized with zeros; `sparse` property or extensions could override zeros with actual values. */ int32_t bufferView; /** * @brief The offset relative to the start of the bufferView in bytes. * - * The offset relative to the start of the bufferView in bytes. This must be a multiple of the size of the component datatype. + * This must be a multiple of the size of the component datatype. */ int64_t byteOffset; /** * @brief The datatype of components in the attribute. * - * The datatype of components in the attribute. All valid values correspond to WebGL enums. The corresponding typed arrays are `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Uint32Array`, and `Float32Array`, respectively. 5125 (UNSIGNED_INT) is only allowed when the accessor contains indices, i.e., the accessor is only referenced by `primitive.indices`. + * All valid values correspond to WebGL enums. The corresponding typed arrays are `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Uint32Array`, and `Float32Array`, respectively. 5125 (UNSIGNED_INT) is only allowed when the accessor contains indices, i.e., the accessor is only referenced by `primitive.indices`. */ ComponentType componentType; @@ -85,7 +85,7 @@ namespace CesiumGltf { /** * @brief Maximum value of each component in this attribute. * - * Maximum value of each component in this attribute. Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. + * Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. * * `normalized` property has no effect on array values: they always correspond to the actual values stored in the buffer. When accessor is sparse, this property must contain max values of accessor data with sparse substitution applied. */ @@ -94,7 +94,7 @@ namespace CesiumGltf { /** * @brief Minimum value of each component in this attribute. * - * Minimum value of each component in this attribute. Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. + * Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. * * `normalized` property has no effect on array values: they always correspond to the actual values stored in the buffer. When accessor is sparse, this property must contain min values of accessor data with sparse substitution applied. */ diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h index 465b079d0..a618a3b12 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h @@ -31,7 +31,7 @@ namespace CesiumGltf { /** * @brief The indices data type. * - * The indices data type. Valid values correspond to WebGL enums: `5121` (UNSIGNED_BYTE), `5123` (UNSIGNED_SHORT), `5125` (UNSIGNED_INT). + * Valid values correspond to WebGL enums: `5121` (UNSIGNED_BYTE), `5123` (UNSIGNED_SHORT), `5125` (UNSIGNED_INT). */ ComponentType componentType; }; diff --git a/CesiumGltf/include/CesiumGltf/AnimationSampler.h b/CesiumGltf/include/CesiumGltf/AnimationSampler.h index adb88bc57..d37a72ab6 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationSampler.h +++ b/CesiumGltf/include/CesiumGltf/AnimationSampler.h @@ -21,14 +21,12 @@ namespace CesiumGltf { /** * @brief The index of an accessor containing keyframe input values, e.g., time. * - * The index of an accessor containing keyframe input values, e.g., time. That accessor must have componentType `FLOAT`. The values represent time in seconds with `time[0] >= 0.0`, and strictly increasing values, i.e., `time[n + 1] > time[n]`. + * That accessor must have componentType `FLOAT`. The values represent time in seconds with `time[0] >= 0.0`, and strictly increasing values, i.e., `time[n + 1] > time[n]`. */ int32_t input; /** * @brief Interpolation algorithm. - * - * Interpolation algorithm. */ Interpolation interpolation; diff --git a/CesiumGltf/include/CesiumGltf/Buffer.h b/CesiumGltf/include/CesiumGltf/Buffer.h index 35328ec62..317ee6bfc 100644 --- a/CesiumGltf/include/CesiumGltf/Buffer.h +++ b/CesiumGltf/include/CesiumGltf/Buffer.h @@ -15,7 +15,7 @@ namespace CesiumGltf { /** * @brief The uri of the buffer. * - * The uri of the buffer. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. + * Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. */ std::string uri; diff --git a/CesiumGltf/include/CesiumGltf/Camera.h b/CesiumGltf/include/CesiumGltf/Camera.h index 6a105e00b..b7a33f50b 100644 --- a/CesiumGltf/include/CesiumGltf/Camera.h +++ b/CesiumGltf/include/CesiumGltf/Camera.h @@ -30,7 +30,7 @@ namespace CesiumGltf { /** * @brief Specifies if the camera uses a perspective or orthographic projection. * - * Specifies if the camera uses a perspective or orthographic projection. Based on this, either the camera's `perspective` or `orthographic` property will be defined. + * Based on this, either the camera's `perspective` or `orthographic` property will be defined. */ Type type; }; diff --git a/CesiumGltf/include/CesiumGltf/CameraPerspective.h b/CesiumGltf/include/CesiumGltf/CameraPerspective.h index a932592a6..fcf857a26 100644 --- a/CesiumGltf/include/CesiumGltf/CameraPerspective.h +++ b/CesiumGltf/include/CesiumGltf/CameraPerspective.h @@ -13,7 +13,7 @@ namespace CesiumGltf { /** * @brief The floating-point aspect ratio of the field of view. * - * The floating-point aspect ratio of the field of view. When this is undefined, the aspect ratio of the canvas is used. + * When this is undefined, the aspect ratio of the canvas is used. */ double aspectRatio; @@ -25,14 +25,12 @@ namespace CesiumGltf { /** * @brief The floating-point distance to the far clipping plane. * - * The floating-point distance to the far clipping plane. When defined, `zfar` must be greater than `znear`. If `zfar` is undefined, runtime must use infinite projection matrix. + * When defined, `zfar` must be greater than `znear`. If `zfar` is undefined, runtime must use infinite projection matrix. */ double zfar; /** * @brief The floating-point distance to the near clipping plane. - * - * The floating-point distance to the near clipping plane. */ double znear; }; diff --git a/CesiumGltf/include/CesiumGltf/Image.h b/CesiumGltf/include/CesiumGltf/Image.h index 66a387d12..21f4f3f84 100644 --- a/CesiumGltf/include/CesiumGltf/Image.h +++ b/CesiumGltf/include/CesiumGltf/Image.h @@ -20,7 +20,7 @@ namespace CesiumGltf { /** * @brief The uri of the image. * - * The uri of the image. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. The image format must be jpg or png. + * Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. The image format must be jpg or png. */ std::string uri; diff --git a/CesiumGltf/include/CesiumGltf/Material.h b/CesiumGltf/include/CesiumGltf/Material.h index 4ac2e91ed..89b34a749 100644 --- a/CesiumGltf/include/CesiumGltf/Material.h +++ b/CesiumGltf/include/CesiumGltf/Material.h @@ -37,7 +37,7 @@ namespace CesiumGltf { /** * @brief The occlusion map texture. * - * The occlusion map texture. The occlusion values are sampled from the R channel. Higher values indicate areas that should receive full indirect lighting and lower values indicate no indirect lighting. These values are linear. If other channels are present (GBA), they are ignored for occlusion calculations. + * The occlusion values are sampled from the R channel. Higher values indicate areas that should receive full indirect lighting and lower values indicate no indirect lighting. These values are linear. If other channels are present (GBA), they are ignored for occlusion calculations. */ MaterialOcclusionTextureInfo occlusionTexture; @@ -72,7 +72,7 @@ namespace CesiumGltf { /** * @brief Specifies whether the material is double sided. * - * Specifies whether the material is double sided. When this value is false, back-face culling is enabled. When this value is true, back-face culling is disabled and double sided lighting is enabled. The back-face must have its normals reversed before the lighting equation is evaluated. + * When this value is false, back-face culling is enabled. When this value is true, back-face culling is disabled and double sided lighting is enabled. The back-face must have its normals reversed before the lighting equation is evaluated. */ bool doubleSided; }; diff --git a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h index de4bfbd43..d72fe1660 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h @@ -13,7 +13,7 @@ namespace CesiumGltf { /** * @brief A scalar multiplier controlling the amount of occlusion applied. * - * A scalar multiplier controlling the amount of occlusion applied. A value of 0.0 means no occlusion. A value of 1.0 means full occlusion. This value affects the resulting color using the formula: `occludedColor = lerp(color, color * , )`. This value is ignored if the corresponding texture is not specified. This value is linear. + * A value of 0.0 means no occlusion. A value of 1.0 means full occlusion. This value affects the resulting color using the formula: `occludedColor = lerp(color, color * , )`. This value is ignored if the corresponding texture is not specified. This value is linear. */ double strength; }; diff --git a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h index 5de4ae4dc..caf2f921f 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h +++ b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h @@ -22,28 +22,28 @@ namespace CesiumGltf { /** * @brief The base color texture. * - * The base color texture. The first three components (RGB) are encoded with the sRGB transfer function. They specify the base color of the material. If the fourth component (A) is present, it represents the linear alpha coverage of the material. Otherwise, an alpha of 1.0 is assumed. The `alphaMode` property specifies how alpha is interpreted. The stored texels must not be premultiplied. + * The first three components (RGB) are encoded with the sRGB transfer function. They specify the base color of the material. If the fourth component (A) is present, it represents the linear alpha coverage of the material. Otherwise, an alpha of 1.0 is assumed. The `alphaMode` property specifies how alpha is interpreted. The stored texels must not be premultiplied. */ TextureInfo baseColorTexture; /** * @brief The metalness of the material. * - * The metalness of the material. A value of 1.0 means the material is a metal. A value of 0.0 means the material is a dielectric. Values in between are for blending between metals and dielectrics such as dirty metallic surfaces. This value is linear. If a metallicRoughnessTexture is specified, this value is multiplied with the metallic texel values. + * A value of 1.0 means the material is a metal. A value of 0.0 means the material is a dielectric. Values in between are for blending between metals and dielectrics such as dirty metallic surfaces. This value is linear. If a metallicRoughnessTexture is specified, this value is multiplied with the metallic texel values. */ double metallicFactor; /** * @brief The roughness of the material. * - * The roughness of the material. A value of 1.0 means the material is completely rough. A value of 0.0 means the material is completely smooth. This value is linear. If a metallicRoughnessTexture is specified, this value is multiplied with the roughness texel values. + * A value of 1.0 means the material is completely rough. A value of 0.0 means the material is completely smooth. This value is linear. If a metallicRoughnessTexture is specified, this value is multiplied with the roughness texel values. */ double roughnessFactor; /** * @brief The metallic-roughness texture. * - * The metallic-roughness texture. The metalness values are sampled from the B channel. The roughness values are sampled from the G channel. These values are linear. If other channels are present (R or A), they are ignored for metallic-roughness calculations. + * The metalness values are sampled from the B channel. The roughness values are sampled from the G channel. These values are linear. If other channels are present (R or A), they are ignored for metallic-roughness calculations. */ TextureInfo metallicRoughnessTexture; }; diff --git a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h index 13a23a1bd..fd25fc977 100644 --- a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h +++ b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h @@ -48,7 +48,7 @@ namespace CesiumGltf { /** * @brief The type of primitives to render. * - * The type of primitives to render. All valid values correspond to WebGL enums. + * All valid values correspond to WebGL enums. */ Mode mode; diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index 16f40a8c7..922a17f69 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -40,7 +40,7 @@ namespace CesiumGltf { /** * @brief An array of accessors. * - * An array of accessors. An accessor is a typed view into a bufferView. + * An accessor is a typed view into a bufferView. */ std::vector accessors; @@ -57,42 +57,42 @@ namespace CesiumGltf { /** * @brief An array of buffers. * - * An array of buffers. A buffer points to binary geometry, animation, or skins. + * A buffer points to binary geometry, animation, or skins. */ std::vector buffers; /** * @brief An array of bufferViews. * - * An array of bufferViews. A bufferView is a view into a buffer generally representing a subset of the buffer. + * A bufferView is a view into a buffer generally representing a subset of the buffer. */ std::vector bufferViews; /** * @brief An array of cameras. * - * An array of cameras. A camera defines a projection matrix. + * A camera defines a projection matrix. */ std::vector cameras; /** * @brief An array of images. * - * An array of images. An image defines data used to create a texture. + * An image defines data used to create a texture. */ std::vector images; /** * @brief An array of materials. * - * An array of materials. A material defines the appearance of a primitive. + * A material defines the appearance of a primitive. */ std::vector materials; /** * @brief An array of meshes. * - * An array of meshes. A mesh is a set of primitives to be rendered. + * A mesh is a set of primitives to be rendered. */ std::vector meshes; @@ -104,7 +104,7 @@ namespace CesiumGltf { /** * @brief An array of samplers. * - * An array of samplers. A sampler contains properties for texture filtering and wrapping modes. + * A sampler contains properties for texture filtering and wrapping modes. */ std::vector samplers; @@ -121,7 +121,7 @@ namespace CesiumGltf { /** * @brief An array of skins. * - * An array of skins. A skin is defined by joints and matrices. + * A skin is defined by joints and matrices. */ std::vector skins; diff --git a/CesiumGltf/include/CesiumGltf/Node.h b/CesiumGltf/include/CesiumGltf/Node.h index 6e354a1bb..abb3ab325 100644 --- a/CesiumGltf/include/CesiumGltf/Node.h +++ b/CesiumGltf/include/CesiumGltf/Node.h @@ -25,14 +25,12 @@ namespace CesiumGltf { /** * @brief The index of the skin referenced by this node. * - * The index of the skin referenced by this node. When a skin is referenced by a node within a scene, all joints used by the skin must belong to the same scene. + * When a skin is referenced by a node within a scene, all joints used by the skin must belong to the same scene. */ int32_t skin; /** * @brief A floating-point 4x4 transformation matrix stored in column-major order. - * - * A floating-point 4x4 transformation matrix stored in column-major order. */ std::vector matrix; diff --git a/CesiumGltf/include/CesiumGltf/Sampler.h b/CesiumGltf/include/CesiumGltf/Sampler.h index 9701909a1..4128d6322 100644 --- a/CesiumGltf/include/CesiumGltf/Sampler.h +++ b/CesiumGltf/include/CesiumGltf/Sampler.h @@ -48,14 +48,14 @@ namespace CesiumGltf { /** * @brief Magnification filter. * - * Magnification filter. Valid values correspond to WebGL enums: `9728` (NEAREST) and `9729` (LINEAR). + * Valid values correspond to WebGL enums: `9728` (NEAREST) and `9729` (LINEAR). */ MagFilter magFilter; /** * @brief Minification filter. * - * Minification filter. All valid values correspond to WebGL enums. + * All valid values correspond to WebGL enums. */ MinFilter minFilter; diff --git a/CesiumGltf/include/CesiumGltf/Skin.h b/CesiumGltf/include/CesiumGltf/Skin.h index c9cb1777d..7741316ae 100644 --- a/CesiumGltf/include/CesiumGltf/Skin.h +++ b/CesiumGltf/include/CesiumGltf/Skin.h @@ -20,14 +20,14 @@ namespace CesiumGltf { /** * @brief The index of the node used as a skeleton root. * - * The index of the node used as a skeleton root. The node must be the closest common root of the joints hierarchy or a direct or indirect parent node of the closest common root. + * The node must be the closest common root of the joints hierarchy or a direct or indirect parent node of the closest common root. */ int32_t skeleton; /** * @brief Indices of skeleton nodes, used as joints in this skin. * - * Indices of skeleton nodes, used as joints in this skin. The array length must be the same as the `count` property of the `inverseBindMatrices` accessor (when defined). + * The array length must be the same as the `count` property of the `inverseBindMatrices` accessor (when defined). */ std::vector joints; }; diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 1112d9141..ce259489e 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -4,8 +4,11 @@ if (DOXYGEN_FOUND) set( LIB_DIRS ../Cesium3DTiles/include - ../CesiumGeospatial/include + ../CesiumAsync/include ../CesiumGeometry/include + ../CesiumGeospatial/include + ../CesiumGltf/include + ../CesiumGltfReader/include ../CesiumUtility/include ) @@ -13,8 +16,11 @@ if (DOXYGEN_FOUND) set( DOXYGEN_EXAMPLE_PATH ../Cesium3DTiles/test - ../CesiumGeospatial/test + ../CesiumAsync/test ../CesiumGeometry/test + ../CesiumGeospatial/test + ../CesiumGltf/test + ../CesiumGltfReader/test ../CesiumUtility/test ) diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index 8d1701b3d..732ba7e6a 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -29,7 +29,7 @@ function resolveProperty( headers: [""], type: "int64_t", readerHeaders: [`"IntegerJsonHandler.h"`], - readerType: "IntegerJsonHandler" + readerType: "IntegerJsonHandler", }; } else if (propertyDetails.type == "number") { return { @@ -94,7 +94,7 @@ function resolveProperty( headers: [`"CesiumGltf/${type}.h"`], readerType: `${type}JsonHandler`, readerHeaders: [`"${type}JsonHandler.h"`], - schemas: [itemSchema] + schemas: [itemSchema], }; } } else if (propertyDetails.allOf && propertyDetails.allOf.length == 1) { @@ -105,9 +105,12 @@ function resolveProperty( propertyName, propertyDetails.allOf[0] ); - nested.briefDoc = propertyDetails.description; - nested.fullDoc = propertyDetails.gltf_detailedDescription; - return nested; + + return { + ...nested, + briefDoc: propertyDefaults(propertyName, propertyDetails).briefDoc, + fullDoc: propertyDefaults(propertyName, propertyDetails).fullDoc, + }; } else { console.warn(`Skipping unhandled property ${propertyName}.`); return undefined; @@ -123,6 +126,15 @@ function toPascalCase(name) { } function propertyDefaults(propertyName, propertyDetails) { + const fullDoc = + propertyDetails.gltf_detailedDescription && + propertyDetails.gltf_detailedDescription.indexOf( + propertyDetails.description + ) === 0 + ? propertyDetails.gltf_detailedDescription + .substr(propertyDetails.description.length) + .trim() + : propertyDetails.gltf_detailedDescription; return { name: propertyName, headers: [], @@ -134,11 +146,17 @@ function propertyDefaults(propertyName, propertyDetails) { readerLocalTypes: [], readerLocalTypesImpl: [], briefDoc: propertyDetails.description, - fullDoc: propertyDetails.gltf_detailedDescription, + fullDoc: fullDoc, }; } -function resolveArray(schemaCache, nameMapping, parentName, propertyName, propertyDetails) { +function resolveArray( + schemaCache, + nameMapping, + parentName, + propertyName, + propertyDetails +) { const itemProperty = resolveProperty( schemaCache, nameMapping, @@ -159,11 +177,17 @@ function resolveArray(schemaCache, nameMapping, parentName, propertyName, proper localTypes: itemProperty.localTypes, type: `std::vector<${itemProperty.type}>`, readerHeaders: [`"ArrayJsonHandler.h"`, ...itemProperty.readerHeaders], - readerType: `ArrayJsonHandler<${itemProperty.type}, ${itemProperty.readerType}>` + readerType: `ArrayJsonHandler<${itemProperty.type}, ${itemProperty.readerType}>`, }; } -function resolveDictionary(schemaCache, nameMapping, parentName, propertyName, propertyDetails) { +function resolveDictionary( + schemaCache, + nameMapping, + parentName, + propertyName, + propertyDetails +) { const additional = resolveProperty( schemaCache, nameMapping, @@ -184,18 +208,34 @@ function resolveDictionary(schemaCache, nameMapping, parentName, propertyName, p localTypes: additional.localTypes, type: `std::unordered_map`, readerHeaders: [`"DictionaryJsonHandler.h"`, ...additional.readerHeaders], - readerType: `DictionaryJsonHandler<${additional.type}, ${additional.readerType}>` + readerType: `DictionaryJsonHandler<${additional.type}, ${additional.readerType}>`, }; } -function resolveEnum(schemaCache, nameMapping, parentName, propertyName, propertyDetails) { - if (!propertyDetails.anyOf || propertyDetails.anyOf.length === 0 || !propertyDetails.anyOf[0].enum || propertyDetails.anyOf[0].enum.length === 0) { +function resolveEnum( + schemaCache, + nameMapping, + parentName, + propertyName, + propertyDetails +) { + if ( + !propertyDetails.anyOf || + propertyDetails.anyOf.length === 0 || + !propertyDetails.anyOf[0].enum || + propertyDetails.anyOf[0].enum.length === 0 + ) { return undefined; } const enumName = toPascalCase(propertyName); - const readerTypes = createEnumReaderType(parentName, enumName, propertyName, propertyDetails); + const readerTypes = createEnumReaderType( + parentName, + enumName, + propertyName, + propertyDetails + ); const result = { ...propertyDefaults(propertyName, propertyDetails), @@ -210,12 +250,17 @@ function resolveEnum(schemaCache, nameMapping, parentName, propertyName, propert 12 )} }; - `) + `), ], type: enumName, readerHeaders: [`"CesiumGltf/${parentName}.h"`], readerLocalTypes: readerTypes, - readerLocalTypesImpl: createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDetails) + readerLocalTypesImpl: createEnumReaderTypeImpl( + parentName, + enumName, + propertyName, + propertyDetails + ), }; if (readerTypes.length > 0) { @@ -234,13 +279,20 @@ function createEnum(enumDetails) { } if (enumDetails.type === "integer") { - return `${makeIdentifier(enumDetails.description)} = ${enumDetails.enum[0]}`; + return `${makeIdentifier(enumDetails.description)} = ${ + enumDetails.enum[0] + }`; } else { return makeIdentifier(enumDetails.enum[0]); } } -function createEnumReaderType(parentName, enumName, propertyName, propertyDetails) { +function createEnumReaderType( + parentName, + enumName, + propertyName, + propertyDetails +) { if (propertyDetails.anyOf[0].type === "integer") { // No special reader needed for integer enums. return []; @@ -258,7 +310,12 @@ function createEnumReaderType(parentName, enumName, propertyName, propertyDetail `); } -function createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDetails) { +function createEnumReaderTypeImpl( + parentName, + enumName, + propertyName, + propertyDetails +) { if (propertyDetails.anyOf[0].type === "integer") { // No special reader needed for integer enums. return []; @@ -277,8 +334,16 @@ function createEnumReaderTypeImpl(parentName, enumName, propertyName, propertyDe ${indent( propertyDetails.anyOf - .map((e) => e.enum && e.enum[0] !== undefined ? `if ("${e.enum[0]}"s == str) *this->_pEnum = ${parentName}::${enumName}::${makeIdentifier(e.enum[0])};` : undefined) - .filter(s => s !== undefined) + .map((e) => + e.enum && e.enum[0] !== undefined + ? `if ("${ + e.enum[0] + }"s == str) *this->_pEnum = ${parentName}::${enumName}::${makeIdentifier( + e.enum[0] + )};` + : undefined + ) + .filter((s) => s !== undefined) .join("\nelse "), 6 )} From 3f6e301acf2853f7ea452f4101fc618a4eb7192b Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 7 Jan 2021 22:17:55 +1100 Subject: [PATCH 25/61] GLB support. --- CesiumGltf/include/CesiumGltf/Accessor.h | 1 + .../include/CesiumGltf/AccessorSparse.h | 1 + .../CesiumGltf/AccessorSparseIndices.h | 1 + .../include/CesiumGltf/AccessorSparseValues.h | 1 + CesiumGltf/include/CesiumGltf/Animation.h | 1 + .../include/CesiumGltf/AnimationChannel.h | 1 + .../CesiumGltf/AnimationChannelTarget.h | 1 + .../include/CesiumGltf/AnimationSampler.h | 1 + CesiumGltf/include/CesiumGltf/Asset.h | 1 + CesiumGltf/include/CesiumGltf/Buffer.h | 7 + CesiumGltf/include/CesiumGltf/BufferCesium.h | 12 + CesiumGltf/include/CesiumGltf/BufferView.h | 1 + CesiumGltf/include/CesiumGltf/Camera.h | 1 + .../include/CesiumGltf/CameraOrthographic.h | 1 + .../include/CesiumGltf/CameraPerspective.h | 1 + CesiumGltf/include/CesiumGltf/Image.h | 7 + CesiumGltf/include/CesiumGltf/ImageCesium.h | 48 ++++ CesiumGltf/include/CesiumGltf/Material.h | 1 + .../CesiumGltf/MaterialNormalTextureInfo.h | 1 + .../CesiumGltf/MaterialOcclusionTextureInfo.h | 1 + .../CesiumGltf/MaterialPBRMetallicRoughness.h | 1 + CesiumGltf/include/CesiumGltf/Mesh.h | 1 + CesiumGltf/include/CesiumGltf/MeshPrimitive.h | 1 + CesiumGltf/include/CesiumGltf/Model.h | 1 + CesiumGltf/include/CesiumGltf/Node.h | 1 + CesiumGltf/include/CesiumGltf/Sampler.h | 1 + CesiumGltf/include/CesiumGltf/Scene.h | 1 + CesiumGltf/include/CesiumGltf/Skin.h | 1 + CesiumGltf/include/CesiumGltf/Texture.h | 1 + CesiumGltf/include/CesiumGltf/TextureInfo.h | 1 + CesiumGltfReader/src/Reader.cpp | 258 +++++++++++++----- tools/generate-gltf-classes/generate.js | 22 +- tools/generate-gltf-classes/index.js | 8 + 33 files changed, 321 insertions(+), 67 deletions(-) create mode 100644 CesiumGltf/include/CesiumGltf/BufferCesium.h create mode 100644 CesiumGltf/include/CesiumGltf/ImageCesium.h diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index 6faff6a0f..efe4fcdbe 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -104,5 +104,6 @@ namespace CesiumGltf { * @brief Sparse storage of attributes that deviate from their initialization value. */ AccessorSparse sparse; + }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparse.h b/CesiumGltf/include/CesiumGltf/AccessorSparse.h index 480a6b158..6fd82c12e 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparse.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparse.h @@ -29,5 +29,6 @@ namespace CesiumGltf { * @brief Array of size `count` times number of components, storing the displaced accessor attributes pointed by `indices`. Substituted values must have the same `componentType` and number of components as the base accessor. */ AccessorSparseValues values; + }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h index a618a3b12..4ef007b8a 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h @@ -34,5 +34,6 @@ namespace CesiumGltf { * Valid values correspond to WebGL enums: `5121` (UNSIGNED_BYTE), `5123` (UNSIGNED_SHORT), `5125` (UNSIGNED_INT). */ ComponentType componentType; + }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h index a5d4e7c93..5be53822a 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h @@ -20,5 +20,6 @@ namespace CesiumGltf { * @brief The offset relative to the start of the bufferView in bytes. Must be aligned. */ int64_t byteOffset; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Animation.h b/CesiumGltf/include/CesiumGltf/Animation.h index c3c559f7b..58625aaf2 100644 --- a/CesiumGltf/include/CesiumGltf/Animation.h +++ b/CesiumGltf/include/CesiumGltf/Animation.h @@ -22,5 +22,6 @@ namespace CesiumGltf { * @brief An array of samplers that combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target). */ std::vector samplers; + }; } diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannel.h b/CesiumGltf/include/CesiumGltf/AnimationChannel.h index 728f10e22..ce8493e69 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationChannel.h +++ b/CesiumGltf/include/CesiumGltf/AnimationChannel.h @@ -23,5 +23,6 @@ namespace CesiumGltf { * @brief The index of the node and TRS property to target. */ AnimationChannelTarget target; + }; } diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h index 7150052a5..76c6d0c0a 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h +++ b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h @@ -29,5 +29,6 @@ namespace CesiumGltf { * @brief The name of the node's TRS property to modify, or the "weights" of the Morph Targets it instantiates. For the "translation" property, the values that are provided by the sampler are the translation along the x, y, and z axes. For the "rotation" property, the values are a quaternion in the order (x, y, z, w), where w is the scalar. For the "scale" property, the values are the scaling factors along the x, y, and z axes. */ Path path; + }; } diff --git a/CesiumGltf/include/CesiumGltf/AnimationSampler.h b/CesiumGltf/include/CesiumGltf/AnimationSampler.h index d37a72ab6..9faf5b913 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationSampler.h +++ b/CesiumGltf/include/CesiumGltf/AnimationSampler.h @@ -36,5 +36,6 @@ namespace CesiumGltf { * The index of an accessor containing keyframe output values. When targeting translation or scale paths, the `accessor.componentType` of the output values must be `FLOAT`. When targeting rotation or morph weights, the `accessor.componentType` of the output values must be `FLOAT` or normalized integer. For weights, each output element stores `SCALAR` values with a count equal to the number of morph targets. */ int32_t output; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Asset.h b/CesiumGltf/include/CesiumGltf/Asset.h index ec164ee58..c314358f2 100644 --- a/CesiumGltf/include/CesiumGltf/Asset.h +++ b/CesiumGltf/include/CesiumGltf/Asset.h @@ -30,5 +30,6 @@ namespace CesiumGltf { * @brief The minimum glTF version that this asset targets. */ std::string minVersion; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Buffer.h b/CesiumGltf/include/CesiumGltf/Buffer.h index 317ee6bfc..a0a91210a 100644 --- a/CesiumGltf/include/CesiumGltf/Buffer.h +++ b/CesiumGltf/include/CesiumGltf/Buffer.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/BufferCesium.h" #include "CesiumGltf/NamedObject.h" #include #include @@ -23,5 +24,11 @@ namespace CesiumGltf { * @brief The length of the buffer in bytes. */ int64_t byteLength; + + /** + * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. + */ + BufferCesium cesium; + }; } diff --git a/CesiumGltf/include/CesiumGltf/BufferCesium.h b/CesiumGltf/include/CesiumGltf/BufferCesium.h new file mode 100644 index 000000000..dce15adeb --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/BufferCesium.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace CesiumGltf { + struct BufferCesium final { + /** + * @brief The buffer's data. + */ + std::vector data; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/BufferView.h b/CesiumGltf/include/CesiumGltf/BufferView.h index 7dc2354be..ca04c032e 100644 --- a/CesiumGltf/include/CesiumGltf/BufferView.h +++ b/CesiumGltf/include/CesiumGltf/BufferView.h @@ -42,5 +42,6 @@ namespace CesiumGltf { * @brief The target that the GPU buffer should be bound to. */ Target target; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Camera.h b/CesiumGltf/include/CesiumGltf/Camera.h index b7a33f50b..c78d0d2da 100644 --- a/CesiumGltf/include/CesiumGltf/Camera.h +++ b/CesiumGltf/include/CesiumGltf/Camera.h @@ -33,5 +33,6 @@ namespace CesiumGltf { * Based on this, either the camera's `perspective` or `orthographic` property will be defined. */ Type type; + }; } diff --git a/CesiumGltf/include/CesiumGltf/CameraOrthographic.h b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h index 2dc403cfe..b2cb7c24b 100644 --- a/CesiumGltf/include/CesiumGltf/CameraOrthographic.h +++ b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h @@ -29,5 +29,6 @@ namespace CesiumGltf { * @brief The floating-point distance to the near clipping plane. */ double znear; + }; } diff --git a/CesiumGltf/include/CesiumGltf/CameraPerspective.h b/CesiumGltf/include/CesiumGltf/CameraPerspective.h index fcf857a26..abac81114 100644 --- a/CesiumGltf/include/CesiumGltf/CameraPerspective.h +++ b/CesiumGltf/include/CesiumGltf/CameraPerspective.h @@ -33,5 +33,6 @@ namespace CesiumGltf { * @brief The floating-point distance to the near clipping plane. */ double znear; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Image.h b/CesiumGltf/include/CesiumGltf/Image.h index 21f4f3f84..21630ffa0 100644 --- a/CesiumGltf/include/CesiumGltf/Image.h +++ b/CesiumGltf/include/CesiumGltf/Image.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/ImageCesium.h" #include "CesiumGltf/NamedObject.h" #include #include @@ -33,5 +34,11 @@ namespace CesiumGltf { * @brief The index of the bufferView that contains the image. Use this instead of the image's uri property. */ int32_t bufferView; + + /** + * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. + */ + ImageCesium cesium; + }; } diff --git a/CesiumGltf/include/CesiumGltf/ImageCesium.h b/CesiumGltf/include/CesiumGltf/ImageCesium.h new file mode 100644 index 000000000..f955dbc33 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/ImageCesium.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include + +namespace CesiumGltf { + struct ImageCesium final { + /** + * @brief The width of the image in pixels. + */ + int32_t width; + + /** + * @brief The height of the image in pixels. + */ + int32_t height; + + /** + * @brief The number of channels per pixel. + */ + int32_t channels; + + /** + * @brief The number of bytes per channel. + */ + int32_t bytesPerChannel; + + /** + * @brief The raw pixel data. + * + * The pixel data is consistent with the [stb](https://github.com/nothings/stb) image library. + * + * For a correctly-formed image, the size of the array will be + * `width * height * channels * bytesPerChannel` bytes. There is no + * padding between rows or columns of the image, regardless of format. + * + * The channels and their meaning are as follows: + * + * | Number of Channels | Channel Meaning | + * |--------------------|-------------------------| + * | 1 | grey | + * | 2 | grey, alpha | + * | 3 | red, green, blue | + * | 4 | red, green, blue, alpha | + */ + std::vector pixelData; + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Material.h b/CesiumGltf/include/CesiumGltf/Material.h index 89b34a749..b450e3ed4 100644 --- a/CesiumGltf/include/CesiumGltf/Material.h +++ b/CesiumGltf/include/CesiumGltf/Material.h @@ -75,5 +75,6 @@ namespace CesiumGltf { * When this value is false, back-face culling is enabled. When this value is true, back-face culling is disabled and double sided lighting is enabled. The back-face must have its normals reversed before the lighting equation is evaluated. */ bool doubleSided; + }; } diff --git a/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h index 27e8409c4..ba16981b9 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h @@ -16,5 +16,6 @@ namespace CesiumGltf { * The scalar multiplier applied to each normal vector of the texture. This value scales the normal vector using the formula: `scaledNormal = normalize(( * 2.0 - 1.0) * vec3(, , 1.0))`. This value is ignored if normalTexture is not specified. This value is linear. */ double scale; + }; } diff --git a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h index d72fe1660..ed1c1c9c4 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h @@ -16,5 +16,6 @@ namespace CesiumGltf { * A value of 0.0 means no occlusion. A value of 1.0 means full occlusion. This value affects the resulting color using the formula: `occludedColor = lerp(color, color * , )`. This value is ignored if the corresponding texture is not specified. This value is linear. */ double strength; + }; } diff --git a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h index caf2f921f..54dba0c67 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h +++ b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h @@ -46,5 +46,6 @@ namespace CesiumGltf { * The metalness values are sampled from the B channel. The roughness values are sampled from the G channel. These values are linear. If other channels are present (R or A), they are ignored for metallic-roughness calculations. */ TextureInfo metallicRoughnessTexture; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Mesh.h b/CesiumGltf/include/CesiumGltf/Mesh.h index 97927b7df..45ce7e33b 100644 --- a/CesiumGltf/include/CesiumGltf/Mesh.h +++ b/CesiumGltf/include/CesiumGltf/Mesh.h @@ -21,5 +21,6 @@ namespace CesiumGltf { * @brief Array of weights to be applied to the Morph Targets. */ std::vector weights; + }; } diff --git a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h index fd25fc977..b2d027cb1 100644 --- a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h +++ b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h @@ -56,5 +56,6 @@ namespace CesiumGltf { * @brief An array of Morph Targets, each Morph Target is a dictionary mapping attributes (only `POSITION`, `NORMAL`, and `TANGENT` supported) to their deviations in the Morph Target. */ std::vector> targets; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index 922a17f69..28da2fe74 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -129,5 +129,6 @@ namespace CesiumGltf { * @brief An array of textures. */ std::vector textures; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Node.h b/CesiumGltf/include/CesiumGltf/Node.h index abb3ab325..cb8bcc374 100644 --- a/CesiumGltf/include/CesiumGltf/Node.h +++ b/CesiumGltf/include/CesiumGltf/Node.h @@ -58,5 +58,6 @@ namespace CesiumGltf { * @brief The weights of the instantiated Morph Target. Number of elements must match number of Morph Targets of used mesh. */ std::vector weights; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Sampler.h b/CesiumGltf/include/CesiumGltf/Sampler.h index 4128d6322..032e48208 100644 --- a/CesiumGltf/include/CesiumGltf/Sampler.h +++ b/CesiumGltf/include/CesiumGltf/Sampler.h @@ -72,5 +72,6 @@ namespace CesiumGltf { * T (V) wrapping mode. All valid values correspond to WebGL enums. */ WrapT wrapT; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Scene.h b/CesiumGltf/include/CesiumGltf/Scene.h index 16f7e0a83..fc6661c96 100644 --- a/CesiumGltf/include/CesiumGltf/Scene.h +++ b/CesiumGltf/include/CesiumGltf/Scene.h @@ -16,5 +16,6 @@ namespace CesiumGltf { * @brief The indices of each root node. */ std::vector nodes; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Skin.h b/CesiumGltf/include/CesiumGltf/Skin.h index 7741316ae..a70825757 100644 --- a/CesiumGltf/include/CesiumGltf/Skin.h +++ b/CesiumGltf/include/CesiumGltf/Skin.h @@ -30,5 +30,6 @@ namespace CesiumGltf { * The array length must be the same as the `count` property of the `inverseBindMatrices` accessor (when defined). */ std::vector joints; + }; } diff --git a/CesiumGltf/include/CesiumGltf/Texture.h b/CesiumGltf/include/CesiumGltf/Texture.h index 5c369e26e..5775de335 100644 --- a/CesiumGltf/include/CesiumGltf/Texture.h +++ b/CesiumGltf/include/CesiumGltf/Texture.h @@ -20,5 +20,6 @@ namespace CesiumGltf { * @brief The index of the image used by this texture. When undefined, it is expected that an extension or other mechanism will supply an alternate texture source, otherwise behavior is undefined. */ int32_t source; + }; } diff --git a/CesiumGltf/include/CesiumGltf/TextureInfo.h b/CesiumGltf/include/CesiumGltf/TextureInfo.h index 27e7bae2b..e0e0a7a54 100644 --- a/CesiumGltf/include/CesiumGltf/TextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/TextureInfo.h @@ -22,5 +22,6 @@ namespace CesiumGltf { * This integer value is used to construct a string in the format `TEXCOORD_` which is a reference to a key in mesh.primitives.attributes (e.g. A value of `0` corresponds to `TEXCOORD_0`). Mesh must have corresponding texture coordinate attributes for the material to be applicable to it. */ int64_t texCoord; + }; } diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 5070fe060..0acd8ef46 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -63,94 +63,220 @@ namespace { ModelReaderResult& _result; rapidjson::MemoryStream& _inputStream; }; -} - -ModelReaderResult CesiumGltf::readModel(const gsl::span& data) { - rapidjson::Reader reader; - rapidjson::MemoryStream inputStream(reinterpret_cast(data.data()), data.size()); - - ModelReaderResult result; - ModelJsonHandler modelHandler; - FinalJsonHandler finalHandler(result, inputStream); - Dispatcher dispatcher { &modelHandler }; - - result.model.emplace(); - modelHandler.reset(&finalHandler, &result.model.value()); - - reader.IterativeParseInit(); - - bool success = true; - while (success && !reader.IterativeParseComplete()) { - success = reader.IterativeParseNext(inputStream, dispatcher); - } - if (reader.HasParseError()) { - result.model.reset(); - - std::string s("glTF JSON parsing error at byte offset "); - s += std::to_string(reader.GetErrorOffset()); - s += ": "; - - switch (reader.GetParseErrorCode()) { + std::string getMessageFromRapidJsonError(rapidjson::ParseErrorCode code) { + switch (code) { case rapidjson::ParseErrorCode::kParseErrorDocumentEmpty: - s += "The document is empty."; - break; + return "The document is empty."; case rapidjson::ParseErrorCode::kParseErrorDocumentRootNotSingular: - s += "The document root must not be followed by other values."; - break; + return "The document root must not be followed by other values."; case rapidjson::ParseErrorCode::kParseErrorValueInvalid: - s += "Invalid value."; - break; + return "Invalid value."; case rapidjson::ParseErrorCode::kParseErrorObjectMissName: - s += "Missing a name for object member."; - break; + return "Missing a name for object member."; case rapidjson::ParseErrorCode::kParseErrorObjectMissColon: - s += "Missing a colon after a name of object member."; - break; + return "Missing a colon after a name of object member."; case rapidjson::ParseErrorCode::kParseErrorObjectMissCommaOrCurlyBracket: - s += "Missing a comma or '}' after an object member."; - break; + return "Missing a comma or '}' after an object member."; case rapidjson::ParseErrorCode::kParseErrorArrayMissCommaOrSquareBracket: - s += "Missing a comma or ']' after an array element."; - break; + return "Missing a comma or ']' after an array element."; case rapidjson::ParseErrorCode::kParseErrorStringUnicodeEscapeInvalidHex: - s += "Incorrect hex digit after \\u escape in string."; - break; + return "Incorrect hex digit after \\u escape in string."; case rapidjson::ParseErrorCode::kParseErrorStringUnicodeSurrogateInvalid: - s += "The surrogate pair in string is invalid."; - break; + return "The surrogate pair in string is invalid."; case rapidjson::ParseErrorCode::kParseErrorStringEscapeInvalid: - s += "Invalid escape character in string."; - break; + return "Invalid escape character in string."; case rapidjson::ParseErrorCode::kParseErrorStringMissQuotationMark: - s += "Missing a closing quotation mark in string."; - break; + return "Missing a closing quotation mark in string."; case rapidjson::ParseErrorCode::kParseErrorStringInvalidEncoding: - s += "Invalid encoding in string."; - break; + return "Invalid encoding in string."; case rapidjson::ParseErrorCode::kParseErrorNumberTooBig: - s += "Number too big to be stored in double."; - break; + return "Number too big to be stored in double."; case rapidjson::ParseErrorCode::kParseErrorNumberMissFraction: - s += "Missing fraction part in number."; - break; + return "Missing fraction part in number."; case rapidjson::ParseErrorCode::kParseErrorNumberMissExponent: - s += "Missing exponent in number."; - break; + return "Missing exponent in number."; case rapidjson::ParseErrorCode::kParseErrorTermination: - s += "Parsing was terminated."; - break; + return "Parsing was terminated."; case rapidjson::ParseErrorCode::kParseErrorUnspecificSyntaxError: default: - s += "Unspecific syntax error."; - break; + return "Unspecific syntax error."; + } + } + + #pragma pack(push, 1) + struct GlbHeader { + uint32_t magic; + uint32_t version; + uint32_t length; + }; + + struct ChunkHeader { + uint32_t chunkLength; + uint32_t chunkType; + }; + #pragma pack(pop) + + bool isBinaryGltf(const gsl::span& data) { + if (data.size() < sizeof(GlbHeader)) { + return false; + } + + return reinterpret_cast(data.data())->magic == 0x46546C67; + } + + ModelReaderResult readJsonModel(const gsl::span& data) { + rapidjson::Reader reader; + rapidjson::MemoryStream inputStream(reinterpret_cast(data.data()), data.size()); + + ModelReaderResult result; + ModelJsonHandler modelHandler; + FinalJsonHandler finalHandler(result, inputStream); + Dispatcher dispatcher { &modelHandler }; + + result.model.emplace(); + modelHandler.reset(&finalHandler, &result.model.value()); + + reader.IterativeParseInit(); + + bool success = true; + while (success && !reader.IterativeParseComplete()) { + success = reader.IterativeParseNext(inputStream, dispatcher); + } + + if (reader.HasParseError()) { + result.model.reset(); + + std::string s("glTF JSON parsing error at byte offset "); + s += std::to_string(reader.GetErrorOffset()); + s += ": "; + s += getMessageFromRapidJsonError(reader.GetParseErrorCode()); + + if (!result.errors.empty()) { + result.errors.push_back('\n'); + } + result.errors += s; + } + + return result; + } + + ModelReaderResult readBinaryModel(const gsl::span& data) { + if (data.size() < sizeof(GlbHeader) + sizeof(ChunkHeader)) { + return { + std::nullopt, + "Too short to be a valid GLB.", + "" + }; + } + + const GlbHeader* pHeader = reinterpret_cast(data.data()); + if (pHeader->magic != 0x46546C67) { + return { + std::nullopt, + "GLB does not start with the expected magic value 'glTF'.", + "" + }; + } + + if (pHeader->version != 2) { + return { + std::nullopt, + "Only binary glTF version 2 is supported.", + "" + }; + } + + if (pHeader->length > data.size()) { + return { + std::nullopt, + "GLB extends past the end of the buffer.", + "" + }; + } + + gsl::span glbData = data.subspan(0, pHeader->length); + + const ChunkHeader* pJsonChunkHeader = reinterpret_cast(glbData.data() + sizeof(GlbHeader)); + if (pJsonChunkHeader->chunkType != 0x4E4F534A) { + return { + std::nullopt, + "GLB JSON chunk does not have the expected chunkType.", + "" + }; + } + + size_t jsonStart = sizeof(GlbHeader) + sizeof(ChunkHeader); + size_t jsonEnd = jsonStart + pJsonChunkHeader->chunkLength; + + if (jsonEnd > glbData.size()) { + return { + std::nullopt, + "GLB JSON chunk extends past the end of the buffer.", + "" + }; + } + + gsl::span jsonChunk = glbData.subspan(jsonStart, pJsonChunkHeader->chunkLength); + gsl::span binaryChunk; + + if (jsonEnd + sizeof(ChunkHeader) <= data.size()) { + const ChunkHeader* pBinaryChunkHeader = reinterpret_cast(glbData.data() + jsonEnd); + if (pJsonChunkHeader->chunkType != 0x004E4942) { + return { + std::nullopt, + "GLB binary chunk does not have the expected chunkType.", + "" + }; + } + + size_t binaryStart = jsonEnd + sizeof(ChunkHeader); + size_t binaryEnd = binaryStart + pBinaryChunkHeader->chunkLength; + + if (binaryEnd > glbData.size()) { + return { + std::nullopt, + "GLB binary chunk extends past the end of the buffer.", + "" + }; + } + + binaryChunk = glbData.subspan(binaryStart, pBinaryChunkHeader->chunkLength); } - if (!result.errors.empty()) { - result.errors.push_back('\n'); + ModelReaderResult result = readJsonModel(jsonChunk); + + if (result.model && !binaryChunk.empty()) { + Model& model = result.model.value(); + + if (model.buffers.size() == 0) { + result.errors = "GLB has a binary chunk but the JSON does not define any buffers."; + return result; + } + + Buffer& buffer = model.buffers[0]; + if (!buffer.uri.empty()) { + result.errors = "GLB has a binary chunk but the first buffer in the JSON chunk also has a 'uri'."; + return result; + } + + int64_t binaryChunkSize = static_cast(binaryChunk.size()); + if (buffer.byteLength > binaryChunkSize || buffer.byteLength + 3 < binaryChunkSize) { + result.errors = "GLB binary chunk size does not match the size of the first buffer in the JSON chunk."; + return result; + } + + buffer.cesium.data = std::vector(binaryChunk.begin(), binaryChunk.begin() + buffer.byteLength); } - result.errors += s; + + return result; } +} - return result; +ModelReaderResult CesiumGltf::readModel(const gsl::span& data) { + if (isBinaryGltf(data)) { + return readBinaryModel(data); + } else { + return readJsonModel(data); + } } diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index d7733cb1c..ef23a26e0 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -7,7 +7,7 @@ const unindent = require("./unindent"); const indent = require("./indent"); function generate(options, schema) { - const { schemaCache, nameMapping, outputDir, readerOutputDir } = options; + const { schemaCache, nameMapping, outputDir, readerOutputDir, cesiumProperties } = options; const name = getNameFromSchema(nameMapping, schema); @@ -31,6 +31,11 @@ function generate(options, schema) { const headers = lodash.uniq( [`"CesiumGltf/${base}Object.h"`, ...lodash.flatten(properties.map((property) => property.headers))] ); + + if (cesiumProperties[name]) { + headers.push(`"CesiumGltf/${name}Cesium.h"`); + } + headers.sort(); const header = ` @@ -53,6 +58,8 @@ function generate(options, schema) { .join("\n\n"), 16 )} + + ${indent(getCesiumProperty(cesiumProperties, name, schema), 16)} }; } `; @@ -187,4 +194,17 @@ function formatReaderPropertyImpl(property) { return `if ("${property.name}"s == str) return property("${property.name}", this->_${property.name}, this->_pObject->${property.name});`; } +function getCesiumProperty(cesiumProperties, name, schema) { + if (!cesiumProperties[name]) { + return ""; + } + + return unindent(` + /** + * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. + */ + ${name}Cesium cesium; + `); +} + module.exports = generate; diff --git a/tools/generate-gltf-classes/index.js b/tools/generate-gltf-classes/index.js index 3a84339db..dacdaae61 100644 --- a/tools/generate-gltf-classes/index.js +++ b/tools/generate-gltf-classes/index.js @@ -30,12 +30,20 @@ const nameMapping = { "glTFRootProperty": "NamedObject" }; +// Custom `cesium` properties will be added to these objects. +// e.g. Buffer will gain `BufferCesium cesium;` +const cesiumProperties = { + "Buffer": true, + "Image": true +}; + const schemaCache = new SchemaCache(argv.schema); const modelSchema = schemaCache.load("glTF.schema.json"); const options = { schemaCache, nameMapping, + cesiumProperties, outputDir: argv.output, readerOutputDir: argv.readerOutput }; From 08d173d57372c161ac5455f3c2aa7ae2a2b2719e Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Fri, 8 Jan 2021 14:09:08 +1100 Subject: [PATCH 26/61] Use CesiumGltf instead of tinygltf. --- Cesium3DTiles/CMakeLists.txt | 5 +- Cesium3DTiles/include/Cesium3DTiles/Gltf.h | 56 ++------- .../include/Cesium3DTiles/GltfAccessor.h | 83 ++++++++++--- .../include/Cesium3DTiles/GltfContent.h | 2 +- .../include/Cesium3DTiles/GltfWriter.h | 20 ++-- .../Cesium3DTiles/IPrepareRendererResources.h | 8 +- .../include/Cesium3DTiles/RasterOverlayTile.h | 4 +- Cesium3DTiles/include/Cesium3DTiles/Tile.h | 2 +- .../Cesium3DTiles/TileContentLoadResult.h | 2 +- Cesium3DTiles/src/Batched3DModelContent.cpp | 52 ++++---- Cesium3DTiles/src/BingMapsRasterOverlay.cpp | 5 + Cesium3DTiles/src/Gltf.cpp | 62 ++++------ Cesium3DTiles/src/GltfContent.cpp | 54 ++++----- Cesium3DTiles/src/QuantizedMeshContent.cpp | 63 +++++----- Cesium3DTiles/src/RasterOverlayTile.cpp | 13 +- .../src/RasterOverlayTileProvider.cpp | 4 +- Cesium3DTiles/src/Tile.cpp | 20 ++-- Cesium3DTiles/src/tinygltf.cpp | 20 ---- .../src/upsampleGltfForRasterOverlays.cpp | 111 +++++++++--------- .../src/upsampleGltfForRasterOverlays.h | 2 +- .../test/TestQuantizedMeshContent.cpp | 24 ++-- CesiumGltf/CMakeLists.txt | 4 +- CesiumGltf/include/CesiumGltf/Accessor.h | 2 +- .../include/CesiumGltf/AccessorSparse.h | 2 +- .../CesiumGltf/AccessorSparseIndices.h | 2 +- .../include/CesiumGltf/AccessorSparseValues.h | 2 +- CesiumGltf/include/CesiumGltf/Animation.h | 2 +- .../include/CesiumGltf/AnimationChannel.h | 2 +- .../CesiumGltf/AnimationChannelTarget.h | 2 +- .../include/CesiumGltf/AnimationSampler.h | 2 +- CesiumGltf/include/CesiumGltf/Asset.h | 2 +- CesiumGltf/include/CesiumGltf/Buffer.h | 2 +- CesiumGltf/include/CesiumGltf/BufferView.h | 2 +- CesiumGltf/include/CesiumGltf/Camera.h | 2 +- .../include/CesiumGltf/CameraOrthographic.h | 2 +- .../include/CesiumGltf/CameraPerspective.h | 2 +- CesiumGltf/include/CesiumGltf/Image.h | 2 +- CesiumGltf/include/CesiumGltf/Material.h | 2 +- .../CesiumGltf/MaterialNormalTextureInfo.h | 4 +- .../CesiumGltf/MaterialOcclusionTextureInfo.h | 4 +- .../CesiumGltf/MaterialPBRMetallicRoughness.h | 2 +- CesiumGltf/include/CesiumGltf/Mesh.h | 2 +- CesiumGltf/include/CesiumGltf/MeshPrimitive.h | 2 +- CesiumGltf/include/CesiumGltf/Model.h | 2 +- CesiumGltf/include/CesiumGltf/Node.h | 2 +- CesiumGltf/include/CesiumGltf/Sampler.h | 2 +- CesiumGltf/include/CesiumGltf/Scene.h | 2 +- CesiumGltf/include/CesiumGltf/Skin.h | 2 +- CesiumGltf/include/CesiumGltf/Texture.h | 2 +- CesiumGltf/include/CesiumGltf/TextureInfo.h | 2 +- CesiumGltfReader/CMakeLists.txt | 2 +- .../generated/AccessorJsonHandler.cpp | 27 +++-- .../generated/AccessorJsonHandler.h | 5 +- .../AccessorSparseIndicesJsonHandler.cpp | 15 ++- .../AccessorSparseIndicesJsonHandler.h | 5 +- .../generated/AccessorSparseJsonHandler.cpp | 15 ++- .../generated/AccessorSparseJsonHandler.h | 5 +- .../AccessorSparseValuesJsonHandler.cpp | 13 +- .../AccessorSparseValuesJsonHandler.h | 5 +- .../generated/AnimationChannelJsonHandler.cpp | 13 +- .../generated/AnimationChannelJsonHandler.h | 5 +- .../AnimationChannelTargetJsonHandler.cpp | 13 +- .../AnimationChannelTargetJsonHandler.h | 5 +- .../generated/AnimationJsonHandler.cpp | 13 +- .../generated/AnimationJsonHandler.h | 5 +- .../generated/AnimationSamplerJsonHandler.cpp | 15 ++- .../generated/AnimationSamplerJsonHandler.h | 5 +- .../generated/AssetJsonHandler.cpp | 17 +-- CesiumGltfReader/generated/AssetJsonHandler.h | 5 +- .../generated/BufferJsonHandler.cpp | 13 +- .../generated/BufferJsonHandler.h | 5 +- .../generated/BufferViewJsonHandler.cpp | 19 +-- .../generated/BufferViewJsonHandler.h | 5 +- .../generated/CameraJsonHandler.cpp | 15 ++- .../generated/CameraJsonHandler.h | 5 +- .../CameraOrthographicJsonHandler.cpp | 17 +-- .../generated/CameraOrthographicJsonHandler.h | 5 +- .../CameraPerspectiveJsonHandler.cpp | 17 +-- .../generated/CameraPerspectiveJsonHandler.h | 5 +- .../generated/ImageJsonHandler.cpp | 15 ++- CesiumGltfReader/generated/ImageJsonHandler.h | 5 +- .../generated/MaterialJsonHandler.cpp | 25 ++-- .../generated/MaterialJsonHandler.h | 5 +- .../MaterialNormalTextureInfoJsonHandler.cpp | 13 +- .../MaterialNormalTextureInfoJsonHandler.h | 7 +- ...aterialOcclusionTextureInfoJsonHandler.cpp | 13 +- .../MaterialOcclusionTextureInfoJsonHandler.h | 7 +- ...aterialPBRMetallicRoughnessJsonHandler.cpp | 19 +-- .../MaterialPBRMetallicRoughnessJsonHandler.h | 5 +- .../generated/MeshJsonHandler.cpp | 13 +- CesiumGltfReader/generated/MeshJsonHandler.h | 5 +- .../generated/MeshPrimitiveJsonHandler.cpp | 19 +-- .../generated/MeshPrimitiveJsonHandler.h | 5 +- .../generated/ModelJsonHandler.cpp | 43 +++---- CesiumGltfReader/generated/ModelJsonHandler.h | 5 +- .../generated/NodeJsonHandler.cpp | 27 +++-- CesiumGltfReader/generated/NodeJsonHandler.h | 5 +- .../generated/SamplerJsonHandler.cpp | 17 +-- .../generated/SamplerJsonHandler.h | 5 +- .../generated/SceneJsonHandler.cpp | 11 +- CesiumGltfReader/generated/SceneJsonHandler.h | 5 +- .../generated/SkinJsonHandler.cpp | 15 ++- CesiumGltfReader/generated/SkinJsonHandler.h | 5 +- .../generated/TextureInfoJsonHandler.cpp | 13 +- .../generated/TextureInfoJsonHandler.h | 5 +- .../generated/TextureJsonHandler.cpp | 13 +- .../generated/TextureJsonHandler.h | 5 +- CesiumGltfReader/src/ArrayJsonHandler.h | 106 +++++++++++++++++ .../src/ExtensibleObjectJsonHandler.cpp | 4 + .../src/ExtensibleObjectJsonHandler.h | 1 + .../src/NamedObjectJsonHandler.cpp | 4 + CesiumGltfReader/src/NamedObjectJsonHandler.h | 1 + CesiumGltfReader/src/Reader.cpp | 2 +- tools/generate-gltf-classes/generate.js | 31 +++-- tools/generate-gltf-classes/index.js | 4 +- 115 files changed, 862 insertions(+), 591 deletions(-) delete mode 100644 Cesium3DTiles/src/tinygltf.cpp diff --git a/Cesium3DTiles/CMakeLists.txt b/Cesium3DTiles/CMakeLists.txt index 94f3b7605..44352d53e 100644 --- a/Cesium3DTiles/CMakeLists.txt +++ b/Cesium3DTiles/CMakeLists.txt @@ -16,9 +16,6 @@ target_sources( target_include_directories( Cesium3DTiles SYSTEM PUBLIC - # We're not using CMake for tinygltf at all, but it's header only. Add its headers here. - ${CMAKE_CURRENT_SOURCE_DIR}/../extern/tinygltf - # Same with RapidJSON ${CMAKE_CURRENT_SOURCE_DIR}/../extern/rapidjson/include @@ -31,4 +28,4 @@ target_include_directories( src ) -target_link_libraries(Cesium3DTiles PUBLIC CesiumAsync CesiumGeospatial CesiumGeometry CesiumGltf CesiumUtility uriparser draco tinyxml2 spdlog) +target_link_libraries(Cesium3DTiles PUBLIC CesiumAsync CesiumGeospatial CesiumGeometry CesiumGltf CesiumGltfReader CesiumUtility uriparser draco tinyxml2 spdlog) diff --git a/Cesium3DTiles/include/Cesium3DTiles/Gltf.h b/Cesium3DTiles/include/Cesium3DTiles/Gltf.h index 30d3975aa..e68dd8b99 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/Gltf.h +++ b/Cesium3DTiles/include/Cesium3DTiles/Gltf.h @@ -1,17 +1,18 @@ #pragma once #include "Cesium3DTiles/Library.h" +#include "CesiumGltf/Model.h" #include #include #include -#include +#include namespace Cesium3DTiles { /** * @brief Functions for loading and processing glTF models. * - * This class offers basic functions for loading glTF models as `tinygltf::Model` + * This class offers basic functions for loading glTF models as `CesiumGltf::Model` * instances, and for processing the mesh primitives that appear in the resulting * models. */ @@ -22,45 +23,14 @@ namespace Cesium3DTiles { /** @brief This class cannot be instantiated */ Gltf() = delete; - /** - * @brief A summary of the result of loading a glTF model from raw data. - */ - struct LoadResult { - /** - * @brief The gltf model that was loaded. - * - * This will be `std::nullopt` if the model was not loaded successfully. - */ - std::optional model; - - /** - * @brief Warning messages from the attempt to load the model. - */ - std::string warnings; - - /** - * @brief Error messages from the attempt to load the model. - */ - std::string errors; - }; - - /** - * @brief Load a glTF model from the given input data. - * - * @param data The input data. - * @return The {@link LoadResult} containing the model (if it could be loaded), - * and possible warning- or error messages. - */ - static LoadResult load(const gsl::span& data); - /** * @brief A callback function for {@link Gltf::forEachPrimitiveInScene}. */ typedef void ForEachPrimitiveInSceneCallback( - tinygltf::Model& gltf, - tinygltf::Node& node, - tinygltf::Mesh& mesh, - tinygltf::Primitive& primitive, + CesiumGltf::Model& gltf, + CesiumGltf::Node& node, + CesiumGltf::Mesh& mesh, + CesiumGltf::MeshPrimitive& primitive, const glm::dmat4& transform ); @@ -86,21 +56,21 @@ namespace Cesium3DTiles { * @param sceneID The scene ID (index) * @param callback The callback to apply */ - static void forEachPrimitiveInScene(tinygltf::Model& gltf, int sceneID, std::function&& callback); + static void forEachPrimitiveInScene(CesiumGltf::Model& gltf, int sceneID, std::function&& callback); /** * @brief A callback function for {@link Gltf::forEachPrimitiveInScene}. */ typedef void ForEachPrimitiveInSceneConstCallback( - const tinygltf::Model& gltf, - const tinygltf::Node& node, - const tinygltf::Mesh& mesh, - const tinygltf::Primitive& primitive, + const CesiumGltf::Model& gltf, + const CesiumGltf::Node& node, + const CesiumGltf::Mesh& mesh, + const CesiumGltf::MeshPrimitive& primitive, const glm::dmat4& transform ); /** @copydoc Gltf::forEachPrimitiveInScene() */ - static void forEachPrimitiveInScene(const tinygltf::Model& gltf, int sceneID, std::function&& callback); + static void forEachPrimitiveInScene(const CesiumGltf::Model& gltf, int sceneID, std::function&& callback); }; diff --git a/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h b/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h index cc1a87706..f4f72b6bd 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h +++ b/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h @@ -15,7 +15,7 @@ namespace Cesium3DTiles { * can be used to access the elements: * * ``` - * tinygltf::Model model; + * CesiumGltf::Model model; * GltfAccessor positions(model, accessorIndex) * glm::vec3 position = positions[i]; * ``` @@ -25,9 +25,9 @@ namespace Cesium3DTiles { template class GltfAccessor final { private: - const tinygltf::Buffer* _pGltfBuffer; - const tinygltf::BufferView* _pGltfBufferView; - const tinygltf::Accessor* _pGltfAccessor; + const CesiumGltf::Buffer* _pGltfBuffer; + const CesiumGltf::BufferView* _pGltfBufferView; + const CesiumGltf::Accessor* _pGltfAccessor; const unsigned char* _pBufferViewData; size_t _stride; size_t _offset; @@ -49,36 +49,36 @@ namespace Cesium3DTiles { * itself, or to cases where the size of the template parameter `T` * does not match the size of the elements of the specified accessor. */ - GltfAccessor(const tinygltf::Model& model, size_t accessorID) + GltfAccessor(const CesiumGltf::Model& model, size_t accessorID) { - const tinygltf::Accessor& accessor = model.accessors[accessorID]; - const tinygltf::BufferView& bufferView = model.bufferViews[accessor.bufferView]; - const tinygltf::Buffer& buffer = model.buffers[bufferView.buffer]; + const CesiumGltf::Accessor& accessor = model.accessors[accessorID]; + const CesiumGltf::BufferView& bufferView = model.bufferViews[accessor.bufferView]; + const CesiumGltf::Buffer& buffer = model.buffers[bufferView.buffer]; - const std::vector& data = buffer.data; - size_t bufferBytes = data.size(); + const std::vector& data = buffer.cesium.data; + int64_t bufferBytes = data.size(); if (bufferView.byteOffset + bufferView.byteLength > bufferBytes) { throw std::runtime_error("bufferView does not fit in buffer."); } - int accessorByteStride = accessor.ByteStride(bufferView); + int64_t accessorByteStride = computeByteStride(accessor, bufferView); if (accessorByteStride == -1) { throw std::runtime_error("cannot compute accessor byteStride."); } - int32_t accessorComponentElements = tinygltf::GetNumComponentsInType(accessor.type); - int32_t accessorComponentBytes = tinygltf::GetComponentSizeInBytes(accessor.componentType); - int32_t accessorBytesPerStride = accessorComponentElements * accessorComponentBytes; + int64_t accessorComponentElements = computeNumberOfComponents(accessor.type); + int64_t accessorComponentBytes = computeByteSizeOfComponent(accessor.componentType); + int64_t accessorBytesPerStride = accessorComponentElements * accessorComponentBytes; if (sizeof(T) != accessorBytesPerStride) { throw std::runtime_error("sizeof(T) does not much accessor bytes."); } - size_t accessorBytes = accessorByteStride * accessor.count; - size_t bytesRemainingInBufferView = bufferView.byteLength - (accessor.byteOffset + accessorByteStride * (accessor.count - 1) + accessorBytesPerStride); + int64_t accessorBytes = accessorByteStride * accessor.count; + int64_t bytesRemainingInBufferView = bufferView.byteLength - (accessor.byteOffset + accessorByteStride * (accessor.count - 1) + accessorBytesPerStride); if (accessorBytes > bufferView.byteLength || bytesRemainingInBufferView < 0) { throw std::runtime_error("accessor does not fit in bufferView."); @@ -129,7 +129,7 @@ namespace Cesium3DTiles { /** * @brief Returns the underyling buffer implementation. */ - const tinygltf::Buffer& gltfBuffer() const + const CesiumGltf::Buffer& gltfBuffer() const { return *this->_pGltfBuffer; } @@ -137,7 +137,7 @@ namespace Cesium3DTiles { /** * @brief Returns the underyling buffer view implementation. */ - const tinygltf::BufferView& gltfBufferView() const noexcept + const CesiumGltf::BufferView& gltfBufferView() const noexcept { return *this->_pGltfBufferView; } @@ -145,10 +145,55 @@ namespace Cesium3DTiles { /** * @brief Returns the underyling acessor implementation. */ - const tinygltf::Accessor& gltfAccessor() const noexcept + const CesiumGltf::Accessor& gltfAccessor() const noexcept { return *this->_pGltfAccessor; } + + static int64_t computeNumberOfComponents(CesiumGltf::Accessor::Type type) { + switch (type) { + case CesiumGltf::Accessor::Type::SCALAR: + return 1; + case CesiumGltf::Accessor::Type::VEC2: + return 2; + case CesiumGltf::Accessor::Type::VEC3: + return 3; + case CesiumGltf::Accessor::Type::VEC4: + return 4; + case CesiumGltf::Accessor::Type::MAT2: + return 4; + case CesiumGltf::Accessor::Type::MAT3: + return 9; + case CesiumGltf::Accessor::Type::MAT4: + return 16; + default: + return 0; + } + } + + static int64_t computeByteSizeOfComponent(CesiumGltf::Accessor::ComponentType componentType) { + switch (componentType) { + case CesiumGltf::Accessor::ComponentType::BYTE: + case CesiumGltf::Accessor::ComponentType::UNSIGNED_BYTE: + return 1; + case CesiumGltf::Accessor::ComponentType::SHORT: + case CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT: + return 2; + case CesiumGltf::Accessor::ComponentType::UNSIGNED_INT: + case CesiumGltf::Accessor::ComponentType::FLOAT: + return 4; + default: + return 0; + } + } + + static int64_t computeByteStride(const CesiumGltf::Accessor& accessor, const CesiumGltf::BufferView& bufferView) { + if (bufferView.byteStride <= 0) { + return computeNumberOfComponents(accessor.type) * computeByteSizeOfComponent(accessor.componentType); + } else { + return bufferView.byteStride; + } + } }; } \ No newline at end of file diff --git a/Cesium3DTiles/include/Cesium3DTiles/GltfContent.h b/Cesium3DTiles/include/Cesium3DTiles/GltfContent.h index 8cb13c681..7ce38679b 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/GltfContent.h +++ b/Cesium3DTiles/include/Cesium3DTiles/GltfContent.h @@ -50,7 +50,7 @@ namespace Cesium3DTiles { * @return The bounding region. */ static CesiumGeospatial::BoundingRegion createRasterOverlayTextureCoordinates( - tinygltf::Model& gltf, + CesiumGltf::Model& gltf, uint32_t textureCoordinateID, const CesiumGeospatial::Projection& projection, const CesiumGeometry::Rectangle& rectangle diff --git a/Cesium3DTiles/include/Cesium3DTiles/GltfWriter.h b/Cesium3DTiles/include/Cesium3DTiles/GltfWriter.h index 3527d7c14..921057f41 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/GltfWriter.h +++ b/Cesium3DTiles/include/Cesium3DTiles/GltfWriter.h @@ -18,7 +18,7 @@ namespace Cesium3DTiles { public: /** @copydoc GltfAccessor::GltfAccessor */ - GltfWriter(tinygltf::Model& model, size_t accessorID) : + GltfWriter(CesiumGltf::Model& model, size_t accessorID) : _accessor(model, accessorID) { } @@ -39,36 +39,36 @@ namespace Cesium3DTiles { } /** @copydoc GltfAccessor::gltfBuffer */ - const tinygltf::Buffer& gltfBuffer() const noexcept + const CesiumGltf::Buffer& gltfBuffer() const noexcept { return this->_accessor.gltfBuffer(); } /** @copydoc GltfAccessor::gltfBuffer */ - tinygltf::Buffer& gltfBuffer() noexcept + CesiumGltf::Buffer& gltfBuffer() noexcept { - return const_cast(this->_accessor.gltfBuffer()); + return const_cast(this->_accessor.gltfBuffer()); } /** @copydoc GltfAccessor::gltfBufferView */ - const tinygltf::BufferView& gltfBufferView() const noexcept + const CesiumGltf::BufferView& gltfBufferView() const noexcept { return this->_accessor.gltfBufferView(); } /** @copydoc GltfAccessor::gltfBufferView */ - tinygltf::BufferView& gltfBufferView() noexcept { - return const_cast(this->_accessor.gltfBufferView()); + CesiumGltf::BufferView& gltfBufferView() noexcept { + return const_cast(this->_accessor.gltfBufferView()); } /** @copydoc GltfAccessor::gltfAccessor */ - const tinygltf::Accessor& gltfAccessor() const noexcept { + const CesiumGltf::Accessor& gltfAccessor() const noexcept { return this->_accessor.gltfAccessor(); } /** @copydoc GltfAccessor::gltfAccessor */ - tinygltf::Accessor& gltfAccessor() noexcept { - return const_cast(this->_accessor.gltfAccessor()); + CesiumGltf::Accessor& gltfAccessor() noexcept { + return const_cast(this->_accessor.gltfAccessor()); } }; diff --git a/Cesium3DTiles/include/Cesium3DTiles/IPrepareRendererResources.h b/Cesium3DTiles/include/Cesium3DTiles/IPrepareRendererResources.h index a949f80a7..e6f5da93b 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/IPrepareRendererResources.h +++ b/Cesium3DTiles/include/Cesium3DTiles/IPrepareRendererResources.h @@ -9,9 +9,9 @@ namespace CesiumGeometry { struct Rectangle; } -namespace tinygltf { +namespace CesiumGltf { struct Image; - class Model; + struct Model; } namespace Cesium3DTiles { @@ -44,7 +44,7 @@ namespace Cesium3DTiles { * @returns Arbitrary data representing the result of the load process. This data is * passed to {@link prepareInMainThread} as the `pLoadThreadResult` parameter. */ - virtual void* prepareInLoadThread(const tinygltf::Model& model, const glm::dmat4& transform) = 0; + virtual void* prepareInLoadThread(const CesiumGltf::Model& model, const glm::dmat4& transform) = 0; /** * @brief Further prepares renderer resources. @@ -85,7 +85,7 @@ namespace Cesium3DTiles { * @returns Arbitrary data representing the result of the load process. This data is * passed to {@link prepareRasterInMainThread} as the `pLoadThreadResult` parameter. */ - virtual void* prepareRasterInLoadThread(const tinygltf::Image& image) = 0; + virtual void* prepareRasterInLoadThread(const CesiumGltf::Image& image) = 0; /** * @brief Further preprares a raster overlay tile. diff --git a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTile.h b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTile.h index 2dbe163ed..fb81b7c81 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTile.h +++ b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTile.h @@ -127,7 +127,7 @@ namespace Cesium3DTiles { * * @return The image data. */ - const tinygltf::Image& getImage() const noexcept { return this->_image; } + const CesiumGltf::Image& getImage() const noexcept { return this->_image; } /** * @brief Create the renderer resources for the loaded image. @@ -170,7 +170,7 @@ namespace Cesium3DTiles { CesiumGeometry::QuadtreeTileID _tileID; std::vector _tileCredits; std::atomic _state; - tinygltf::Image _image; + CesiumGltf::Image _image; void* _pRendererResources; uint32_t _references; }; diff --git a/Cesium3DTiles/include/Cesium3DTiles/Tile.h b/Cesium3DTiles/include/Cesium3DTiles/Tile.h index 3c5c60c2d..f0f38f720 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/Tile.h +++ b/Cesium3DTiles/include/Cesium3DTiles/Tile.h @@ -485,7 +485,7 @@ namespace Cesium3DTiles { * * @return The bounding region */ - static std::optional generateTextureCoordinates(tinygltf::Model& model, const BoundingVolume& boundingVolume, const std::vector& projections); + static std::optional generateTextureCoordinates(CesiumGltf::Model& model, const BoundingVolume& boundingVolume, const std::vector& projections); /** * @brief Upsample the parent of this tile. diff --git a/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h b/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h index 76da162fc..a78637d87 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h +++ b/Cesium3DTiles/include/Cesium3DTiles/TileContentLoadResult.h @@ -29,7 +29,7 @@ namespace Cesium3DTiles { * If it has a value but the model is blank, the tile can * be "rendered", but it is rendered as nothing. */ - std::optional model; + std::optional model; /** * @brief A new context, if any, used by the `childTiles`. diff --git a/Cesium3DTiles/src/Batched3DModelContent.cpp b/Cesium3DTiles/src/Batched3DModelContent.cpp index f65ccfe99..69a7e39e9 100644 --- a/Cesium3DTiles/src/Batched3DModelContent.cpp +++ b/Cesium3DTiles/src/Batched3DModelContent.cpp @@ -40,7 +40,7 @@ namespace Cesium3DTiles { void parseFeatureTableJsonData( const std::shared_ptr& pLogger, - tinygltf::Model& gltf, + CesiumGltf::Model& /*gltf*/, const gsl::span& featureTableJsonData) { rapidjson::Document document; @@ -50,30 +50,30 @@ namespace Cesium3DTiles { return; } - auto rtcIt = document.FindMember("RTC_CENTER"); - if ( - rtcIt != document.MemberEnd() && - rtcIt->value.IsArray() && - rtcIt->value.Size() == 3 && - rtcIt->value[0].IsDouble() && - rtcIt->value[1].IsDouble() && - rtcIt->value[2].IsDouble() - ) { - // Add the RTC_CENTER value to the glTF itself. - tinygltf::Value::Object extras; - if (gltf.extras.IsObject()) { - extras = gltf.extras.Get(); - } - - rapidjson::Value& rtcValue = rtcIt->value; - extras["RTC_CENTER"] = tinygltf::Value(tinygltf::Value::Array{ - tinygltf::Value(rtcValue[0].GetDouble()), - tinygltf::Value(rtcValue[1].GetDouble()), - tinygltf::Value(rtcValue[2].GetDouble()) - }); - - gltf.extras = tinygltf::Value(extras); - } + // auto rtcIt = document.FindMember("RTC_CENTER"); + // if ( + // rtcIt != document.MemberEnd() && + // rtcIt->value.IsArray() && + // rtcIt->value.Size() == 3 && + // rtcIt->value[0].IsDouble() && + // rtcIt->value[1].IsDouble() && + // rtcIt->value[2].IsDouble() + // ) { + // // Add the RTC_CENTER value to the glTF itself. + // CesiumGltf::Value::Object extras; + // if (gltf.extras.IsObject()) { + // extras = gltf.extras.Get(); + // } + + // rapidjson::Value& rtcValue = rtcIt->value; + // extras["RTC_CENTER"] = CesiumGltf::Value(CesiumGltf::Value::Array{ + // CesiumGltf::Value(rtcValue[0].GetDouble()), + // CesiumGltf::Value(rtcValue[1].GetDouble()), + // CesiumGltf::Value(rtcValue[2].GetDouble()) + // }); + + // gltf.extras = CesiumGltf::Value(extras); + // } } } @@ -172,7 +172,7 @@ namespace Cesium3DTiles { ); if (pResult->model && header.featureTableJsonByteLength > 0) { - tinygltf::Model& gltf = pResult->model.value(); + CesiumGltf::Model& gltf = pResult->model.value(); gsl::span featureTableJsonData = data.subspan(headerLength, header.featureTableJsonByteLength); parseFeatureTableJsonData(pLogger, gltf, featureTableJsonData); } diff --git a/Cesium3DTiles/src/BingMapsRasterOverlay.cpp b/Cesium3DTiles/src/BingMapsRasterOverlay.cpp index 2c4431df4..6e56a0ae4 100644 --- a/Cesium3DTiles/src/BingMapsRasterOverlay.cpp +++ b/Cesium3DTiles/src/BingMapsRasterOverlay.cpp @@ -207,6 +207,11 @@ namespace Cesium3DTiles { ](std::unique_ptr pRequest) -> std::unique_ptr { IAssetResponse* pResponse = pRequest->response(); + if (pResponse == nullptr) { + SPDLOG_LOGGER_ERROR(pLogger, "No response received from Bing Maps imagery metadata service."); + return nullptr; + } + rapidjson::Document response; response.Parse(reinterpret_cast(pResponse->data().data()), pResponse->data().size()); diff --git a/Cesium3DTiles/src/Gltf.cpp b/Cesium3DTiles/src/Gltf.cpp index e50aa3af4..47eb954d6 100644 --- a/Cesium3DTiles/src/Gltf.cpp +++ b/Cesium3DTiles/src/Gltf.cpp @@ -1,35 +1,19 @@ #include "Cesium3DTiles/Gltf.h" namespace Cesium3DTiles { - Gltf::LoadResult Gltf::load(const gsl::span& data) - { - tinygltf::TinyGLTF loader; - tinygltf::Model model; - std::string errors; - std::string warnings; - - loader.LoadBinaryFromMemory(&model, &errors, &warnings, data.data(), static_cast(data.size())); - - return LoadResult{ - model, - warnings, - errors - }; - } - - /*static*/ void Gltf::forEachPrimitiveInScene(tinygltf::Model& gltf, int sceneID, std::function&& callback) { - return Gltf::forEachPrimitiveInScene(const_cast(gltf), sceneID, [&callback]( - const tinygltf::Model& gltf_, - const tinygltf::Node& node, - const tinygltf::Mesh& mesh, - const tinygltf::Primitive& primitive, + /*static*/ void Gltf::forEachPrimitiveInScene(CesiumGltf::Model& gltf, int sceneID, std::function&& callback) { + return Gltf::forEachPrimitiveInScene(const_cast(gltf), sceneID, [&callback]( + const CesiumGltf::Model& gltf_, + const CesiumGltf::Node& node, + const CesiumGltf::Mesh& mesh, + const CesiumGltf::MeshPrimitive& primitive, const glm::dmat4& transform ) { callback( - const_cast(gltf_), - const_cast(node), - const_cast(mesh), - const_cast(primitive), + const_cast(gltf_), + const_cast(node), + const_cast(mesh), + const_cast(primitive), transform ); }); @@ -51,17 +35,17 @@ namespace Cesium3DTiles { static void forEachPrimitiveInMeshObject( const glm::dmat4x4& transform, - const tinygltf::Model& model, - const tinygltf::Node& node, - const tinygltf::Mesh& mesh, + const CesiumGltf::Model& model, + const CesiumGltf::Node& node, + const CesiumGltf::Mesh& mesh, std::function& callback ) { - for (const tinygltf::Primitive& primitive : mesh.primitives) { + for (const CesiumGltf::MeshPrimitive& primitive : mesh.primitives) { callback(model, node, mesh, primitive, transform); } } - static void forEachPrimitiveInNodeObject(const glm::dmat4x4& transform, const tinygltf::Model& model, const tinygltf::Node& node, std::function& callback) { + static void forEachPrimitiveInNodeObject(const glm::dmat4x4& transform, const CesiumGltf::Model& model, const CesiumGltf::Node& node, std::function& callback) { glm::dmat4x4 nodeTransform = transform; if (node.matrix.size() > 0) { @@ -82,7 +66,7 @@ namespace Cesium3DTiles { int meshId = node.mesh; if (meshId >= 0 && meshId < static_cast(model.meshes.size())) { - const tinygltf::Mesh& mesh = model.meshes[static_cast(meshId)]; + const CesiumGltf::Mesh& mesh = model.meshes[static_cast(meshId)]; forEachPrimitiveInMeshObject(nodeTransform, model, node, mesh, callback); } @@ -93,7 +77,7 @@ namespace Cesium3DTiles { } } - static void forEachPrimitiveInSceneObject(const glm::dmat4x4& transform, const tinygltf::Model& model, const tinygltf::Scene& scene, std::function& callback) { + static void forEachPrimitiveInSceneObject(const glm::dmat4x4& transform, const CesiumGltf::Model& model, const CesiumGltf::Scene& scene, std::function& callback) { for (int nodeID : scene.nodes) { if (nodeID >= 0 && nodeID < static_cast(model.nodes.size())) { forEachPrimitiveInNodeObject(transform, model, model.nodes[static_cast(nodeID)], callback); @@ -101,7 +85,7 @@ namespace Cesium3DTiles { } } - /*static*/ void Gltf::forEachPrimitiveInScene(const tinygltf::Model& gltf, int sceneID, std::function&& callback) { + /*static*/ void Gltf::forEachPrimitiveInScene(const CesiumGltf::Model& gltf, int sceneID, std::function&& callback) { glm::dmat4x4 rootTransform = gltfAxesToCesiumAxes; if (sceneID >= 0) { @@ -109,20 +93,20 @@ namespace Cesium3DTiles { if (sceneID < static_cast(gltf.scenes.size())) { forEachPrimitiveInSceneObject(rootTransform, gltf, gltf.scenes[static_cast(sceneID)], callback); } - } else if (gltf.defaultScene >= 0 && gltf.defaultScene < static_cast(gltf.scenes.size())) { + } else if (gltf.scene >= 0 && gltf.scene < static_cast(gltf.scenes.size())) { // Use the default scene - forEachPrimitiveInSceneObject(rootTransform, gltf, gltf.scenes[static_cast(gltf.defaultScene)], callback); + forEachPrimitiveInSceneObject(rootTransform, gltf, gltf.scenes[static_cast(gltf.scene)], callback); } else if (gltf.scenes.size() > 0) { // There's no default, so use the first scene - const tinygltf::Scene& defaultScene = gltf.scenes[0]; + const CesiumGltf::Scene& defaultScene = gltf.scenes[0]; forEachPrimitiveInSceneObject(rootTransform, gltf, defaultScene, callback); } else if (gltf.nodes.size() > 0) { // No scenes at all, use the first node as the root node. forEachPrimitiveInNodeObject(rootTransform, gltf, gltf.nodes[0], callback); } else if (gltf.meshes.size() > 0) { // No nodes either, show all the meshes. - for (const tinygltf::Mesh& mesh : gltf.meshes) { - forEachPrimitiveInMeshObject(rootTransform, gltf, tinygltf::Node(), mesh, callback); + for (const CesiumGltf::Mesh& mesh : gltf.meshes) { + forEachPrimitiveInMeshObject(rootTransform, gltf, CesiumGltf::Node(), mesh, callback); } } } diff --git a/Cesium3DTiles/src/GltfContent.cpp b/Cesium3DTiles/src/GltfContent.cpp index 5d24ea404..4a8c69e2a 100644 --- a/Cesium3DTiles/src/GltfContent.cpp +++ b/Cesium3DTiles/src/GltfContent.cpp @@ -2,6 +2,7 @@ #include "Cesium3DTiles/GltfContent.h" #include "Cesium3DTiles/GltfWriter.h" #include "Cesium3DTiles/spdlog-cesium.h" +#include "CesiumGltf/Reader.h" #include "CesiumUtility/Math.h" #include @@ -16,29 +17,26 @@ namespace Cesium3DTiles { const glm::dmat4& /*tileTransform*/, const std::optional& /*tileContentBoundingVolume*/, TileRefine /*tileRefine*/, - const std::string& /*url*/, + const std::string& url, const gsl::span& data ) { std::unique_ptr pResult = std::make_unique(); - std::string errors; - std::string warnings; - - tinygltf::TinyGLTF loader; - pResult->model.emplace(); - bool success = loader.LoadBinaryFromMemory(&pResult->model.value(), &errors, &warnings, data.data(), static_cast(data.size())); - if (!success) { - SPDLOG_LOGGER_ERROR(pLogger, "Failed to load binary glTF from memory: {}", errors); + CesiumGltf::ModelReaderResult loadedModel = CesiumGltf::readModel(data); + if (!loadedModel.errors.empty()) { + SPDLOG_LOGGER_ERROR(pLogger, "Failed to load binary glTF from {}: {}", url, loadedModel.errors); } - if (!warnings.empty()) { - SPDLOG_LOGGER_WARN(pLogger, "Warning when loading binary glTF from memory: {}", warnings); + if (!loadedModel.warnings.empty()) { + SPDLOG_LOGGER_WARN(pLogger, "Warning when loading binary glTF from {}: {}", url, loadedModel.warnings); } + pResult->model = std::move(loadedModel.model); + return pResult; } static int generateOverlayTextureCoordinates( - tinygltf::Model& gltf, + CesiumGltf::Model& gltf, int positionAccessorIndex, const glm::dmat4x4& transform, const CesiumGeospatial::Projection& projection, @@ -50,12 +48,12 @@ namespace Cesium3DTiles { double& minimumHeight, double& maximumHeight ) { - std::vector& buffers = gltf.buffers; - std::vector& bufferViews = gltf.bufferViews; - std::vector& accessors = gltf.accessors; + std::vector& buffers = gltf.buffers; + std::vector& bufferViews = gltf.bufferViews; + std::vector& accessors = gltf.accessors; int uvBufferId = static_cast(buffers.size()); - tinygltf::Buffer uvBuffer = buffers.emplace_back(); + CesiumGltf::Buffer& uvBuffer = buffers.emplace_back(); int uvBufferViewId = static_cast(bufferViews.size()); bufferViews.emplace_back(); @@ -65,21 +63,21 @@ namespace Cesium3DTiles { GltfAccessor positionAccessor(gltf, static_cast(positionAccessorIndex)); - uvBuffer.data.resize(positionAccessor.size() * 2 * sizeof(float)); + uvBuffer.cesium.data.resize(positionAccessor.size() * 2 * sizeof(float)); - tinygltf::BufferView& uvBufferView = gltf.bufferViews[static_cast(uvBufferViewId)]; + CesiumGltf::BufferView& uvBufferView = gltf.bufferViews[static_cast(uvBufferViewId)]; uvBufferView.buffer = uvBufferId; uvBufferView.byteOffset = 0; uvBufferView.byteStride = 2 * sizeof(float); - uvBufferView.byteLength = uvBuffer.data.size(); - uvBufferView.target = TINYGLTF_TARGET_ARRAY_BUFFER; + uvBufferView.byteLength = uvBuffer.cesium.data.size(); + uvBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; - tinygltf::Accessor& uvAccessor = gltf.accessors[static_cast(uvAccessorId)]; + CesiumGltf::Accessor& uvAccessor = gltf.accessors[static_cast(uvAccessorId)]; uvAccessor.bufferView = uvBufferViewId; uvAccessor.byteOffset = 0; - uvAccessor.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT; + uvAccessor.componentType = CesiumGltf::Accessor::ComponentType::FLOAT; uvAccessor.count = positionAccessor.size(); - uvAccessor.type = TINYGLTF_TYPE_VEC2; + uvAccessor.type = CesiumGltf::Accessor::Type::VEC2; GltfWriter uvWriter(gltf, static_cast(uvAccessorId)); @@ -154,7 +152,7 @@ namespace Cesium3DTiles { } /*static*/ CesiumGeospatial::BoundingRegion GltfContent::createRasterOverlayTextureCoordinates( - tinygltf::Model& gltf, + CesiumGltf::Model& gltf, uint32_t textureCoordinateID, const CesiumGeospatial::Projection& projection, const CesiumGeometry::Rectangle& rectangle @@ -172,10 +170,10 @@ namespace Cesium3DTiles { double maximumHeight = std::numeric_limits::lowest(); Gltf::forEachPrimitiveInScene(gltf, -1, [&positionAccessorsToTextureCoordinateAccessor, &attributeName, &projection, &rectangle, &west, &south, &east, &north, &minimumHeight, &maximumHeight]( - tinygltf::Model& gltf_, - tinygltf::Node& /*node*/, - tinygltf::Mesh& /*mesh*/, - tinygltf::Primitive& primitive, + CesiumGltf::Model& gltf_, + CesiumGltf::Node& /*node*/, + CesiumGltf::Mesh& /*mesh*/, + CesiumGltf::MeshPrimitive& primitive, const glm::dmat4& transform ) { auto positionIt = primitive.attributes.find("POSITION"); diff --git a/Cesium3DTiles/src/QuantizedMeshContent.cpp b/Cesium3DTiles/src/QuantizedMeshContent.cpp index f099d1122..2f7e77adb 100644 --- a/Cesium3DTiles/src/QuantizedMeshContent.cpp +++ b/Cesium3DTiles/src/QuantizedMeshContent.cpp @@ -6,7 +6,6 @@ #include "CesiumUtility/Math.h" #include "QuantizedMeshContent.h" #include "calcQuadtreeMaxGeometricError.h" -#include "tiny_gltf.h" #include "Uri.h" #include "JsonHelpers.h" #include @@ -830,42 +829,42 @@ namespace Cesium3DTiles { // create gltf pResult->model.emplace(); - tinygltf::Model& model = pResult->model.value(); + CesiumGltf::Model& model = pResult->model.value(); size_t meshId = model.meshes.size(); model.meshes.emplace_back(); - tinygltf::Mesh& mesh = model.meshes[meshId]; + CesiumGltf::Mesh& mesh = model.meshes[meshId]; mesh.primitives.emplace_back(); - tinygltf::Primitive& primitive = mesh.primitives[0]; - primitive.mode = TINYGLTF_MODE_TRIANGLES; + CesiumGltf::MeshPrimitive& primitive = mesh.primitives[0]; + primitive.mode = CesiumGltf::MeshPrimitive::Mode::TRIANGLES; primitive.material = 0; // add position buffer to gltf size_t positionBufferId = model.buffers.size(); model.buffers.emplace_back(); - tinygltf::Buffer& positionBuffer = model.buffers[positionBufferId]; - positionBuffer.data = std::move(outputPositionsBuffer); + CesiumGltf::Buffer& positionBuffer = model.buffers[positionBufferId]; + positionBuffer.cesium.data = std::move(outputPositionsBuffer); size_t positionBufferViewId = model.bufferViews.size(); model.bufferViews.emplace_back(); - tinygltf::BufferView& positionBufferView = model.bufferViews[positionBufferViewId]; + CesiumGltf::BufferView& positionBufferView = model.bufferViews[positionBufferViewId]; positionBufferView.buffer = static_cast(positionBufferId); positionBufferView.byteOffset = 0; positionBufferView.byteStride = 3 * sizeof(float); - positionBufferView.byteLength = positionBuffer.data.size(); - positionBufferView.target = TINYGLTF_TARGET_ARRAY_BUFFER; + positionBufferView.byteLength = positionBuffer.cesium.data.size(); + positionBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; size_t positionAccessorId = model.accessors.size(); model.accessors.emplace_back(); - tinygltf::Accessor& positionAccessor = model.accessors[positionAccessorId]; + CesiumGltf::Accessor& positionAccessor = model.accessors[positionAccessorId]; positionAccessor.bufferView = static_cast(positionBufferViewId); positionAccessor.byteOffset = 0; - positionAccessor.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT; + positionAccessor.componentType = CesiumGltf::Accessor::ComponentType::FLOAT; positionAccessor.count = vertexCount + skirtVertexCount; - positionAccessor.type = TINYGLTF_TYPE_VEC3; - positionAccessor.minValues = { minX, minY, minZ }; - positionAccessor.maxValues = { maxX, maxY, maxZ }; + positionAccessor.type = CesiumGltf::Accessor::Type::VEC3; + positionAccessor.min = { minX, minY, minZ }; + positionAccessor.max = { maxX, maxY, maxZ }; primitive.attributes.emplace("POSITION", static_cast(positionAccessorId)); @@ -873,26 +872,26 @@ namespace Cesium3DTiles { if (!outputNormalsBuffer.empty()) { size_t normalBufferId = model.buffers.size(); model.buffers.emplace_back(); - tinygltf::Buffer& normalBuffer = model.buffers[normalBufferId]; - normalBuffer.data = std::move(outputNormalsBuffer); + CesiumGltf::Buffer& normalBuffer = model.buffers[normalBufferId]; + normalBuffer.cesium.data = std::move(outputNormalsBuffer); size_t normalBufferViewId = model.bufferViews.size(); model.bufferViews.emplace_back(); - tinygltf::BufferView& normalBufferView = model.bufferViews[normalBufferViewId]; + CesiumGltf::BufferView& normalBufferView = model.bufferViews[normalBufferViewId]; normalBufferView.buffer = static_cast(normalBufferId); normalBufferView.byteOffset = 0; normalBufferView.byteStride = 3 * sizeof(float); - normalBufferView.byteLength = normalBuffer.data.size(); - normalBufferView.target = TINYGLTF_TARGET_ARRAY_BUFFER; + normalBufferView.byteLength = normalBuffer.cesium.data.size(); + normalBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; size_t normalAccessorId = model.accessors.size(); model.accessors.emplace_back(); - tinygltf::Accessor& normalAccessor = model.accessors[normalAccessorId]; + CesiumGltf::Accessor& normalAccessor = model.accessors[normalAccessorId]; normalAccessor.bufferView = static_cast(normalBufferViewId); normalAccessor.byteOffset = 0; - normalAccessor.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT; + normalAccessor.componentType = CesiumGltf::Accessor::ComponentType::FLOAT; normalAccessor.count = vertexCount + skirtVertexCount; - normalAccessor.type = TINYGLTF_TYPE_VEC3; + normalAccessor.type = CesiumGltf::Accessor::Type::VEC3; primitive.attributes.emplace("NORMAL", static_cast(normalAccessorId)); } @@ -900,32 +899,32 @@ namespace Cesium3DTiles { // add indices buffer to gltf size_t indicesBufferId = model.buffers.size(); model.buffers.emplace_back(); - tinygltf::Buffer& indicesBuffer = model.buffers[indicesBufferId]; - indicesBuffer.data = std::move(outputIndicesBuffer); + CesiumGltf::Buffer& indicesBuffer = model.buffers[indicesBufferId]; + indicesBuffer.cesium.data = std::move(outputIndicesBuffer); size_t indicesBufferViewId = model.bufferViews.size(); model.bufferViews.emplace_back(); - tinygltf::BufferView& indicesBufferView = model.bufferViews[indicesBufferViewId]; + CesiumGltf::BufferView& indicesBufferView = model.bufferViews[indicesBufferViewId]; indicesBufferView.buffer = static_cast(indicesBufferId); indicesBufferView.byteOffset = 0; - indicesBufferView.byteLength = indicesBuffer.data.size(); + indicesBufferView.byteLength = indicesBuffer.cesium.data.size(); indicesBufferView.byteStride = indexSizeBytes; - indicesBufferView.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER; + indicesBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; size_t indicesAccessorId = model.accessors.size(); model.accessors.emplace_back(); - tinygltf::Accessor& indicesAccessor = model.accessors[indicesAccessorId]; + CesiumGltf::Accessor& indicesAccessor = model.accessors[indicesAccessorId]; indicesAccessor.bufferView = static_cast(indicesBufferViewId); indicesAccessor.byteOffset = 0; - indicesAccessor.type = TINYGLTF_TYPE_SCALAR; + indicesAccessor.type = CesiumGltf::Accessor::Type::SCALAR; indicesAccessor.count = indicesCount + skirtIndicesCount; - indicesAccessor.componentType = indexSizeBytes == sizeof(uint32_t) ? TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT : TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT; + indicesAccessor.componentType = indexSizeBytes == sizeof(uint32_t) ? CesiumGltf::Accessor::ComponentType::UNSIGNED_INT : CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT; primitive.indices = static_cast(indicesBufferId); // create node and update bounding volume model.nodes.emplace_back(); - tinygltf::Node& node = model.nodes[0]; + CesiumGltf::Node& node = model.nodes[0]; node.mesh = 0; node.matrix = { 1.0, 0.0, 0.0, 0.0, diff --git a/Cesium3DTiles/src/RasterOverlayTile.cpp b/Cesium3DTiles/src/RasterOverlayTile.cpp index 5fb5fcf50..cd7b7b0c9 100644 --- a/Cesium3DTiles/src/RasterOverlayTile.cpp +++ b/Cesium3DTiles/src/RasterOverlayTile.cpp @@ -48,7 +48,7 @@ namespace Cesium3DTiles { {} LoadState state; - tinygltf::Image image; + CesiumGltf::Image image; std::string warnings; std::string errors; void* pRendererResources; @@ -79,18 +79,19 @@ namespace Cesium3DTiles { LoadResult result; gsl::span data = pResponse->data(); - bool success = tinygltf::LoadImageData(&result.image, 0, &result.errors, &result.warnings, 0, 0, data.data(), static_cast(data.size()), nullptr); + // bool success = CesiumGltf::LoadImageData(&result.image, 0, &result.errors, &result.warnings, 0, 0, data.data(), static_cast(data.size()), nullptr); + bool success = false; const int bytesPerPixel = 4; - if (success && result.image.image.size() >= static_cast(result.image.width * result.image.height * bytesPerPixel)) { + if (success && result.image.cesium.pixelData.size() >= static_cast(result.image.cesium.width * result.image.cesium.height * bytesPerPixel)) { double tileWidth = tileRectangle.computeWidth(); double tileHeight = tileRectangle.computeHeight(); gsl::span cutouts = cutoutsCollection.getCutouts(); - std::vector& imageData = result.image.image; - int width = result.image.width; - int height = result.image.width; + std::vector& imageData = result.image.cesium.pixelData; + int width = result.image.cesium.width; + int height = result.image.cesium.height; for (const CesiumGeospatial::GlobeRectangle& rectangle : cutouts) { CesiumGeometry::Rectangle cutoutRectangle = projectRectangleSimple(projection, rectangle); diff --git a/Cesium3DTiles/src/RasterOverlayTileProvider.cpp b/Cesium3DTiles/src/RasterOverlayTileProvider.cpp index b8b1b2ba5..c6c16871f 100644 --- a/Cesium3DTiles/src/RasterOverlayTileProvider.cpp +++ b/Cesium3DTiles/src/RasterOverlayTileProvider.cpp @@ -353,7 +353,7 @@ namespace Cesium3DTiles { } void RasterOverlayTileProvider::notifyTileLoaded(RasterOverlayTile* pTile) noexcept { - this->_tileDataBytes += pTile->getImage().image.size(); + this->_tileDataBytes += pTile->getImage().cesium.pixelData.size(); --this->_tilesCurrentlyLoading; } @@ -364,7 +364,7 @@ namespace Cesium3DTiles { assert(it != this->_tiles.end()); assert(it->second.get() == pTile); - this->_tileDataBytes -= pTile->getImage().image.size(); + this->_tileDataBytes -= pTile->getImage().cesium.pixelData.size(); RasterOverlay& overlay = pTile->getOverlay(); diff --git a/Cesium3DTiles/src/Tile.cpp b/Cesium3DTiles/src/Tile.cpp index 417a14261..e84069ba6 100644 --- a/Cesium3DTiles/src/Tile.cpp +++ b/Cesium3DTiles/src/Tile.cpp @@ -303,11 +303,13 @@ namespace Cesium3DTiles { this->_pRendererResources = loadResult.pRendererResources; this->getTileset()->notifyTileDoneLoading(this); this->setState(loadResult.state); - }).catchInMainThread([this](const std::exception& /*e*/) { + }).catchInMainThread([this](const std::exception& e) { this->_pContent.reset(); this->_pRendererResources = nullptr; this->getTileset()->notifyTileDoneLoading(this); this->setState(LoadState::Failed); + + SPDLOG_LOGGER_ERROR(this->getTileset()->getExternals().pLogger, "An exception occurred while loading tile: {}", e.what()); }); } @@ -595,24 +597,24 @@ namespace Cesium3DTiles { const TileContentLoadResult* pContent = this->getContent(); if (pContent && pContent->model) { - const tinygltf::Model& model = pContent->model.value(); + const CesiumGltf::Model& model = pContent->model.value(); // Add up the glTF buffers - for (const tinygltf::Buffer& buffer : model.buffers) { - bytes += buffer.data.size(); + for (const CesiumGltf::Buffer& buffer : model.buffers) { + bytes += buffer.cesium.data.size(); } // For images loaded from buffers, subtract the buffer size and add // the decoded image size instead. - const std::vector& bufferViews = model.bufferViews; - for (const tinygltf::Image& image : model.images) { + const std::vector& bufferViews = model.bufferViews; + for (const CesiumGltf::Image& image : model.images) { int bufferView = image.bufferView; if (bufferView < 0 || bufferView >= static_cast(bufferViews.size())) { continue; } bytes -= bufferViews[static_cast(bufferView)].byteLength; - bytes += image.image.size(); + bytes += image.cesium.pixelData.size(); } } @@ -624,7 +626,7 @@ namespace Cesium3DTiles { } /*static*/ std::optional Tile::generateTextureCoordinates( - tinygltf::Model& model, + CesiumGltf::Model& model, const BoundingVolume& boundingVolume, const std::vector& projections ) { @@ -676,7 +678,7 @@ namespace Cesium3DTiles { return; } - tinygltf::Model& parentModel = pParentContent->model.value(); + CesiumGltf::Model& parentModel = pParentContent->model.value(); Tileset* pTileset = this->getTileset(); pTileset->notifyTileStartLoading(this); diff --git a/Cesium3DTiles/src/tinygltf.cpp b/Cesium3DTiles/src/tinygltf.cpp deleted file mode 100644 index 476f9b64c..000000000 --- a/Cesium3DTiles/src/tinygltf.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#define TINYGLTF_USE_CPP14 -#define TINYGLTF_IMPLEMENTATION -#define STB_IMAGE_IMPLEMENTATION -#define STB_IMAGE_WRITE_IMPLEMENTATION -//#define TINYGLTF_NOEXCEPTION // optional. disable exception handling. -#define TINYGLTF_ENABLE_DRACO -#define TINYGLTF_USE_RAPIDJSON -#define TINYGLTF_NO_INCLUDE_JSON -#define TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR - -#ifdef _MSC_VER -#pragma warning(disable:4996 4946 4100 4189 4127) -#endif - -#include -#include -#include -#include -#include -#include diff --git a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp index 89b839267..12fbfb9dd 100644 --- a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp +++ b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp @@ -6,18 +6,18 @@ namespace Cesium3DTiles { static void upsamplePrimitiveForRasterOverlays( - const tinygltf::Model& parentModel, - tinygltf::Model& model, - tinygltf::Mesh& mesh, - tinygltf::Primitive& primitive, + const CesiumGltf::Model& parentModel, + CesiumGltf::Model& model, + CesiumGltf::Mesh& mesh, + CesiumGltf::MeshPrimitive& primitive, CesiumGeometry::QuadtreeChild childID ); struct FloatVertexAttribute { const std::vector& buffer; - size_t offset; - int32_t stride; - int32_t numberOfFloatsPerVertex; + int64_t offset; + int64_t stride; + int64_t numberOfFloatsPerVertex; int32_t accessorIndex; std::vector minimums; std::vector maximums; @@ -32,8 +32,8 @@ namespace Cesium3DTiles { const std::vector& clipResult ); - tinygltf::Model upsampleGltfForRasterOverlays(const tinygltf::Model& parentModel, CesiumGeometry::QuadtreeChild childID) { - tinygltf::Model result; + CesiumGltf::Model upsampleGltfForRasterOverlays(const CesiumGltf::Model& parentModel, CesiumGeometry::QuadtreeChild childID) { + CesiumGltf::Model result; // Copy the entire parent model except for the buffers, bufferViews, and accessors, which we'll be rewriting. result.animations = parentModel.animations; @@ -46,18 +46,17 @@ namespace Cesium3DTiles { result.samplers = parentModel.samplers; result.cameras = parentModel.cameras; result.scenes = parentModel.scenes; - result.lights = parentModel.lights; - result.defaultScene = parentModel.defaultScene; + result.scene = parentModel.scene; result.extensionsUsed = parentModel.extensionsUsed; result.extensionsRequired = parentModel.extensionsRequired; result.asset = parentModel.asset; - result.extras = parentModel.extras; - result.extensions = parentModel.extensions; - result.extras_json_string = parentModel.extras_json_string; - result.extensions_json_string = parentModel.extensions_json_string; + // result.extras = parentModel.extras; + // result.extensions = parentModel.extensions; + // result.extras_json_string = parentModel.extras_json_string; + // result.extensions_json_string = parentModel.extensions_json_string; - for (tinygltf::Mesh& mesh : result.meshes) { - for (tinygltf::Primitive& primitive : mesh.primitives) { + for (CesiumGltf::Mesh& mesh : result.meshes) { + for (CesiumGltf::MeshPrimitive& primitive : mesh.primitives) { upsamplePrimitiveForRasterOverlays(parentModel, result, mesh, primitive, childID); } } @@ -192,10 +191,10 @@ namespace Cesium3DTiles { template static void upsamplePrimitiveForRasterOverlays( - const tinygltf::Model& parentModel, - tinygltf::Model& model, - tinygltf::Mesh& /*mesh*/, - tinygltf::Primitive& primitive, + const CesiumGltf::Model& parentModel, + CesiumGltf::Model& model, + CesiumGltf::Mesh& /*mesh*/, + CesiumGltf::MeshPrimitive& primitive, CesiumGeometry::QuadtreeChild childID ) { // Add up the per-vertex size of all attributes and create buffers, bufferViews, and accessors @@ -214,13 +213,13 @@ namespace Cesium3DTiles { size_t indexBufferViewIndex = model.bufferViews.size(); model.bufferViews.emplace_back(); - tinygltf::BufferView& vertexBufferView = model.bufferViews[vertexBufferViewIndex]; + CesiumGltf::BufferView& vertexBufferView = model.bufferViews[vertexBufferViewIndex]; vertexBufferView.buffer = static_cast(vertexBufferIndex); - vertexBufferView.target = TINYGLTF_TARGET_ARRAY_BUFFER; + vertexBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; - tinygltf::BufferView& indexBufferView = model.bufferViews[indexBufferViewIndex]; + CesiumGltf::BufferView& indexBufferView = model.bufferViews[indexBufferViewIndex]; indexBufferView.buffer = static_cast(indexBufferIndex); - indexBufferView.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER; + indexBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; uint32_t vertexSizeFloats = 0; int uvAccessorIndex = -1; @@ -247,39 +246,39 @@ namespace Cesium3DTiles { continue; } - const tinygltf::Accessor& accessor = parentModel.accessors[static_cast(attribute.second)]; + const CesiumGltf::Accessor& accessor = parentModel.accessors[static_cast(attribute.second)]; if (accessor.bufferView < 0 || accessor.bufferView >= static_cast(parentModel.bufferViews.size())) { toRemove.push_back(attribute.first); continue; } - const tinygltf::BufferView& bufferView = parentModel.bufferViews[static_cast(accessor.bufferView)]; + const CesiumGltf::BufferView& bufferView = parentModel.bufferViews[static_cast(accessor.bufferView)]; if (bufferView.buffer < 0 || bufferView.buffer >= static_cast(parentModel.buffers.size())) { toRemove.push_back(attribute.first); continue; } - const tinygltf::Buffer& buffer = parentModel.buffers[static_cast(bufferView.buffer)]; + const CesiumGltf::Buffer& buffer = parentModel.buffers[static_cast(bufferView.buffer)]; - int32_t accessorByteStride = accessor.ByteStride(bufferView); - int32_t accessorComponentElements = tinygltf::GetNumComponentsInType(static_cast(accessor.type)); - if (accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) { + int64_t accessorByteStride = Cesium3DTiles::GltfAccessor::computeByteStride(accessor, bufferView); + int64_t accessorComponentElements = Cesium3DTiles::GltfAccessor::computeNumberOfComponents(accessor.type); + if (accessor.componentType != CesiumGltf::Accessor::ComponentType::FLOAT) { // Can only interpolate floating point vertex attributes return; } attribute.second = static_cast(model.accessors.size()); model.accessors.emplace_back(); - tinygltf::Accessor& newAccessor = model.accessors.back(); + CesiumGltf::Accessor& newAccessor = model.accessors.back(); newAccessor.bufferView = static_cast(vertexBufferIndex); newAccessor.byteOffset = vertexSizeFloats * sizeof(float); - newAccessor.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT; + newAccessor.componentType = CesiumGltf::Accessor::ComponentType::FLOAT; newAccessor.type = accessor.type; vertexSizeFloats += static_cast(accessorComponentElements); attributes.push_back(FloatVertexAttribute { - buffer.data, + buffer.cesium.data, accessor.byteOffset, accessorByteStride, accessorComponentElements, @@ -375,35 +374,35 @@ namespace Cesium3DTiles { // Update the accessor vertex counts and min/max values size_t numberOfVertices = newVertexFloats.size() / vertexSizeFloats; for (const FloatVertexAttribute& attribute : attributes) { - tinygltf::Accessor& accessor = model.accessors[static_cast(attribute.accessorIndex)]; + CesiumGltf::Accessor& accessor = model.accessors[static_cast(attribute.accessorIndex)]; accessor.count = numberOfVertices; - accessor.minValues = std::move(attribute.minimums); - accessor.maxValues = std::move(attribute.maximums); + accessor.min = std::move(attribute.minimums); + accessor.max = std::move(attribute.maximums); } // Add an accessor for the indices size_t indexAccessorIndex = model.accessors.size(); model.accessors.emplace_back(); - tinygltf::Accessor& newIndicesAccessor = model.accessors.back(); + CesiumGltf::Accessor& newIndicesAccessor = model.accessors.back(); newIndicesAccessor.bufferView = static_cast(indexBufferViewIndex); newIndicesAccessor.byteOffset = 0; newIndicesAccessor.count = indices.size(); - newIndicesAccessor.componentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT; - newIndicesAccessor.type = TINYGLTF_TYPE_SCALAR; + newIndicesAccessor.componentType = CesiumGltf::Accessor::ComponentType::UNSIGNED_INT; + newIndicesAccessor.type = CesiumGltf::Accessor::Type::SCALAR; // Populate the buffers - tinygltf::Buffer& vertexBuffer = model.buffers[vertexBufferIndex]; - vertexBuffer.data.resize(newVertexFloats.size() * sizeof(float)); - float* pAsFloats = reinterpret_cast(vertexBuffer.data.data()); + CesiumGltf::Buffer& vertexBuffer = model.buffers[vertexBufferIndex]; + vertexBuffer.cesium.data.resize(newVertexFloats.size() * sizeof(float)); + float* pAsFloats = reinterpret_cast(vertexBuffer.cesium.data.data()); std::copy(newVertexFloats.begin(), newVertexFloats.end(), pAsFloats); - vertexBufferView.byteLength = vertexBuffer.data.size(); + vertexBufferView.byteLength = vertexBuffer.cesium.data.size(); vertexBufferView.byteStride = vertexSizeFloats * sizeof(float); - tinygltf::Buffer& indexBuffer = model.buffers[indexBufferIndex]; - indexBuffer.data.resize(indices.size() * sizeof(uint32_t)); - uint32_t* pAsUint32s = reinterpret_cast(indexBuffer.data.data()); + CesiumGltf::Buffer& indexBuffer = model.buffers[indexBufferIndex]; + indexBuffer.cesium.data.resize(indices.size() * sizeof(uint32_t)); + uint32_t* pAsUint32s = reinterpret_cast(indexBuffer.cesium.data.data()); std::copy(indices.begin(), indices.end(), pAsUint32s); - indexBufferView.byteLength = indexBuffer.data.size(); + indexBufferView.byteLength = indexBuffer.cesium.data.size(); primitive.indices = static_cast(indexAccessorIndex); } @@ -468,14 +467,14 @@ namespace Cesium3DTiles { } static void upsamplePrimitiveForRasterOverlays( - const tinygltf::Model& parentModel, - tinygltf::Model& model, - tinygltf::Mesh& mesh, - tinygltf::Primitive& primitive, + const CesiumGltf::Model& parentModel, + CesiumGltf::Model& model, + CesiumGltf::Mesh& mesh, + CesiumGltf::MeshPrimitive& primitive, CesiumGeometry::QuadtreeChild childID ) { if ( - primitive.mode != TINYGLTF_MODE_TRIANGLES || + primitive.mode != CesiumGltf::MeshPrimitive::Mode::TRIANGLES || primitive.indices < 0 || primitive.indices >= static_cast(parentModel.accessors.size()) ) { @@ -485,10 +484,10 @@ namespace Cesium3DTiles { return; } - const tinygltf::Accessor& indicesAccessorGltf = parentModel.accessors[static_cast(primitive.indices)]; - if (indicesAccessorGltf.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) { + const CesiumGltf::Accessor& indicesAccessorGltf = parentModel.accessors[static_cast(primitive.indices)]; + if (indicesAccessorGltf.componentType == CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT) { upsamplePrimitiveForRasterOverlays(parentModel, model, mesh, primitive, childID); - } else if (indicesAccessorGltf.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT) { + } else if (indicesAccessorGltf.componentType == CesiumGltf::Accessor::ComponentType::UNSIGNED_INT) { upsamplePrimitiveForRasterOverlays(parentModel, model, mesh, primitive, childID); } } diff --git a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.h b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.h index 657afe1b8..2ab75fbd8 100644 --- a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.h +++ b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.h @@ -5,6 +5,6 @@ namespace Cesium3DTiles { - tinygltf::Model upsampleGltfForRasterOverlays(const tinygltf::Model& parentModel, CesiumGeometry::QuadtreeChild childID); + CesiumGltf::Model upsampleGltfForRasterOverlays(const CesiumGltf::Model& parentModel, CesiumGeometry::QuadtreeChild childID); } diff --git a/Cesium3DTiles/test/TestQuantizedMeshContent.cpp b/Cesium3DTiles/test/TestQuantizedMeshContent.cpp index 7ac0ae6bf..f6097f54c 100644 --- a/Cesium3DTiles/test/TestQuantizedMeshContent.cpp +++ b/Cesium3DTiles/test/TestQuantizedMeshContent.cpp @@ -606,9 +606,9 @@ TEST_CASE("Test converting quantized mesh to gltf with skirt") { REQUIRE(loadResult->model != std::nullopt); // make sure the gltf is the grid - const tinygltf::Model& model = *loadResult->model; - const tinygltf::Mesh& mesh = model.meshes.front(); - const tinygltf::Primitive& primitive = mesh.primitives.front(); + const CesiumGltf::Model& model = *loadResult->model; + const CesiumGltf::Mesh& mesh = model.meshes.front(); + const CesiumGltf::MeshPrimitive& primitive = mesh.primitives.front(); // make sure mesh contains grid mesh and skirts at the end GltfAccessor indices(model, static_cast(primitive.indices)); @@ -653,9 +653,9 @@ TEST_CASE("Test converting quantized mesh to gltf with skirt") { REQUIRE(loadResult->model != std::nullopt); // make sure the gltf is the grid - const tinygltf::Model& model = *loadResult->model; - const tinygltf::Mesh& mesh = model.meshes.front(); - const tinygltf::Primitive& primitive = mesh.primitives.front(); + const CesiumGltf::Model& model = *loadResult->model; + const CesiumGltf::Mesh& mesh = model.meshes.front(); + const CesiumGltf::Primitive& primitive = mesh.primitives.front(); // make sure mesh contains grid mesh and skirts at the end GltfAccessor indices(model, static_cast(primitive.indices)); @@ -700,9 +700,9 @@ TEST_CASE("Test converting quantized mesh to gltf with skirt") { REQUIRE(loadResult->model != std::nullopt); // make sure the gltf is the grid - const tinygltf::Model& model = *loadResult->model; - const tinygltf::Mesh& mesh = model.meshes.front(); - const tinygltf::Primitive& primitive = mesh.primitives.front(); + const CesiumGltf::Model& model = *loadResult->model; + const CesiumGltf::Mesh& mesh = model.meshes.front(); + const CesiumGltf::MeshPrimitive& primitive = mesh.primitives.front(); // make sure mesh contains grid mesh and skirts at the end GltfAccessor indices(model, static_cast(primitive.indices)); @@ -764,9 +764,9 @@ TEST_CASE("Test converting quantized mesh to gltf with skirt") { REQUIRE(loadResult->model != std::nullopt); // make sure the gltf has normals - const tinygltf::Model& model = *loadResult->model; - const tinygltf::Mesh& mesh = model.meshes.front(); - const tinygltf::Primitive& primitive = mesh.primitives.front(); + const CesiumGltf::Model& model = *loadResult->model; + const CesiumGltf::Mesh& mesh = model.meshes.front(); + const CesiumGltf::MeshPrimitive& primitive = mesh.primitives.front(); size_t westIndicesCount = quantizedMesh.vertexData.westIndices.size(); size_t southIndicesCount = quantizedMesh.vertexData.southIndices.size(); diff --git a/CesiumGltf/CMakeLists.txt b/CesiumGltf/CMakeLists.txt index 5a590fb48..6652cd3a0 100644 --- a/CesiumGltf/CMakeLists.txt +++ b/CesiumGltf/CMakeLists.txt @@ -16,8 +16,6 @@ target_sources( target_include_directories( CesiumGltf SYSTEM PUBLIC - # We're not using CMake for tinygltf at all, but it's header only. Add its headers here. - ${CMAKE_CURRENT_SOURCE_DIR}/../extern/tinygltf ${CMAKE_CURRENT_SOURCE_DIR}/../extern/rapidjson/include PUBLIC include @@ -27,4 +25,4 @@ target_include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../extern/cgltf ) -target_link_libraries(CesiumGltf PUBLIC CesiumGeometry CesiumUtility) +target_link_libraries(CesiumGltf PUBLIC) diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index efe4fcdbe..d09a1633f 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -11,7 +11,7 @@ namespace CesiumGltf { /** * @brief A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides a typed view into a bufferView or a subset of a bufferView similar to how WebGL's `vertexAttribPointer()` defines an attribute in a buffer. */ - struct Accessor final : public NamedObject { + struct Accessor : public NamedObject { enum class ComponentType { BYTE = 5120, diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparse.h b/CesiumGltf/include/CesiumGltf/AccessorSparse.h index 6fd82c12e..11d285e89 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparse.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparse.h @@ -11,7 +11,7 @@ namespace CesiumGltf { /** * @brief Sparse storage of attributes that deviate from their initialization value. */ - struct AccessorSparse final : public ExtensibleObject { + struct AccessorSparse : public ExtensibleObject { /** * @brief Number of entries stored in the sparse array. diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h index 4ef007b8a..fa691f3cd 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h @@ -9,7 +9,7 @@ namespace CesiumGltf { /** * @brief Indices of those attributes that deviate from their initialization value. */ - struct AccessorSparseIndices final : public ExtensibleObject { + struct AccessorSparseIndices : public ExtensibleObject { enum class ComponentType { UNSIGNED_BYTE = 5121, diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h index 5be53822a..a62d1bc90 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h @@ -9,7 +9,7 @@ namespace CesiumGltf { /** * @brief Array of size `accessor.sparse.count` times number of components storing the displaced accessor attributes pointed by `accessor.sparse.indices`. */ - struct AccessorSparseValues final : public ExtensibleObject { + struct AccessorSparseValues : public ExtensibleObject { /** * @brief The index of the bufferView with sparse values. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target. diff --git a/CesiumGltf/include/CesiumGltf/Animation.h b/CesiumGltf/include/CesiumGltf/Animation.h index 58625aaf2..268d34ab3 100644 --- a/CesiumGltf/include/CesiumGltf/Animation.h +++ b/CesiumGltf/include/CesiumGltf/Animation.h @@ -11,7 +11,7 @@ namespace CesiumGltf { /** * @brief A keyframe animation. */ - struct Animation final : public NamedObject { + struct Animation : public NamedObject { /** * @brief An array of channels, each of which targets an animation's sampler at a node's property. Different channels of the same animation can't have equal targets. diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannel.h b/CesiumGltf/include/CesiumGltf/AnimationChannel.h index ce8493e69..126306e74 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationChannel.h +++ b/CesiumGltf/include/CesiumGltf/AnimationChannel.h @@ -10,7 +10,7 @@ namespace CesiumGltf { /** * @brief Targets an animation's sampler at a node's property. */ - struct AnimationChannel final : public ExtensibleObject { + struct AnimationChannel : public ExtensibleObject { /** * @brief The index of a sampler in this animation used to compute the value for the target. diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h index 76c6d0c0a..046dd89bb 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h +++ b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h @@ -9,7 +9,7 @@ namespace CesiumGltf { /** * @brief The index of the node and TRS property that an animation channel targets. */ - struct AnimationChannelTarget final : public ExtensibleObject { + struct AnimationChannelTarget : public ExtensibleObject { enum class Path { translation, diff --git a/CesiumGltf/include/CesiumGltf/AnimationSampler.h b/CesiumGltf/include/CesiumGltf/AnimationSampler.h index 9faf5b913..91716d0d6 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationSampler.h +++ b/CesiumGltf/include/CesiumGltf/AnimationSampler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { /** * @brief Combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target). */ - struct AnimationSampler final : public ExtensibleObject { + struct AnimationSampler : public ExtensibleObject { enum class Interpolation { LINEAR, diff --git a/CesiumGltf/include/CesiumGltf/Asset.h b/CesiumGltf/include/CesiumGltf/Asset.h index c314358f2..331e97270 100644 --- a/CesiumGltf/include/CesiumGltf/Asset.h +++ b/CesiumGltf/include/CesiumGltf/Asset.h @@ -9,7 +9,7 @@ namespace CesiumGltf { /** * @brief Metadata about the glTF asset. */ - struct Asset final : public ExtensibleObject { + struct Asset : public ExtensibleObject { /** * @brief A copyright message suitable for display to credit the content creator. diff --git a/CesiumGltf/include/CesiumGltf/Buffer.h b/CesiumGltf/include/CesiumGltf/Buffer.h index a0a91210a..0b58845da 100644 --- a/CesiumGltf/include/CesiumGltf/Buffer.h +++ b/CesiumGltf/include/CesiumGltf/Buffer.h @@ -11,7 +11,7 @@ namespace CesiumGltf { /** * @brief A buffer points to binary geometry, animation, or skins. */ - struct Buffer final : public NamedObject { + struct Buffer : public NamedObject { /** * @brief The uri of the buffer. diff --git a/CesiumGltf/include/CesiumGltf/BufferView.h b/CesiumGltf/include/CesiumGltf/BufferView.h index ca04c032e..0e8eec307 100644 --- a/CesiumGltf/include/CesiumGltf/BufferView.h +++ b/CesiumGltf/include/CesiumGltf/BufferView.h @@ -9,7 +9,7 @@ namespace CesiumGltf { /** * @brief A view into a buffer generally representing a subset of the buffer. */ - struct BufferView final : public NamedObject { + struct BufferView : public NamedObject { enum class Target { ARRAY_BUFFER = 34962, diff --git a/CesiumGltf/include/CesiumGltf/Camera.h b/CesiumGltf/include/CesiumGltf/Camera.h index c78d0d2da..6eb8e7c94 100644 --- a/CesiumGltf/include/CesiumGltf/Camera.h +++ b/CesiumGltf/include/CesiumGltf/Camera.h @@ -10,7 +10,7 @@ namespace CesiumGltf { /** * @brief A camera's projection. A node can reference a camera to apply a transform to place the camera in the scene. */ - struct Camera final : public NamedObject { + struct Camera : public NamedObject { enum class Type { perspective, diff --git a/CesiumGltf/include/CesiumGltf/CameraOrthographic.h b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h index b2cb7c24b..efb7409c4 100644 --- a/CesiumGltf/include/CesiumGltf/CameraOrthographic.h +++ b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h @@ -8,7 +8,7 @@ namespace CesiumGltf { /** * @brief An orthographic camera containing properties to create an orthographic projection matrix. */ - struct CameraOrthographic final : public ExtensibleObject { + struct CameraOrthographic : public ExtensibleObject { /** * @brief The floating-point horizontal magnification of the view. Must not be zero. diff --git a/CesiumGltf/include/CesiumGltf/CameraPerspective.h b/CesiumGltf/include/CesiumGltf/CameraPerspective.h index abac81114..10d5df37b 100644 --- a/CesiumGltf/include/CesiumGltf/CameraPerspective.h +++ b/CesiumGltf/include/CesiumGltf/CameraPerspective.h @@ -8,7 +8,7 @@ namespace CesiumGltf { /** * @brief A perspective camera containing properties to create a perspective projection matrix. */ - struct CameraPerspective final : public ExtensibleObject { + struct CameraPerspective : public ExtensibleObject { /** * @brief The floating-point aspect ratio of the field of view. diff --git a/CesiumGltf/include/CesiumGltf/Image.h b/CesiumGltf/include/CesiumGltf/Image.h index 21630ffa0..e9f29ac2d 100644 --- a/CesiumGltf/include/CesiumGltf/Image.h +++ b/CesiumGltf/include/CesiumGltf/Image.h @@ -11,7 +11,7 @@ namespace CesiumGltf { /** * @brief Image data used to create a texture. Image can be referenced by URI or `bufferView` index. `mimeType` is required in the latter case. */ - struct Image final : public NamedObject { + struct Image : public NamedObject { enum class MimeType { image_jpeg, diff --git a/CesiumGltf/include/CesiumGltf/Material.h b/CesiumGltf/include/CesiumGltf/Material.h index b450e3ed4..8ff89627f 100644 --- a/CesiumGltf/include/CesiumGltf/Material.h +++ b/CesiumGltf/include/CesiumGltf/Material.h @@ -13,7 +13,7 @@ namespace CesiumGltf { /** * @brief The material appearance of a primitive. */ - struct Material final : public NamedObject { + struct Material : public NamedObject { enum class AlphaMode { OPAQUE, diff --git a/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h index ba16981b9..2b645ca32 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h @@ -2,13 +2,13 @@ // DO NOT EDIT THIS FILE! #pragma once -#include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/TextureInfo.h" namespace CesiumGltf { /** * @brief undefined */ - struct MaterialNormalTextureInfo final : public ExtensibleObject { + struct MaterialNormalTextureInfo : public TextureInfo { /** * @brief The scalar multiplier applied to each normal vector of the normal texture. diff --git a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h index ed1c1c9c4..cbba82b41 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h @@ -2,13 +2,13 @@ // DO NOT EDIT THIS FILE! #pragma once -#include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/TextureInfo.h" namespace CesiumGltf { /** * @brief undefined */ - struct MaterialOcclusionTextureInfo final : public ExtensibleObject { + struct MaterialOcclusionTextureInfo : public TextureInfo { /** * @brief A scalar multiplier controlling the amount of occlusion applied. diff --git a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h index 54dba0c67..c2f42bc04 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h +++ b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h @@ -10,7 +10,7 @@ namespace CesiumGltf { /** * @brief A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology. */ - struct MaterialPBRMetallicRoughness final : public ExtensibleObject { + struct MaterialPBRMetallicRoughness : public ExtensibleObject { /** * @brief The material's base color factor. diff --git a/CesiumGltf/include/CesiumGltf/Mesh.h b/CesiumGltf/include/CesiumGltf/Mesh.h index 45ce7e33b..607831909 100644 --- a/CesiumGltf/include/CesiumGltf/Mesh.h +++ b/CesiumGltf/include/CesiumGltf/Mesh.h @@ -10,7 +10,7 @@ namespace CesiumGltf { /** * @brief A set of primitives to be rendered. A node can contain one mesh. A node's transform places the mesh in the scene. */ - struct Mesh final : public NamedObject { + struct Mesh : public NamedObject { /** * @brief An array of primitives, each defining geometry to be rendered with a material. diff --git a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h index b2d027cb1..4f0bae603 100644 --- a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h +++ b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h @@ -11,7 +11,7 @@ namespace CesiumGltf { /** * @brief Geometry to be rendered with the given material. */ - struct MeshPrimitive final : public ExtensibleObject { + struct MeshPrimitive : public ExtensibleObject { enum class Mode { POINTS = 0, diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index 28da2fe74..b6cffa30b 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -25,7 +25,7 @@ namespace CesiumGltf { /** * @brief The root object for a glTF asset. */ - struct Model final : public ExtensibleObject { + struct Model : public ExtensibleObject { /** * @brief Names of glTF extensions used somewhere in this asset. diff --git a/CesiumGltf/include/CesiumGltf/Node.h b/CesiumGltf/include/CesiumGltf/Node.h index cb8bcc374..a18d31aea 100644 --- a/CesiumGltf/include/CesiumGltf/Node.h +++ b/CesiumGltf/include/CesiumGltf/Node.h @@ -10,7 +10,7 @@ namespace CesiumGltf { /** * @brief A node in the node hierarchy. When the node contains `skin`, all `mesh.primitives` must contain `JOINTS_0` and `WEIGHTS_0` attributes. A node can have either a `matrix` or any combination of `translation`/`rotation`/`scale` (TRS) properties. TRS properties are converted to matrices and postmultiplied in the `T * R * S` order to compose the transformation matrix; first the scale is applied to the vertices, then the rotation, and then the translation. If none are provided, the transform is the identity. When a node is targeted for animation (referenced by an animation.channel.target), only TRS properties may be present; `matrix` will not be present. */ - struct Node final : public NamedObject { + struct Node : public NamedObject { /** * @brief The index of the camera referenced by this node. diff --git a/CesiumGltf/include/CesiumGltf/Sampler.h b/CesiumGltf/include/CesiumGltf/Sampler.h index 032e48208..bebb10132 100644 --- a/CesiumGltf/include/CesiumGltf/Sampler.h +++ b/CesiumGltf/include/CesiumGltf/Sampler.h @@ -8,7 +8,7 @@ namespace CesiumGltf { /** * @brief Texture sampler properties for filtering and wrapping modes. */ - struct Sampler final : public NamedObject { + struct Sampler : public NamedObject { enum class MagFilter { NEAREST = 9728, diff --git a/CesiumGltf/include/CesiumGltf/Scene.h b/CesiumGltf/include/CesiumGltf/Scene.h index fc6661c96..53771fb45 100644 --- a/CesiumGltf/include/CesiumGltf/Scene.h +++ b/CesiumGltf/include/CesiumGltf/Scene.h @@ -10,7 +10,7 @@ namespace CesiumGltf { /** * @brief The root nodes of a scene. */ - struct Scene final : public NamedObject { + struct Scene : public NamedObject { /** * @brief The indices of each root node. diff --git a/CesiumGltf/include/CesiumGltf/Skin.h b/CesiumGltf/include/CesiumGltf/Skin.h index a70825757..331bca601 100644 --- a/CesiumGltf/include/CesiumGltf/Skin.h +++ b/CesiumGltf/include/CesiumGltf/Skin.h @@ -10,7 +10,7 @@ namespace CesiumGltf { /** * @brief Joints and matrices defining a skin. */ - struct Skin final : public NamedObject { + struct Skin : public NamedObject { /** * @brief The index of the accessor containing the floating-point 4x4 inverse-bind matrices. The default is that each matrix is a 4x4 identity matrix, which implies that inverse-bind matrices were pre-applied. diff --git a/CesiumGltf/include/CesiumGltf/Texture.h b/CesiumGltf/include/CesiumGltf/Texture.h index 5775de335..2c8518a05 100644 --- a/CesiumGltf/include/CesiumGltf/Texture.h +++ b/CesiumGltf/include/CesiumGltf/Texture.h @@ -9,7 +9,7 @@ namespace CesiumGltf { /** * @brief A texture and its sampler. */ - struct Texture final : public NamedObject { + struct Texture : public NamedObject { /** * @brief The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used. diff --git a/CesiumGltf/include/CesiumGltf/TextureInfo.h b/CesiumGltf/include/CesiumGltf/TextureInfo.h index e0e0a7a54..5cacd3f4d 100644 --- a/CesiumGltf/include/CesiumGltf/TextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/TextureInfo.h @@ -9,7 +9,7 @@ namespace CesiumGltf { /** * @brief Reference to a texture. */ - struct TextureInfo final : public ExtensibleObject { + struct TextureInfo : public ExtensibleObject { /** * @brief The index of the texture. diff --git a/CesiumGltfReader/CMakeLists.txt b/CesiumGltfReader/CMakeLists.txt index 52c99223c..2af5ce8db 100644 --- a/CesiumGltfReader/CMakeLists.txt +++ b/CesiumGltfReader/CMakeLists.txt @@ -24,4 +24,4 @@ target_include_directories( generated ) -target_link_libraries(CesiumGltfReader PUBLIC CesiumGltf) +target_link_libraries(CesiumGltfReader PUBLIC CesiumGltf GSL) diff --git a/CesiumGltfReader/generated/AccessorJsonHandler.cpp b/CesiumGltfReader/generated/AccessorJsonHandler.cpp index abee605eb..6a09a2c65 100644 --- a/CesiumGltfReader/generated/AccessorJsonHandler.cpp +++ b/CesiumGltfReader/generated/AccessorJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void AccessorJsonHandler::reset(IJsonHandler* pParent, Accessor* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,19 +24,22 @@ void AccessorJsonHandler::reportWarning(const std::string& warning, std::vector< } IJsonHandler* AccessorJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->AccessorKey(str, *this->_pObject); +} + +IJsonHandler* AccessorJsonHandler::AccessorKey(const char* str, Accessor& o) { + using namespace std::string_literals; - if ("bufferView"s == str) return property("bufferView", this->_bufferView, this->_pObject->bufferView); - if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, this->_pObject->byteOffset); - if ("componentType"s == str) return property("componentType", this->_componentType, this->_pObject->componentType); - if ("normalized"s == str) return property("normalized", this->_normalized, this->_pObject->normalized); - if ("count"s == str) return property("count", this->_count, this->_pObject->count); - if ("type"s == str) return property("type", this->_type, this->_pObject->type); - if ("max"s == str) return property("max", this->_max, this->_pObject->max); - if ("min"s == str) return property("min", this->_min, this->_pObject->min); - if ("sparse"s == str) return property("sparse", this->_sparse, this->_pObject->sparse); + if ("bufferView"s == str) return property("bufferView", this->_bufferView, o.bufferView); + if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, o.byteOffset); + if ("componentType"s == str) return property("componentType", this->_componentType, o.componentType); + if ("normalized"s == str) return property("normalized", this->_normalized, o.normalized); + if ("count"s == str) return property("count", this->_count, o.count); + if ("type"s == str) return property("type", this->_type, o.type); + if ("max"s == str) return property("max", this->_max, o.max); + if ("min"s == str) return property("min", this->_min, o.min); + if ("sparse"s == str) return property("sparse", this->_sparse, o.sparse); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/AccessorJsonHandler.h b/CesiumGltfReader/generated/AccessorJsonHandler.h index 7f52c7770..b4410c044 100644 --- a/CesiumGltfReader/generated/AccessorJsonHandler.h +++ b/CesiumGltfReader/generated/AccessorJsonHandler.h @@ -13,7 +13,7 @@ namespace CesiumGltf { struct Accessor; - class AccessorJsonHandler final : public NamedObjectJsonHandler { + class AccessorJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Accessor* pObject); Accessor* getObject(); @@ -21,6 +21,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* AccessorKey(const char* str, Accessor& o); + private: class TypeJsonHandler : public JsonHandler { public: diff --git a/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp index d46c99f0b..0c2904005 100644 --- a/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp +++ b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void AccessorSparseIndicesJsonHandler::reset(IJsonHandler* pParent, AccessorSparseIndices* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,13 +24,16 @@ void AccessorSparseIndicesJsonHandler::reportWarning(const std::string& warning, } IJsonHandler* AccessorSparseIndicesJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->AccessorSparseIndicesKey(str, *this->_pObject); +} + +IJsonHandler* AccessorSparseIndicesJsonHandler::AccessorSparseIndicesKey(const char* str, AccessorSparseIndices& o) { + using namespace std::string_literals; - if ("bufferView"s == str) return property("bufferView", this->_bufferView, this->_pObject->bufferView); - if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, this->_pObject->byteOffset); - if ("componentType"s == str) return property("componentType", this->_componentType, this->_pObject->componentType); + if ("bufferView"s == str) return property("bufferView", this->_bufferView, o.bufferView); + if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, o.byteOffset); + if ("componentType"s == str) return property("componentType", this->_componentType, o.componentType); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.h b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.h index d6322f626..aaaa7f3b7 100644 --- a/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.h +++ b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { struct AccessorSparseIndices; - class AccessorSparseIndicesJsonHandler final : public ExtensibleObjectJsonHandler { + class AccessorSparseIndicesJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, AccessorSparseIndices* pObject); AccessorSparseIndices* getObject(); @@ -17,6 +17,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* AccessorSparseIndicesKey(const char* str, AccessorSparseIndices& o); + private: AccessorSparseIndices* _pObject; diff --git a/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp b/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp index 9b7aa05a8..e613c44b0 100644 --- a/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp +++ b/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void AccessorSparseJsonHandler::reset(IJsonHandler* pParent, AccessorSparse* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,13 +24,16 @@ void AccessorSparseJsonHandler::reportWarning(const std::string& warning, std::v } IJsonHandler* AccessorSparseJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->AccessorSparseKey(str, *this->_pObject); +} + +IJsonHandler* AccessorSparseJsonHandler::AccessorSparseKey(const char* str, AccessorSparse& o) { + using namespace std::string_literals; - if ("count"s == str) return property("count", this->_count, this->_pObject->count); - if ("indices"s == str) return property("indices", this->_indices, this->_pObject->indices); - if ("values"s == str) return property("values", this->_values, this->_pObject->values); + if ("count"s == str) return property("count", this->_count, o.count); + if ("indices"s == str) return property("indices", this->_indices, o.indices); + if ("values"s == str) return property("values", this->_values, o.values); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/AccessorSparseJsonHandler.h b/CesiumGltfReader/generated/AccessorSparseJsonHandler.h index 062834bcd..e39ae4097 100644 --- a/CesiumGltfReader/generated/AccessorSparseJsonHandler.h +++ b/CesiumGltfReader/generated/AccessorSparseJsonHandler.h @@ -10,7 +10,7 @@ namespace CesiumGltf { struct AccessorSparse; - class AccessorSparseJsonHandler final : public ExtensibleObjectJsonHandler { + class AccessorSparseJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, AccessorSparse* pObject); AccessorSparse* getObject(); @@ -18,6 +18,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* AccessorSparseKey(const char* str, AccessorSparse& o); + private: AccessorSparse* _pObject; diff --git a/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp index 06ac8a665..3ff2abd49 100644 --- a/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp +++ b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void AccessorSparseValuesJsonHandler::reset(IJsonHandler* pParent, AccessorSparseValues* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,12 +24,15 @@ void AccessorSparseValuesJsonHandler::reportWarning(const std::string& warning, } IJsonHandler* AccessorSparseValuesJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->AccessorSparseValuesKey(str, *this->_pObject); +} + +IJsonHandler* AccessorSparseValuesJsonHandler::AccessorSparseValuesKey(const char* str, AccessorSparseValues& o) { + using namespace std::string_literals; - if ("bufferView"s == str) return property("bufferView", this->_bufferView, this->_pObject->bufferView); - if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, this->_pObject->byteOffset); + if ("bufferView"s == str) return property("bufferView", this->_bufferView, o.bufferView); + if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, o.byteOffset); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.h b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.h index 7856e490e..3b1a5e4f6 100644 --- a/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.h +++ b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.h @@ -8,7 +8,7 @@ namespace CesiumGltf { struct AccessorSparseValues; - class AccessorSparseValuesJsonHandler final : public ExtensibleObjectJsonHandler { + class AccessorSparseValuesJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, AccessorSparseValues* pObject); AccessorSparseValues* getObject(); @@ -16,6 +16,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* AccessorSparseValuesKey(const char* str, AccessorSparseValues& o); + private: AccessorSparseValues* _pObject; diff --git a/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp b/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp index c5e4f3948..a1f34cb9e 100644 --- a/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp +++ b/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void AnimationChannelJsonHandler::reset(IJsonHandler* pParent, AnimationChannel* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,12 +24,15 @@ void AnimationChannelJsonHandler::reportWarning(const std::string& warning, std: } IJsonHandler* AnimationChannelJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->AnimationChannelKey(str, *this->_pObject); +} + +IJsonHandler* AnimationChannelJsonHandler::AnimationChannelKey(const char* str, AnimationChannel& o) { + using namespace std::string_literals; - if ("sampler"s == str) return property("sampler", this->_sampler, this->_pObject->sampler); - if ("target"s == str) return property("target", this->_target, this->_pObject->target); + if ("sampler"s == str) return property("sampler", this->_sampler, o.sampler); + if ("target"s == str) return property("target", this->_target, o.target); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/AnimationChannelJsonHandler.h b/CesiumGltfReader/generated/AnimationChannelJsonHandler.h index e33eb7a66..ad4cecac2 100644 --- a/CesiumGltfReader/generated/AnimationChannelJsonHandler.h +++ b/CesiumGltfReader/generated/AnimationChannelJsonHandler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { struct AnimationChannel; - class AnimationChannelJsonHandler final : public ExtensibleObjectJsonHandler { + class AnimationChannelJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, AnimationChannel* pObject); AnimationChannel* getObject(); @@ -17,6 +17,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* AnimationChannelKey(const char* str, AnimationChannel& o); + private: AnimationChannel* _pObject; diff --git a/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp index 49c28e0be..34ef520ce 100644 --- a/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp +++ b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void AnimationChannelTargetJsonHandler::reset(IJsonHandler* pParent, AnimationChannelTarget* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,12 +24,15 @@ void AnimationChannelTargetJsonHandler::reportWarning(const std::string& warning } IJsonHandler* AnimationChannelTargetJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->AnimationChannelTargetKey(str, *this->_pObject); +} + +IJsonHandler* AnimationChannelTargetJsonHandler::AnimationChannelTargetKey(const char* str, AnimationChannelTarget& o) { + using namespace std::string_literals; - if ("node"s == str) return property("node", this->_node, this->_pObject->node); - if ("path"s == str) return property("path", this->_path, this->_pObject->path); + if ("node"s == str) return property("node", this->_node, o.node); + if ("path"s == str) return property("path", this->_path, o.path); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.h b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.h index 4a48c2ca3..ee7f709fa 100644 --- a/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.h +++ b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { struct AnimationChannelTarget; - class AnimationChannelTargetJsonHandler final : public ExtensibleObjectJsonHandler { + class AnimationChannelTargetJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, AnimationChannelTarget* pObject); AnimationChannelTarget* getObject(); @@ -17,6 +17,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* AnimationChannelTargetKey(const char* str, AnimationChannelTarget& o); + private: class PathJsonHandler : public JsonHandler { public: diff --git a/CesiumGltfReader/generated/AnimationJsonHandler.cpp b/CesiumGltfReader/generated/AnimationJsonHandler.cpp index 3f3c87099..b91a03d3e 100644 --- a/CesiumGltfReader/generated/AnimationJsonHandler.cpp +++ b/CesiumGltfReader/generated/AnimationJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void AnimationJsonHandler::reset(IJsonHandler* pParent, Animation* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,12 +24,15 @@ void AnimationJsonHandler::reportWarning(const std::string& warning, std::vector } IJsonHandler* AnimationJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->AnimationKey(str, *this->_pObject); +} + +IJsonHandler* AnimationJsonHandler::AnimationKey(const char* str, Animation& o) { + using namespace std::string_literals; - if ("channels"s == str) return property("channels", this->_channels, this->_pObject->channels); - if ("samplers"s == str) return property("samplers", this->_samplers, this->_pObject->samplers); + if ("channels"s == str) return property("channels", this->_channels, o.channels); + if ("samplers"s == str) return property("samplers", this->_samplers, o.samplers); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/AnimationJsonHandler.h b/CesiumGltfReader/generated/AnimationJsonHandler.h index a6783411f..2f5bb3d72 100644 --- a/CesiumGltfReader/generated/AnimationJsonHandler.h +++ b/CesiumGltfReader/generated/AnimationJsonHandler.h @@ -10,7 +10,7 @@ namespace CesiumGltf { struct Animation; - class AnimationJsonHandler final : public NamedObjectJsonHandler { + class AnimationJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Animation* pObject); Animation* getObject(); @@ -18,6 +18,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* AnimationKey(const char* str, Animation& o); + private: Animation* _pObject; diff --git a/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp index 0d2306d7e..6ce50c5d4 100644 --- a/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp +++ b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void AnimationSamplerJsonHandler::reset(IJsonHandler* pParent, AnimationSampler* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,13 +24,16 @@ void AnimationSamplerJsonHandler::reportWarning(const std::string& warning, std: } IJsonHandler* AnimationSamplerJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->AnimationSamplerKey(str, *this->_pObject); +} + +IJsonHandler* AnimationSamplerJsonHandler::AnimationSamplerKey(const char* str, AnimationSampler& o) { + using namespace std::string_literals; - if ("input"s == str) return property("input", this->_input, this->_pObject->input); - if ("interpolation"s == str) return property("interpolation", this->_interpolation, this->_pObject->interpolation); - if ("output"s == str) return property("output", this->_output, this->_pObject->output); + if ("input"s == str) return property("input", this->_input, o.input); + if ("interpolation"s == str) return property("interpolation", this->_interpolation, o.interpolation); + if ("output"s == str) return property("output", this->_output, o.output); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/AnimationSamplerJsonHandler.h b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.h index 963c9bea2..e3ab52166 100644 --- a/CesiumGltfReader/generated/AnimationSamplerJsonHandler.h +++ b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { struct AnimationSampler; - class AnimationSamplerJsonHandler final : public ExtensibleObjectJsonHandler { + class AnimationSamplerJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, AnimationSampler* pObject); AnimationSampler* getObject(); @@ -17,6 +17,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* AnimationSamplerKey(const char* str, AnimationSampler& o); + private: class InterpolationJsonHandler : public JsonHandler { public: diff --git a/CesiumGltfReader/generated/AssetJsonHandler.cpp b/CesiumGltfReader/generated/AssetJsonHandler.cpp index 1baffe8a5..6451ed7a7 100644 --- a/CesiumGltfReader/generated/AssetJsonHandler.cpp +++ b/CesiumGltfReader/generated/AssetJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void AssetJsonHandler::reset(IJsonHandler* pParent, Asset* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,14 +24,17 @@ void AssetJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->AssetKey(str, *this->_pObject); +} + +IJsonHandler* AssetJsonHandler::AssetKey(const char* str, Asset& o) { + using namespace std::string_literals; - if ("copyright"s == str) return property("copyright", this->_copyright, this->_pObject->copyright); - if ("generator"s == str) return property("generator", this->_generator, this->_pObject->generator); - if ("version"s == str) return property("version", this->_version, this->_pObject->version); - if ("minVersion"s == str) return property("minVersion", this->_minVersion, this->_pObject->minVersion); + if ("copyright"s == str) return property("copyright", this->_copyright, o.copyright); + if ("generator"s == str) return property("generator", this->_generator, o.generator); + if ("version"s == str) return property("version", this->_version, o.version); + if ("minVersion"s == str) return property("minVersion", this->_minVersion, o.minVersion); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/AssetJsonHandler.h b/CesiumGltfReader/generated/AssetJsonHandler.h index bcf0af477..81cca28a7 100644 --- a/CesiumGltfReader/generated/AssetJsonHandler.h +++ b/CesiumGltfReader/generated/AssetJsonHandler.h @@ -8,7 +8,7 @@ namespace CesiumGltf { struct Asset; - class AssetJsonHandler final : public ExtensibleObjectJsonHandler { + class AssetJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Asset* pObject); Asset* getObject(); @@ -16,6 +16,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* AssetKey(const char* str, Asset& o); + private: Asset* _pObject; diff --git a/CesiumGltfReader/generated/BufferJsonHandler.cpp b/CesiumGltfReader/generated/BufferJsonHandler.cpp index 9096fe5ed..1e99f0615 100644 --- a/CesiumGltfReader/generated/BufferJsonHandler.cpp +++ b/CesiumGltfReader/generated/BufferJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void BufferJsonHandler::reset(IJsonHandler* pParent, Buffer* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,12 +24,15 @@ void BufferJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->BufferKey(str, *this->_pObject); +} + +IJsonHandler* BufferJsonHandler::BufferKey(const char* str, Buffer& o) { + using namespace std::string_literals; - if ("uri"s == str) return property("uri", this->_uri, this->_pObject->uri); - if ("byteLength"s == str) return property("byteLength", this->_byteLength, this->_pObject->byteLength); + if ("uri"s == str) return property("uri", this->_uri, o.uri); + if ("byteLength"s == str) return property("byteLength", this->_byteLength, o.byteLength); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/BufferJsonHandler.h b/CesiumGltfReader/generated/BufferJsonHandler.h index 2446c05d7..875ee1afa 100644 --- a/CesiumGltfReader/generated/BufferJsonHandler.h +++ b/CesiumGltfReader/generated/BufferJsonHandler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { struct Buffer; - class BufferJsonHandler final : public NamedObjectJsonHandler { + class BufferJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Buffer* pObject); Buffer* getObject(); @@ -17,6 +17,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* BufferKey(const char* str, Buffer& o); + private: Buffer* _pObject; diff --git a/CesiumGltfReader/generated/BufferViewJsonHandler.cpp b/CesiumGltfReader/generated/BufferViewJsonHandler.cpp index a7ef76f75..14854983c 100644 --- a/CesiumGltfReader/generated/BufferViewJsonHandler.cpp +++ b/CesiumGltfReader/generated/BufferViewJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void BufferViewJsonHandler::reset(IJsonHandler* pParent, BufferView* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,15 +24,18 @@ void BufferViewJsonHandler::reportWarning(const std::string& warning, std::vecto } IJsonHandler* BufferViewJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->BufferViewKey(str, *this->_pObject); +} + +IJsonHandler* BufferViewJsonHandler::BufferViewKey(const char* str, BufferView& o) { + using namespace std::string_literals; - if ("buffer"s == str) return property("buffer", this->_buffer, this->_pObject->buffer); - if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, this->_pObject->byteOffset); - if ("byteLength"s == str) return property("byteLength", this->_byteLength, this->_pObject->byteLength); - if ("byteStride"s == str) return property("byteStride", this->_byteStride, this->_pObject->byteStride); - if ("target"s == str) return property("target", this->_target, this->_pObject->target); + if ("buffer"s == str) return property("buffer", this->_buffer, o.buffer); + if ("byteOffset"s == str) return property("byteOffset", this->_byteOffset, o.byteOffset); + if ("byteLength"s == str) return property("byteLength", this->_byteLength, o.byteLength); + if ("byteStride"s == str) return property("byteStride", this->_byteStride, o.byteStride); + if ("target"s == str) return property("target", this->_target, o.target); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/BufferViewJsonHandler.h b/CesiumGltfReader/generated/BufferViewJsonHandler.h index df515eaa3..ef53a355c 100644 --- a/CesiumGltfReader/generated/BufferViewJsonHandler.h +++ b/CesiumGltfReader/generated/BufferViewJsonHandler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { struct BufferView; - class BufferViewJsonHandler final : public NamedObjectJsonHandler { + class BufferViewJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, BufferView* pObject); BufferView* getObject(); @@ -17,6 +17,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* BufferViewKey(const char* str, BufferView& o); + private: BufferView* _pObject; diff --git a/CesiumGltfReader/generated/CameraJsonHandler.cpp b/CesiumGltfReader/generated/CameraJsonHandler.cpp index 38d9cc9a5..5725f6082 100644 --- a/CesiumGltfReader/generated/CameraJsonHandler.cpp +++ b/CesiumGltfReader/generated/CameraJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void CameraJsonHandler::reset(IJsonHandler* pParent, Camera* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,13 +24,16 @@ void CameraJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->CameraKey(str, *this->_pObject); +} + +IJsonHandler* CameraJsonHandler::CameraKey(const char* str, Camera& o) { + using namespace std::string_literals; - if ("orthographic"s == str) return property("orthographic", this->_orthographic, this->_pObject->orthographic); - if ("perspective"s == str) return property("perspective", this->_perspective, this->_pObject->perspective); - if ("type"s == str) return property("type", this->_type, this->_pObject->type); + if ("orthographic"s == str) return property("orthographic", this->_orthographic, o.orthographic); + if ("perspective"s == str) return property("perspective", this->_perspective, o.perspective); + if ("type"s == str) return property("type", this->_type, o.type); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/CameraJsonHandler.h b/CesiumGltfReader/generated/CameraJsonHandler.h index eb09810d5..c32588876 100644 --- a/CesiumGltfReader/generated/CameraJsonHandler.h +++ b/CesiumGltfReader/generated/CameraJsonHandler.h @@ -10,7 +10,7 @@ namespace CesiumGltf { struct Camera; - class CameraJsonHandler final : public NamedObjectJsonHandler { + class CameraJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Camera* pObject); Camera* getObject(); @@ -18,6 +18,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* CameraKey(const char* str, Camera& o); + private: class TypeJsonHandler : public JsonHandler { public: diff --git a/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp index 47b8e7113..84df21893 100644 --- a/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp +++ b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void CameraOrthographicJsonHandler::reset(IJsonHandler* pParent, CameraOrthographic* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,14 +24,17 @@ void CameraOrthographicJsonHandler::reportWarning(const std::string& warning, st } IJsonHandler* CameraOrthographicJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->CameraOrthographicKey(str, *this->_pObject); +} + +IJsonHandler* CameraOrthographicJsonHandler::CameraOrthographicKey(const char* str, CameraOrthographic& o) { + using namespace std::string_literals; - if ("xmag"s == str) return property("xmag", this->_xmag, this->_pObject->xmag); - if ("ymag"s == str) return property("ymag", this->_ymag, this->_pObject->ymag); - if ("zfar"s == str) return property("zfar", this->_zfar, this->_pObject->zfar); - if ("znear"s == str) return property("znear", this->_znear, this->_pObject->znear); + if ("xmag"s == str) return property("xmag", this->_xmag, o.xmag); + if ("ymag"s == str) return property("ymag", this->_ymag, o.ymag); + if ("zfar"s == str) return property("zfar", this->_zfar, o.zfar); + if ("znear"s == str) return property("znear", this->_znear, o.znear); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/CameraOrthographicJsonHandler.h b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.h index 8e4c09a28..40fff6b1e 100644 --- a/CesiumGltfReader/generated/CameraOrthographicJsonHandler.h +++ b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.h @@ -8,7 +8,7 @@ namespace CesiumGltf { struct CameraOrthographic; - class CameraOrthographicJsonHandler final : public ExtensibleObjectJsonHandler { + class CameraOrthographicJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, CameraOrthographic* pObject); CameraOrthographic* getObject(); @@ -16,6 +16,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* CameraOrthographicKey(const char* str, CameraOrthographic& o); + private: CameraOrthographic* _pObject; diff --git a/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp index 40fd48ee6..759e03216 100644 --- a/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp +++ b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void CameraPerspectiveJsonHandler::reset(IJsonHandler* pParent, CameraPerspective* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,14 +24,17 @@ void CameraPerspectiveJsonHandler::reportWarning(const std::string& warning, std } IJsonHandler* CameraPerspectiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->CameraPerspectiveKey(str, *this->_pObject); +} + +IJsonHandler* CameraPerspectiveJsonHandler::CameraPerspectiveKey(const char* str, CameraPerspective& o) { + using namespace std::string_literals; - if ("aspectRatio"s == str) return property("aspectRatio", this->_aspectRatio, this->_pObject->aspectRatio); - if ("yfov"s == str) return property("yfov", this->_yfov, this->_pObject->yfov); - if ("zfar"s == str) return property("zfar", this->_zfar, this->_pObject->zfar); - if ("znear"s == str) return property("znear", this->_znear, this->_pObject->znear); + if ("aspectRatio"s == str) return property("aspectRatio", this->_aspectRatio, o.aspectRatio); + if ("yfov"s == str) return property("yfov", this->_yfov, o.yfov); + if ("zfar"s == str) return property("zfar", this->_zfar, o.zfar); + if ("znear"s == str) return property("znear", this->_znear, o.znear); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.h b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.h index d72a0c8df..155ae50ba 100644 --- a/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.h +++ b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.h @@ -8,7 +8,7 @@ namespace CesiumGltf { struct CameraPerspective; - class CameraPerspectiveJsonHandler final : public ExtensibleObjectJsonHandler { + class CameraPerspectiveJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, CameraPerspective* pObject); CameraPerspective* getObject(); @@ -16,6 +16,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* CameraPerspectiveKey(const char* str, CameraPerspective& o); + private: CameraPerspective* _pObject; diff --git a/CesiumGltfReader/generated/ImageJsonHandler.cpp b/CesiumGltfReader/generated/ImageJsonHandler.cpp index 67fd1bcff..971e367fa 100644 --- a/CesiumGltfReader/generated/ImageJsonHandler.cpp +++ b/CesiumGltfReader/generated/ImageJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void ImageJsonHandler::reset(IJsonHandler* pParent, Image* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,13 +24,16 @@ void ImageJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->ImageKey(str, *this->_pObject); +} + +IJsonHandler* ImageJsonHandler::ImageKey(const char* str, Image& o) { + using namespace std::string_literals; - if ("uri"s == str) return property("uri", this->_uri, this->_pObject->uri); - if ("mimeType"s == str) return property("mimeType", this->_mimeType, this->_pObject->mimeType); - if ("bufferView"s == str) return property("bufferView", this->_bufferView, this->_pObject->bufferView); + if ("uri"s == str) return property("uri", this->_uri, o.uri); + if ("mimeType"s == str) return property("mimeType", this->_mimeType, o.mimeType); + if ("bufferView"s == str) return property("bufferView", this->_bufferView, o.bufferView); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/ImageJsonHandler.h b/CesiumGltfReader/generated/ImageJsonHandler.h index b8803a4f1..ece963690 100644 --- a/CesiumGltfReader/generated/ImageJsonHandler.h +++ b/CesiumGltfReader/generated/ImageJsonHandler.h @@ -10,7 +10,7 @@ namespace CesiumGltf { struct Image; - class ImageJsonHandler final : public NamedObjectJsonHandler { + class ImageJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Image* pObject); Image* getObject(); @@ -18,6 +18,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* ImageKey(const char* str, Image& o); + private: class MimeTypeJsonHandler : public JsonHandler { public: diff --git a/CesiumGltfReader/generated/MaterialJsonHandler.cpp b/CesiumGltfReader/generated/MaterialJsonHandler.cpp index 30edac81a..4cdad2554 100644 --- a/CesiumGltfReader/generated/MaterialJsonHandler.cpp +++ b/CesiumGltfReader/generated/MaterialJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void MaterialJsonHandler::reset(IJsonHandler* pParent, Material* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,18 +24,21 @@ void MaterialJsonHandler::reportWarning(const std::string& warning, std::vector< } IJsonHandler* MaterialJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->MaterialKey(str, *this->_pObject); +} + +IJsonHandler* MaterialJsonHandler::MaterialKey(const char* str, Material& o) { + using namespace std::string_literals; - if ("pbrMetallicRoughness"s == str) return property("pbrMetallicRoughness", this->_pbrMetallicRoughness, this->_pObject->pbrMetallicRoughness); - if ("normalTexture"s == str) return property("normalTexture", this->_normalTexture, this->_pObject->normalTexture); - if ("occlusionTexture"s == str) return property("occlusionTexture", this->_occlusionTexture, this->_pObject->occlusionTexture); - if ("emissiveTexture"s == str) return property("emissiveTexture", this->_emissiveTexture, this->_pObject->emissiveTexture); - if ("emissiveFactor"s == str) return property("emissiveFactor", this->_emissiveFactor, this->_pObject->emissiveFactor); - if ("alphaMode"s == str) return property("alphaMode", this->_alphaMode, this->_pObject->alphaMode); - if ("alphaCutoff"s == str) return property("alphaCutoff", this->_alphaCutoff, this->_pObject->alphaCutoff); - if ("doubleSided"s == str) return property("doubleSided", this->_doubleSided, this->_pObject->doubleSided); + if ("pbrMetallicRoughness"s == str) return property("pbrMetallicRoughness", this->_pbrMetallicRoughness, o.pbrMetallicRoughness); + if ("normalTexture"s == str) return property("normalTexture", this->_normalTexture, o.normalTexture); + if ("occlusionTexture"s == str) return property("occlusionTexture", this->_occlusionTexture, o.occlusionTexture); + if ("emissiveTexture"s == str) return property("emissiveTexture", this->_emissiveTexture, o.emissiveTexture); + if ("emissiveFactor"s == str) return property("emissiveFactor", this->_emissiveFactor, o.emissiveFactor); + if ("alphaMode"s == str) return property("alphaMode", this->_alphaMode, o.alphaMode); + if ("alphaCutoff"s == str) return property("alphaCutoff", this->_alphaCutoff, o.alphaCutoff); + if ("doubleSided"s == str) return property("doubleSided", this->_doubleSided, o.doubleSided); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/MaterialJsonHandler.h b/CesiumGltfReader/generated/MaterialJsonHandler.h index 2525d7a49..265d9ac48 100644 --- a/CesiumGltfReader/generated/MaterialJsonHandler.h +++ b/CesiumGltfReader/generated/MaterialJsonHandler.h @@ -15,7 +15,7 @@ namespace CesiumGltf { struct Material; - class MaterialJsonHandler final : public NamedObjectJsonHandler { + class MaterialJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Material* pObject); Material* getObject(); @@ -23,6 +23,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* MaterialKey(const char* str, Material& o); + private: class AlphaModeJsonHandler : public JsonHandler { public: diff --git a/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp index e533e4b67..730f35b45 100644 --- a/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp +++ b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void MaterialNormalTextureInfoJsonHandler::reset(IJsonHandler* pParent, MaterialNormalTextureInfo* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + TextureInfoJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,11 +24,14 @@ void MaterialNormalTextureInfoJsonHandler::reportWarning(const std::string& warn } IJsonHandler* MaterialNormalTextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->MaterialNormalTextureInfoKey(str, *this->_pObject); +} + +IJsonHandler* MaterialNormalTextureInfoJsonHandler::MaterialNormalTextureInfoKey(const char* str, MaterialNormalTextureInfo& o) { + using namespace std::string_literals; - if ("scale"s == str) return property("scale", this->_scale, this->_pObject->scale); + if ("scale"s == str) return property("scale", this->_scale, o.scale); - return this->ExtensibleObjectKey(str, *this->_pObject); + return this->TextureInfoKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.h b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.h index 718acd19d..a6ba3d3a6 100644 --- a/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.h +++ b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.h @@ -3,12 +3,12 @@ #pragma once #include "DoubleJsonHandler.h" -#include "ExtensibleObjectJsonHandler.h" +#include "TextureInfoJsonHandler.h" namespace CesiumGltf { struct MaterialNormalTextureInfo; - class MaterialNormalTextureInfoJsonHandler final : public ExtensibleObjectJsonHandler { + class MaterialNormalTextureInfoJsonHandler : public TextureInfoJsonHandler { public: void reset(IJsonHandler* pHandler, MaterialNormalTextureInfo* pObject); MaterialNormalTextureInfo* getObject(); @@ -16,6 +16,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* MaterialNormalTextureInfoKey(const char* str, MaterialNormalTextureInfo& o); + private: MaterialNormalTextureInfo* _pObject; diff --git a/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp index f8b986f15..e6d4334d6 100644 --- a/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp +++ b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void MaterialOcclusionTextureInfoJsonHandler::reset(IJsonHandler* pParent, MaterialOcclusionTextureInfo* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + TextureInfoJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,11 +24,14 @@ void MaterialOcclusionTextureInfoJsonHandler::reportWarning(const std::string& w } IJsonHandler* MaterialOcclusionTextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->MaterialOcclusionTextureInfoKey(str, *this->_pObject); +} + +IJsonHandler* MaterialOcclusionTextureInfoJsonHandler::MaterialOcclusionTextureInfoKey(const char* str, MaterialOcclusionTextureInfo& o) { + using namespace std::string_literals; - if ("strength"s == str) return property("strength", this->_strength, this->_pObject->strength); + if ("strength"s == str) return property("strength", this->_strength, o.strength); - return this->ExtensibleObjectKey(str, *this->_pObject); + return this->TextureInfoKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.h b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.h index ddb42adce..a0d812d6a 100644 --- a/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.h +++ b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.h @@ -3,12 +3,12 @@ #pragma once #include "DoubleJsonHandler.h" -#include "ExtensibleObjectJsonHandler.h" +#include "TextureInfoJsonHandler.h" namespace CesiumGltf { struct MaterialOcclusionTextureInfo; - class MaterialOcclusionTextureInfoJsonHandler final : public ExtensibleObjectJsonHandler { + class MaterialOcclusionTextureInfoJsonHandler : public TextureInfoJsonHandler { public: void reset(IJsonHandler* pHandler, MaterialOcclusionTextureInfo* pObject); MaterialOcclusionTextureInfo* getObject(); @@ -16,6 +16,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* MaterialOcclusionTextureInfoKey(const char* str, MaterialOcclusionTextureInfo& o); + private: MaterialOcclusionTextureInfo* _pObject; diff --git a/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp index 75f2200a5..05587cbcd 100644 --- a/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp +++ b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void MaterialPBRMetallicRoughnessJsonHandler::reset(IJsonHandler* pParent, MaterialPBRMetallicRoughness* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,15 +24,18 @@ void MaterialPBRMetallicRoughnessJsonHandler::reportWarning(const std::string& w } IJsonHandler* MaterialPBRMetallicRoughnessJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->MaterialPBRMetallicRoughnessKey(str, *this->_pObject); +} + +IJsonHandler* MaterialPBRMetallicRoughnessJsonHandler::MaterialPBRMetallicRoughnessKey(const char* str, MaterialPBRMetallicRoughness& o) { + using namespace std::string_literals; - if ("baseColorFactor"s == str) return property("baseColorFactor", this->_baseColorFactor, this->_pObject->baseColorFactor); - if ("baseColorTexture"s == str) return property("baseColorTexture", this->_baseColorTexture, this->_pObject->baseColorTexture); - if ("metallicFactor"s == str) return property("metallicFactor", this->_metallicFactor, this->_pObject->metallicFactor); - if ("roughnessFactor"s == str) return property("roughnessFactor", this->_roughnessFactor, this->_pObject->roughnessFactor); - if ("metallicRoughnessTexture"s == str) return property("metallicRoughnessTexture", this->_metallicRoughnessTexture, this->_pObject->metallicRoughnessTexture); + if ("baseColorFactor"s == str) return property("baseColorFactor", this->_baseColorFactor, o.baseColorFactor); + if ("baseColorTexture"s == str) return property("baseColorTexture", this->_baseColorTexture, o.baseColorTexture); + if ("metallicFactor"s == str) return property("metallicFactor", this->_metallicFactor, o.metallicFactor); + if ("roughnessFactor"s == str) return property("roughnessFactor", this->_roughnessFactor, o.roughnessFactor); + if ("metallicRoughnessTexture"s == str) return property("metallicRoughnessTexture", this->_metallicRoughnessTexture, o.metallicRoughnessTexture); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.h b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.h index f6c99d28c..39e8a8272 100644 --- a/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.h +++ b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.h @@ -10,7 +10,7 @@ namespace CesiumGltf { struct MaterialPBRMetallicRoughness; - class MaterialPBRMetallicRoughnessJsonHandler final : public ExtensibleObjectJsonHandler { + class MaterialPBRMetallicRoughnessJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, MaterialPBRMetallicRoughness* pObject); MaterialPBRMetallicRoughness* getObject(); @@ -18,6 +18,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* MaterialPBRMetallicRoughnessKey(const char* str, MaterialPBRMetallicRoughness& o); + private: MaterialPBRMetallicRoughness* _pObject; diff --git a/CesiumGltfReader/generated/MeshJsonHandler.cpp b/CesiumGltfReader/generated/MeshJsonHandler.cpp index f5a8537d9..6413019a9 100644 --- a/CesiumGltfReader/generated/MeshJsonHandler.cpp +++ b/CesiumGltfReader/generated/MeshJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void MeshJsonHandler::reset(IJsonHandler* pParent, Mesh* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,12 +24,15 @@ void MeshJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->MeshKey(str, *this->_pObject); +} + +IJsonHandler* MeshJsonHandler::MeshKey(const char* str, Mesh& o) { + using namespace std::string_literals; - if ("primitives"s == str) return property("primitives", this->_primitives, this->_pObject->primitives); - if ("weights"s == str) return property("weights", this->_weights, this->_pObject->weights); + if ("primitives"s == str) return property("primitives", this->_primitives, o.primitives); + if ("weights"s == str) return property("weights", this->_weights, o.weights); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/MeshJsonHandler.h b/CesiumGltfReader/generated/MeshJsonHandler.h index d517aa478..cb9e7814c 100644 --- a/CesiumGltfReader/generated/MeshJsonHandler.h +++ b/CesiumGltfReader/generated/MeshJsonHandler.h @@ -10,7 +10,7 @@ namespace CesiumGltf { struct Mesh; - class MeshJsonHandler final : public NamedObjectJsonHandler { + class MeshJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Mesh* pObject); Mesh* getObject(); @@ -18,6 +18,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* MeshKey(const char* str, Mesh& o); + private: Mesh* _pObject; diff --git a/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp index f902dfb0d..0512d67b7 100644 --- a/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp +++ b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void MeshPrimitiveJsonHandler::reset(IJsonHandler* pParent, MeshPrimitive* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,15 +24,18 @@ void MeshPrimitiveJsonHandler::reportWarning(const std::string& warning, std::ve } IJsonHandler* MeshPrimitiveJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->MeshPrimitiveKey(str, *this->_pObject); +} + +IJsonHandler* MeshPrimitiveJsonHandler::MeshPrimitiveKey(const char* str, MeshPrimitive& o) { + using namespace std::string_literals; - if ("attributes"s == str) return property("attributes", this->_attributes, this->_pObject->attributes); - if ("indices"s == str) return property("indices", this->_indices, this->_pObject->indices); - if ("material"s == str) return property("material", this->_material, this->_pObject->material); - if ("mode"s == str) return property("mode", this->_mode, this->_pObject->mode); - if ("targets"s == str) return property("targets", this->_targets, this->_pObject->targets); + if ("attributes"s == str) return property("attributes", this->_attributes, o.attributes); + if ("indices"s == str) return property("indices", this->_indices, o.indices); + if ("material"s == str) return property("material", this->_material, o.material); + if ("mode"s == str) return property("mode", this->_mode, o.mode); + if ("targets"s == str) return property("targets", this->_targets, o.targets); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h index 8a6acaeba..8503e032c 100644 --- a/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h +++ b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h @@ -11,7 +11,7 @@ namespace CesiumGltf { struct MeshPrimitive; - class MeshPrimitiveJsonHandler final : public ExtensibleObjectJsonHandler { + class MeshPrimitiveJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, MeshPrimitive* pObject); MeshPrimitive* getObject(); @@ -19,6 +19,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* MeshPrimitiveKey(const char* str, MeshPrimitive& o); + private: MeshPrimitive* _pObject; diff --git a/CesiumGltfReader/generated/ModelJsonHandler.cpp b/CesiumGltfReader/generated/ModelJsonHandler.cpp index 35909a4b1..5625afd53 100644 --- a/CesiumGltfReader/generated/ModelJsonHandler.cpp +++ b/CesiumGltfReader/generated/ModelJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void ModelJsonHandler::reset(IJsonHandler* pParent, Model* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,27 +24,30 @@ void ModelJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->ModelKey(str, *this->_pObject); +} + +IJsonHandler* ModelJsonHandler::ModelKey(const char* str, Model& o) { + using namespace std::string_literals; - if ("extensionsUsed"s == str) return property("extensionsUsed", this->_extensionsUsed, this->_pObject->extensionsUsed); - if ("extensionsRequired"s == str) return property("extensionsRequired", this->_extensionsRequired, this->_pObject->extensionsRequired); - if ("accessors"s == str) return property("accessors", this->_accessors, this->_pObject->accessors); - if ("animations"s == str) return property("animations", this->_animations, this->_pObject->animations); - if ("asset"s == str) return property("asset", this->_asset, this->_pObject->asset); - if ("buffers"s == str) return property("buffers", this->_buffers, this->_pObject->buffers); - if ("bufferViews"s == str) return property("bufferViews", this->_bufferViews, this->_pObject->bufferViews); - if ("cameras"s == str) return property("cameras", this->_cameras, this->_pObject->cameras); - if ("images"s == str) return property("images", this->_images, this->_pObject->images); - if ("materials"s == str) return property("materials", this->_materials, this->_pObject->materials); - if ("meshes"s == str) return property("meshes", this->_meshes, this->_pObject->meshes); - if ("nodes"s == str) return property("nodes", this->_nodes, this->_pObject->nodes); - if ("samplers"s == str) return property("samplers", this->_samplers, this->_pObject->samplers); - if ("scene"s == str) return property("scene", this->_scene, this->_pObject->scene); - if ("scenes"s == str) return property("scenes", this->_scenes, this->_pObject->scenes); - if ("skins"s == str) return property("skins", this->_skins, this->_pObject->skins); - if ("textures"s == str) return property("textures", this->_textures, this->_pObject->textures); + if ("extensionsUsed"s == str) return property("extensionsUsed", this->_extensionsUsed, o.extensionsUsed); + if ("extensionsRequired"s == str) return property("extensionsRequired", this->_extensionsRequired, o.extensionsRequired); + if ("accessors"s == str) return property("accessors", this->_accessors, o.accessors); + if ("animations"s == str) return property("animations", this->_animations, o.animations); + if ("asset"s == str) return property("asset", this->_asset, o.asset); + if ("buffers"s == str) return property("buffers", this->_buffers, o.buffers); + if ("bufferViews"s == str) return property("bufferViews", this->_bufferViews, o.bufferViews); + if ("cameras"s == str) return property("cameras", this->_cameras, o.cameras); + if ("images"s == str) return property("images", this->_images, o.images); + if ("materials"s == str) return property("materials", this->_materials, o.materials); + if ("meshes"s == str) return property("meshes", this->_meshes, o.meshes); + if ("nodes"s == str) return property("nodes", this->_nodes, o.nodes); + if ("samplers"s == str) return property("samplers", this->_samplers, o.samplers); + if ("scene"s == str) return property("scene", this->_scene, o.scene); + if ("scenes"s == str) return property("scenes", this->_scenes, o.scenes); + if ("skins"s == str) return property("skins", this->_skins, o.skins); + if ("textures"s == str) return property("textures", this->_textures, o.textures); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/ModelJsonHandler.h b/CesiumGltfReader/generated/ModelJsonHandler.h index fe3e3c6ec..a885d732b 100644 --- a/CesiumGltfReader/generated/ModelJsonHandler.h +++ b/CesiumGltfReader/generated/ModelJsonHandler.h @@ -24,7 +24,7 @@ namespace CesiumGltf { struct Model; - class ModelJsonHandler final : public ExtensibleObjectJsonHandler { + class ModelJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Model* pObject); Model* getObject(); @@ -32,6 +32,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* ModelKey(const char* str, Model& o); + private: Model* _pObject; diff --git a/CesiumGltfReader/generated/NodeJsonHandler.cpp b/CesiumGltfReader/generated/NodeJsonHandler.cpp index 3d730d707..337f7099c 100644 --- a/CesiumGltfReader/generated/NodeJsonHandler.cpp +++ b/CesiumGltfReader/generated/NodeJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void NodeJsonHandler::reset(IJsonHandler* pParent, Node* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,19 +24,22 @@ void NodeJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->NodeKey(str, *this->_pObject); +} + +IJsonHandler* NodeJsonHandler::NodeKey(const char* str, Node& o) { + using namespace std::string_literals; - if ("camera"s == str) return property("camera", this->_camera, this->_pObject->camera); - if ("children"s == str) return property("children", this->_children, this->_pObject->children); - if ("skin"s == str) return property("skin", this->_skin, this->_pObject->skin); - if ("matrix"s == str) return property("matrix", this->_matrix, this->_pObject->matrix); - if ("mesh"s == str) return property("mesh", this->_mesh, this->_pObject->mesh); - if ("rotation"s == str) return property("rotation", this->_rotation, this->_pObject->rotation); - if ("scale"s == str) return property("scale", this->_scale, this->_pObject->scale); - if ("translation"s == str) return property("translation", this->_translation, this->_pObject->translation); - if ("weights"s == str) return property("weights", this->_weights, this->_pObject->weights); + if ("camera"s == str) return property("camera", this->_camera, o.camera); + if ("children"s == str) return property("children", this->_children, o.children); + if ("skin"s == str) return property("skin", this->_skin, o.skin); + if ("matrix"s == str) return property("matrix", this->_matrix, o.matrix); + if ("mesh"s == str) return property("mesh", this->_mesh, o.mesh); + if ("rotation"s == str) return property("rotation", this->_rotation, o.rotation); + if ("scale"s == str) return property("scale", this->_scale, o.scale); + if ("translation"s == str) return property("translation", this->_translation, o.translation); + if ("weights"s == str) return property("weights", this->_weights, o.weights); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/NodeJsonHandler.h b/CesiumGltfReader/generated/NodeJsonHandler.h index 57a2ff4c5..1515b89e9 100644 --- a/CesiumGltfReader/generated/NodeJsonHandler.h +++ b/CesiumGltfReader/generated/NodeJsonHandler.h @@ -10,7 +10,7 @@ namespace CesiumGltf { struct Node; - class NodeJsonHandler final : public NamedObjectJsonHandler { + class NodeJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Node* pObject); Node* getObject(); @@ -18,6 +18,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* NodeKey(const char* str, Node& o); + private: Node* _pObject; diff --git a/CesiumGltfReader/generated/SamplerJsonHandler.cpp b/CesiumGltfReader/generated/SamplerJsonHandler.cpp index e6f88bd02..e226228c2 100644 --- a/CesiumGltfReader/generated/SamplerJsonHandler.cpp +++ b/CesiumGltfReader/generated/SamplerJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void SamplerJsonHandler::reset(IJsonHandler* pParent, Sampler* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,14 +24,17 @@ void SamplerJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->SamplerKey(str, *this->_pObject); +} + +IJsonHandler* SamplerJsonHandler::SamplerKey(const char* str, Sampler& o) { + using namespace std::string_literals; - if ("magFilter"s == str) return property("magFilter", this->_magFilter, this->_pObject->magFilter); - if ("minFilter"s == str) return property("minFilter", this->_minFilter, this->_pObject->minFilter); - if ("wrapS"s == str) return property("wrapS", this->_wrapS, this->_pObject->wrapS); - if ("wrapT"s == str) return property("wrapT", this->_wrapT, this->_pObject->wrapT); + if ("magFilter"s == str) return property("magFilter", this->_magFilter, o.magFilter); + if ("minFilter"s == str) return property("minFilter", this->_minFilter, o.minFilter); + if ("wrapS"s == str) return property("wrapS", this->_wrapS, o.wrapS); + if ("wrapT"s == str) return property("wrapT", this->_wrapT, o.wrapT); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/SamplerJsonHandler.h b/CesiumGltfReader/generated/SamplerJsonHandler.h index 5af8fa942..db2981232 100644 --- a/CesiumGltfReader/generated/SamplerJsonHandler.h +++ b/CesiumGltfReader/generated/SamplerJsonHandler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { struct Sampler; - class SamplerJsonHandler final : public NamedObjectJsonHandler { + class SamplerJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Sampler* pObject); Sampler* getObject(); @@ -17,6 +17,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* SamplerKey(const char* str, Sampler& o); + private: Sampler* _pObject; diff --git a/CesiumGltfReader/generated/SceneJsonHandler.cpp b/CesiumGltfReader/generated/SceneJsonHandler.cpp index 8fe525d5d..92500c230 100644 --- a/CesiumGltfReader/generated/SceneJsonHandler.cpp +++ b/CesiumGltfReader/generated/SceneJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void SceneJsonHandler::reset(IJsonHandler* pParent, Scene* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,11 +24,14 @@ void SceneJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->SceneKey(str, *this->_pObject); +} + +IJsonHandler* SceneJsonHandler::SceneKey(const char* str, Scene& o) { + using namespace std::string_literals; - if ("nodes"s == str) return property("nodes", this->_nodes, this->_pObject->nodes); + if ("nodes"s == str) return property("nodes", this->_nodes, o.nodes); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/SceneJsonHandler.h b/CesiumGltfReader/generated/SceneJsonHandler.h index c6b5514dc..8c603b808 100644 --- a/CesiumGltfReader/generated/SceneJsonHandler.h +++ b/CesiumGltfReader/generated/SceneJsonHandler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { struct Scene; - class SceneJsonHandler final : public NamedObjectJsonHandler { + class SceneJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Scene* pObject); Scene* getObject(); @@ -17,6 +17,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* SceneKey(const char* str, Scene& o); + private: Scene* _pObject; diff --git a/CesiumGltfReader/generated/SkinJsonHandler.cpp b/CesiumGltfReader/generated/SkinJsonHandler.cpp index 9c4a69606..ad6bf1ef4 100644 --- a/CesiumGltfReader/generated/SkinJsonHandler.cpp +++ b/CesiumGltfReader/generated/SkinJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void SkinJsonHandler::reset(IJsonHandler* pParent, Skin* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,13 +24,16 @@ void SkinJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->SkinKey(str, *this->_pObject); +} + +IJsonHandler* SkinJsonHandler::SkinKey(const char* str, Skin& o) { + using namespace std::string_literals; - if ("inverseBindMatrices"s == str) return property("inverseBindMatrices", this->_inverseBindMatrices, this->_pObject->inverseBindMatrices); - if ("skeleton"s == str) return property("skeleton", this->_skeleton, this->_pObject->skeleton); - if ("joints"s == str) return property("joints", this->_joints, this->_pObject->joints); + if ("inverseBindMatrices"s == str) return property("inverseBindMatrices", this->_inverseBindMatrices, o.inverseBindMatrices); + if ("skeleton"s == str) return property("skeleton", this->_skeleton, o.skeleton); + if ("joints"s == str) return property("joints", this->_joints, o.joints); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/SkinJsonHandler.h b/CesiumGltfReader/generated/SkinJsonHandler.h index 1234d131c..89db00122 100644 --- a/CesiumGltfReader/generated/SkinJsonHandler.h +++ b/CesiumGltfReader/generated/SkinJsonHandler.h @@ -9,7 +9,7 @@ namespace CesiumGltf { struct Skin; - class SkinJsonHandler final : public NamedObjectJsonHandler { + class SkinJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Skin* pObject); Skin* getObject(); @@ -17,6 +17,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* SkinKey(const char* str, Skin& o); + private: Skin* _pObject; diff --git a/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp b/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp index 7637d5385..789479327 100644 --- a/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp +++ b/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void TextureInfoJsonHandler::reset(IJsonHandler* pParent, TextureInfo* pObject) { - ExtensibleObjectJsonHandler::reset(pParent); + ExtensibleObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,12 +24,15 @@ void TextureInfoJsonHandler::reportWarning(const std::string& warning, std::vect } IJsonHandler* TextureInfoJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->TextureInfoKey(str, *this->_pObject); +} + +IJsonHandler* TextureInfoJsonHandler::TextureInfoKey(const char* str, TextureInfo& o) { + using namespace std::string_literals; - if ("index"s == str) return property("index", this->_index, this->_pObject->index); - if ("texCoord"s == str) return property("texCoord", this->_texCoord, this->_pObject->texCoord); + if ("index"s == str) return property("index", this->_index, o.index); + if ("texCoord"s == str) return property("texCoord", this->_texCoord, o.texCoord); return this->ExtensibleObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/TextureInfoJsonHandler.h b/CesiumGltfReader/generated/TextureInfoJsonHandler.h index 7c1e3fde8..c09a6861a 100644 --- a/CesiumGltfReader/generated/TextureInfoJsonHandler.h +++ b/CesiumGltfReader/generated/TextureInfoJsonHandler.h @@ -8,7 +8,7 @@ namespace CesiumGltf { struct TextureInfo; - class TextureInfoJsonHandler final : public ExtensibleObjectJsonHandler { + class TextureInfoJsonHandler : public ExtensibleObjectJsonHandler { public: void reset(IJsonHandler* pHandler, TextureInfo* pObject); TextureInfo* getObject(); @@ -16,6 +16,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* TextureInfoKey(const char* str, TextureInfo& o); + private: TextureInfo* _pObject; diff --git a/CesiumGltfReader/generated/TextureJsonHandler.cpp b/CesiumGltfReader/generated/TextureJsonHandler.cpp index c1b17edc2..5484f3310 100644 --- a/CesiumGltfReader/generated/TextureJsonHandler.cpp +++ b/CesiumGltfReader/generated/TextureJsonHandler.cpp @@ -8,7 +8,7 @@ using namespace CesiumGltf; void TextureJsonHandler::reset(IJsonHandler* pParent, Texture* pObject) { - NamedObjectJsonHandler::reset(pParent); + NamedObjectJsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -24,12 +24,15 @@ void TextureJsonHandler::reportWarning(const std::string& warning, std::vector_pObject); + return this->TextureKey(str, *this->_pObject); +} + +IJsonHandler* TextureJsonHandler::TextureKey(const char* str, Texture& o) { + using namespace std::string_literals; - if ("sampler"s == str) return property("sampler", this->_sampler, this->_pObject->sampler); - if ("source"s == str) return property("source", this->_source, this->_pObject->source); + if ("sampler"s == str) return property("sampler", this->_sampler, o.sampler); + if ("source"s == str) return property("source", this->_source, o.source); return this->NamedObjectKey(str, *this->_pObject); } diff --git a/CesiumGltfReader/generated/TextureJsonHandler.h b/CesiumGltfReader/generated/TextureJsonHandler.h index 14f85eca3..248796942 100644 --- a/CesiumGltfReader/generated/TextureJsonHandler.h +++ b/CesiumGltfReader/generated/TextureJsonHandler.h @@ -8,7 +8,7 @@ namespace CesiumGltf { struct Texture; - class TextureJsonHandler final : public NamedObjectJsonHandler { + class TextureJsonHandler : public NamedObjectJsonHandler { public: void reset(IJsonHandler* pHandler, Texture* pObject); Texture* getObject(); @@ -16,6 +16,9 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* TextureKey(const char* str, Texture& o); + private: Texture* _pObject; diff --git a/CesiumGltfReader/src/ArrayJsonHandler.h b/CesiumGltfReader/src/ArrayJsonHandler.h index e627c8601..b3e078494 100644 --- a/CesiumGltfReader/src/ArrayJsonHandler.h +++ b/CesiumGltfReader/src/ArrayJsonHandler.h @@ -2,6 +2,8 @@ #include "JsonHandler.h" #include "DoubleJsonHandler.h" +#include "IntegerJsonHandler.h" +#include "StringJsonHandler.h" #include #include @@ -128,4 +130,108 @@ namespace CesiumGltf { std::vector* _pArray = nullptr; bool _arrayIsOpen = false; }; + + template + class ArrayJsonHandler> : public JsonHandler { + public: + void reset(IJsonHandler* pParent, std::vector* pArray) { + JsonHandler::reset(pParent); + this->_pArray = pArray; + this->_arrayIsOpen = false; + } + + virtual IJsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return nullptr; + } + + this->_arrayIsOpen = true; + return this; + } + + virtual IJsonHandler* EndArray(size_t) override { + return this->parent(); + } + + virtual IJsonHandler* Int(int i) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(static_cast(i)); + return this; + } + + virtual IJsonHandler* Uint(unsigned i) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(static_cast(i)); + return this; + } + + virtual IJsonHandler* Int64(int64_t i) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(static_cast(i)); + return this; + } + + virtual IJsonHandler* Uint64(uint64_t i) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(static_cast(i)); + return this; + } + + private: + std::vector* _pArray = nullptr; + bool _arrayIsOpen = false; + }; + + template <> + class ArrayJsonHandler : public JsonHandler { + public: + void reset(IJsonHandler* pParent, std::vector* pArray) { + JsonHandler::reset(pParent); + this->_pArray = pArray; + this->_arrayIsOpen = false; + } + + virtual IJsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return nullptr; + } + + this->_arrayIsOpen = true; + return this; + } + + virtual IJsonHandler* EndArray(size_t) override { + return this->parent(); + } + + virtual IJsonHandler* String(const char* str, size_t length, bool /*copy*/) override { + if (!this->_arrayIsOpen) { + return nullptr; + } + + assert(this->_pArray); + this->_pArray->emplace_back(std::string(str, length)); + return this; + } + + private: + std::vector* _pArray = nullptr; + bool _arrayIsOpen = false; + }; } diff --git a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp index f4e24d3bc..67f702f85 100644 --- a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp +++ b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp @@ -2,6 +2,10 @@ using namespace CesiumGltf; +void ExtensibleObjectJsonHandler::reset(IJsonHandler* pParent, ExtensibleObject* /*pObject*/) { + ObjectJsonHandler::reset(pParent); +} + IJsonHandler* ExtensibleObjectJsonHandler::ExtensibleObjectKey(const char* /*str*/, ExtensibleObject& /*o*/) { // TODO: handle extensions and extras. return this->ignoreAndContinue(); diff --git a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h index 4e2967ad7..e1de12f62 100644 --- a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h +++ b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h @@ -7,6 +7,7 @@ namespace CesiumGltf { class ExtensibleObjectJsonHandler : public ObjectJsonHandler { protected: + void reset(IJsonHandler* pParent, ExtensibleObject* pObject); IJsonHandler* ExtensibleObjectKey(const char* str, ExtensibleObject& o); }; } diff --git a/CesiumGltfReader/src/NamedObjectJsonHandler.cpp b/CesiumGltfReader/src/NamedObjectJsonHandler.cpp index 06fb2116c..f18a1d1c8 100644 --- a/CesiumGltfReader/src/NamedObjectJsonHandler.cpp +++ b/CesiumGltfReader/src/NamedObjectJsonHandler.cpp @@ -4,6 +4,10 @@ using namespace CesiumGltf; +void NamedObjectJsonHandler::reset(IJsonHandler* pParent, NamedObject* pObject) { + ExtensibleObjectJsonHandler::reset(pParent, pObject); +} + IJsonHandler* NamedObjectJsonHandler::NamedObjectKey(const char* str, NamedObject& o) { using namespace std::string_literals; if ("name"s == str) return property("name", this->_name, o.name); diff --git a/CesiumGltfReader/src/NamedObjectJsonHandler.h b/CesiumGltfReader/src/NamedObjectJsonHandler.h index 3f42cb42e..fbb89eb7d 100644 --- a/CesiumGltfReader/src/NamedObjectJsonHandler.h +++ b/CesiumGltfReader/src/NamedObjectJsonHandler.h @@ -8,6 +8,7 @@ namespace CesiumGltf { class NamedObjectJsonHandler : public ExtensibleObjectJsonHandler { protected: + void reset(IJsonHandler* pParent, NamedObject* pObject); IJsonHandler* NamedObjectKey(const char* str, NamedObject& o); private: diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 0acd8ef46..680f005be 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -222,7 +222,7 @@ namespace { if (jsonEnd + sizeof(ChunkHeader) <= data.size()) { const ChunkHeader* pBinaryChunkHeader = reinterpret_cast(glbData.data() + jsonEnd); - if (pJsonChunkHeader->chunkType != 0x004E4942) { + if (pBinaryChunkHeader->chunkType != 0x004E4942) { return { std::nullopt, "GLB binary chunk does not have the expected chunkType.", diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index ef23a26e0..8e54ea391 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -13,9 +13,10 @@ function generate(options, schema) { console.log(`Generating ${name}`); - let base = "Extensible"; - if (schema.allOf && schema.allOf.length > 0 && schema.allOf[0].$ref && schema.allOf[0].$ref === "glTFChildOfRootProperty.schema.json") { - base = "Named"; + let base = "ExtensibleObject"; + if (schema.allOf && schema.allOf.length > 0 && schema.allOf[0].$ref) { + const baseSchema = schemaCache.load(schema.allOf[0].$ref); + base = getNameFromSchema(nameMapping, baseSchema); } const properties = Object.keys(schema.properties) @@ -29,7 +30,7 @@ function generate(options, schema) { ); const headers = lodash.uniq( - [`"CesiumGltf/${base}Object.h"`, ...lodash.flatten(properties.map((property) => property.headers))] + [`"CesiumGltf/${base}.h"`, ...lodash.flatten(properties.map((property) => property.headers))] ); if (cesiumProperties[name]) { @@ -49,7 +50,7 @@ function generate(options, schema) { /** * @brief ${schema.description} */ - struct ${name} final : public ${base}Object { + struct ${name} : public ${base} { ${indent(localTypes.join("\n\n"), 16)} ${indent( @@ -70,7 +71,7 @@ function generate(options, schema) { fs.writeFileSync(headerOutputPath, unindent(header), "utf-8"); const readerHeaders = lodash.uniq( - [`"${base}ObjectJsonHandler.h"`, ...lodash.flatten(properties.map((property) => property.readerHeaders))] + [`"${base}JsonHandler.h"`, ...lodash.flatten(properties.map((property) => property.readerHeaders))] ); readerHeaders.sort(); @@ -88,7 +89,7 @@ function generate(options, schema) { namespace CesiumGltf { struct ${name}; - class ${name}JsonHandler final : public ${base}ObjectJsonHandler { + class ${name}JsonHandler : public ${base}JsonHandler { public: void reset(IJsonHandler* pHandler, ${name}* pObject); ${name}* getObject(); @@ -96,6 +97,9 @@ function generate(options, schema) { virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + protected: + IJsonHandler* ${name}Key(const char* str, ${name}& o); + private: ${indent(readerLocalTypes.join("\n\n"), 12)} @@ -130,7 +134,7 @@ function generate(options, schema) { using namespace CesiumGltf; void ${name}JsonHandler::reset(IJsonHandler* pParent, ${name}* pObject) { - ${base}ObjectJsonHandler::reset(pParent); + ${base}JsonHandler::reset(pParent, pObject); this->_pObject = pObject; } @@ -146,9 +150,12 @@ function generate(options, schema) { } IJsonHandler* ${name}JsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { - using namespace std::string_literals; - assert(this->_pObject); + return this->${name}Key(str, *this->_pObject); + } + + IJsonHandler* ${name}JsonHandler::${name}Key(const char* str, ${name}& o) { + using namespace std::string_literals; ${indent( properties @@ -157,7 +164,7 @@ function generate(options, schema) { 10 )} - return this->${base}ObjectKey(str, *this->_pObject); + return this->${base}Key(str, *this->_pObject); } ${indent(readerLocalTypesImpl.join("\n\n"), 8)} @@ -191,7 +198,7 @@ function formatReaderProperty(property) { } function formatReaderPropertyImpl(property) { - return `if ("${property.name}"s == str) return property("${property.name}", this->_${property.name}, this->_pObject->${property.name});`; + return `if ("${property.name}"s == str) return property("${property.name}", this->_${property.name}, o.${property.name});`; } function getCesiumProperty(cesiumProperties, name, schema) { diff --git a/tools/generate-gltf-classes/index.js b/tools/generate-gltf-classes/index.js index dacdaae61..c6ec72194 100644 --- a/tools/generate-gltf-classes/index.js +++ b/tools/generate-gltf-classes/index.js @@ -27,7 +27,9 @@ const argv = yargs.options({ const nameMapping = { "glTF": "Model", "glTF Id": "ExtensibleObject", - "glTFRootProperty": "NamedObject" + "glTFRootProperty": "NamedObject", + "glTF Property": "ExtensibleObject", + "glTF Child of Root Property": "NamedObject" }; // Custom `cesium` properties will be added to these objects. From 2ec456e6ac13b87c1e4f7d569c2fc37c84194051 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Fri, 8 Jan 2021 14:21:58 +1100 Subject: [PATCH 27/61] Fix test compiler error. --- Cesium3DTiles/test/TestQuantizedMeshContent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cesium3DTiles/test/TestQuantizedMeshContent.cpp b/Cesium3DTiles/test/TestQuantizedMeshContent.cpp index f6097f54c..b523dd559 100644 --- a/Cesium3DTiles/test/TestQuantizedMeshContent.cpp +++ b/Cesium3DTiles/test/TestQuantizedMeshContent.cpp @@ -655,7 +655,7 @@ TEST_CASE("Test converting quantized mesh to gltf with skirt") { // make sure the gltf is the grid const CesiumGltf::Model& model = *loadResult->model; const CesiumGltf::Mesh& mesh = model.meshes.front(); - const CesiumGltf::Primitive& primitive = mesh.primitives.front(); + const CesiumGltf::MeshPrimitive& primitive = mesh.primitives.front(); // make sure mesh contains grid mesh and skirts at the end GltfAccessor indices(model, static_cast(primitive.indices)); From 7f914afd4dfdeb5ec805b6c65904b6c97b7e49ce Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Fri, 8 Jan 2021 17:47:39 +1100 Subject: [PATCH 28/61] Improve error handling for arrays. --- CesiumGltfReader/src/ArrayJsonHandler.h | 249 ++++++++++++++++++++---- 1 file changed, 207 insertions(+), 42 deletions(-) diff --git a/CesiumGltfReader/src/ArrayJsonHandler.h b/CesiumGltfReader/src/ArrayJsonHandler.h index b3e078494..9580a4073 100644 --- a/CesiumGltfReader/src/ArrayJsonHandler.h +++ b/CesiumGltfReader/src/ArrayJsonHandler.h @@ -17,22 +17,41 @@ namespace CesiumGltf { this->_arrayIsOpen = false; } - virtual IJsonHandler* StartArray() override { - if (this->_arrayIsOpen) { - return nullptr; - } + virtual IJsonHandler* Null() override { + return this->invalid("A null")->Null(); + } - this->_arrayIsOpen = true; - return this; + virtual IJsonHandler* Bool(bool b) override { + return this->invalid("A boolean")->Bool(b); } - virtual IJsonHandler* EndArray(size_t) override { - return this->parent(); + virtual IJsonHandler* Int(int i) override { + return this->invalid("An integer")->Int(i); + } + + virtual IJsonHandler* Uint(unsigned i) override { + return this->invalid("An integer")->Uint(i); + } + + virtual IJsonHandler* Int64(int64_t i) override { + return this->invalid("An integer")->Int64(i); + } + + virtual IJsonHandler* Uint64(uint64_t i) override { + return this->invalid("An integer")->Uint64(i); + } + + virtual IJsonHandler* Double(double d) override { + return this->invalid("A double (floating-point)")->Double(d); + } + + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override { + return this->invalid("A string")->String(str, length, copy); } virtual IJsonHandler* StartObject() override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An object")->StartObject(); } assert(this->_pArray); @@ -41,14 +60,44 @@ namespace CesiumGltf { return this->_objectHandler.StartObject(); } + virtual IJsonHandler* Key(const char* /*str*/, size_t /*length*/, bool /*copy*/) override { + return nullptr; + } + + virtual IJsonHandler* EndObject(size_t /*memberCount*/) override { + return nullptr; + } + + virtual IJsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return this->invalid("An array")->StartArray(); + } + + this->_arrayIsOpen = true; + return this; + } + + virtual IJsonHandler* EndArray(size_t) override { + return this->parent(); + } + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override { - T* pObject = this->_objectHandler.getObject(); - int64_t index = pObject - this->_pArray->data(); - context.push_back(std::string("[") + std::to_string(index) + "]"); + context.push_back(std::string("[") + std::to_string(this->_pArray->size()) + "]"); this->parent()->reportWarning(warning, std::move(context)); } private: + IJsonHandler* invalid(const std::string& type) { + if (this->_arrayIsOpen) { + this->reportWarning(type + " value is not allowed in the object array and has been replaced with a default value."); + this->_pArray->emplace_back(); + return this->ignoreAndContinue(); + } else { + this->reportWarning(type + " is not allowed and has been ignored."); + return this->ignoreAndReturnToParent(); + } + } + std::vector* _pArray = nullptr; bool _arrayIsOpen = false; THandler _objectHandler; @@ -63,22 +112,17 @@ namespace CesiumGltf { this->_arrayIsOpen = false; } - virtual IJsonHandler* StartArray() override { - if (this->_arrayIsOpen) { - return nullptr; - } - - this->_arrayIsOpen = true; - return this; + virtual IJsonHandler* Null() override { + return this->invalid("A null")->Null(); } - virtual IJsonHandler* EndArray(size_t) override { - return this->parent(); + virtual IJsonHandler* Bool(bool b) override { + return this->invalid("A bool")->Bool(b); } virtual IJsonHandler* Int(int i) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An integer")->Int(i); } assert(this->_pArray); @@ -88,7 +132,7 @@ namespace CesiumGltf { virtual IJsonHandler* Uint(unsigned i) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An integer")->Uint(i); } assert(this->_pArray); @@ -98,7 +142,7 @@ namespace CesiumGltf { virtual IJsonHandler* Int64(int64_t i) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An integer")->Int64(i); } assert(this->_pArray); @@ -108,7 +152,7 @@ namespace CesiumGltf { virtual IJsonHandler* Uint64(uint64_t i) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An integer")->Uint64(i); } assert(this->_pArray); @@ -118,7 +162,7 @@ namespace CesiumGltf { virtual IJsonHandler* Double(double d) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An integer")->Double(d); } assert(this->_pArray); @@ -126,7 +170,44 @@ namespace CesiumGltf { return this; } + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override { + return this->invalid("A string")->String(str, length, copy); + } + + virtual IJsonHandler* StartObject() override { + return this->invalid("An object")->StartObject(); + } + + virtual IJsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return this->invalid("An array")->StartArray(); + } + + this->_arrayIsOpen = true; + return this; + } + + virtual IJsonHandler* EndArray(size_t) override { + return this->parent(); + } + + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override { + context.push_back(std::string("[") + std::to_string(this->_pArray->size()) + "]"); + this->parent()->reportWarning(warning, std::move(context)); + } + private: + IJsonHandler* invalid(const std::string& type) { + if (this->_arrayIsOpen) { + this->reportWarning(type + " value is not allowed in the double array and has been replaced with a default value."); + this->_pArray->emplace_back(); + return this->ignoreAndContinue(); + } else { + this->reportWarning(type + " is not allowed and has been ignored."); + return this->ignoreAndReturnToParent(); + } + } + std::vector* _pArray = nullptr; bool _arrayIsOpen = false; }; @@ -140,22 +221,17 @@ namespace CesiumGltf { this->_arrayIsOpen = false; } - virtual IJsonHandler* StartArray() override { - if (this->_arrayIsOpen) { - return nullptr; - } - - this->_arrayIsOpen = true; - return this; + virtual IJsonHandler* Null() override { + return this->invalid("A null")->Null(); } - virtual IJsonHandler* EndArray(size_t) override { - return this->parent(); + virtual IJsonHandler* Bool(bool b) override { + return this->invalid("A null")->Bool(b); } virtual IJsonHandler* Int(int i) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An integer")->Int(i); } assert(this->_pArray); @@ -165,7 +241,7 @@ namespace CesiumGltf { virtual IJsonHandler* Uint(unsigned i) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An integer")->Uint(i); } assert(this->_pArray); @@ -175,7 +251,7 @@ namespace CesiumGltf { virtual IJsonHandler* Int64(int64_t i) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An integer")->Int64(i); } assert(this->_pArray); @@ -185,15 +261,56 @@ namespace CesiumGltf { virtual IJsonHandler* Uint64(uint64_t i) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("An integer")->Uint64(i); } assert(this->_pArray); this->_pArray->emplace_back(static_cast(i)); return this; } + + virtual IJsonHandler* Double(double d) override { + return this->invalid("A double (floating-point)")->Double(d); + } + + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override { + return this->invalid("A string")->String(str, length, copy); + } + + virtual IJsonHandler* StartObject() override { + return this->invalid("An object")->StartObject(); + } + + virtual IJsonHandler* StartArray() override { + if (this->_arrayIsOpen) { + return this->invalid("An array")->StartArray(); + } + + this->_arrayIsOpen = true; + return this; + } + + virtual IJsonHandler* EndArray(size_t) override { + return this->parent(); + } + + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override { + context.push_back(std::string("[") + std::to_string(this->_pArray->size()) + "]"); + this->parent()->reportWarning(warning, std::move(context)); + } private: + IJsonHandler* invalid(const std::string& type) { + if (this->_arrayIsOpen) { + this->reportWarning(type + " value is not allowed in the integer array and has been replaced with a default value."); + this->_pArray->emplace_back(); + return this->ignoreAndContinue(); + } else { + this->reportWarning(type + " is not allowed and has been ignored."); + return this->ignoreAndReturnToParent(); + } + } + std::vector* _pArray = nullptr; bool _arrayIsOpen = false; }; @@ -207,9 +324,41 @@ namespace CesiumGltf { this->_arrayIsOpen = false; } + virtual IJsonHandler* Null() override { + return this->invalid("A null")->Null(); + } + + virtual IJsonHandler* Bool(bool b) override { + return this->invalid("A bool")->Bool(b); + } + + virtual IJsonHandler* Int(int i) override { + return this->invalid("An integer")->Int(i); + } + + virtual IJsonHandler* Uint(unsigned i) override { + return this->invalid("An integer")->Uint(i); + } + + virtual IJsonHandler* Int64(int64_t i) override { + return this->invalid("An integer")->Int64(i); + } + + virtual IJsonHandler* Uint64(uint64_t i) override { + return this->invalid("An integer")->Uint64(i); + } + + virtual IJsonHandler* Double(double d) override { + return this->invalid("A double (floating-point)")->Double(d); + } + + virtual IJsonHandler* StartObject() override { + return this->invalid("An object")->StartObject(); + } + virtual IJsonHandler* StartArray() override { if (this->_arrayIsOpen) { - return nullptr; + return this->invalid("An array")->StartArray(); } this->_arrayIsOpen = true; @@ -220,9 +369,9 @@ namespace CesiumGltf { return this->parent(); } - virtual IJsonHandler* String(const char* str, size_t length, bool /*copy*/) override { + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override { if (!this->_arrayIsOpen) { - return nullptr; + return this->invalid("A string")->String(str, length, copy); } assert(this->_pArray); @@ -230,7 +379,23 @@ namespace CesiumGltf { return this; } + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override { + context.push_back(std::string("[") + std::to_string(this->_pArray->size()) + "]"); + this->parent()->reportWarning(warning, std::move(context)); + } + private: + IJsonHandler* invalid(const std::string& type) { + if (this->_arrayIsOpen) { + this->reportWarning(type + " value is not allowed in the string array and has been replaced with a default value."); + this->_pArray->emplace_back(); + return this->ignoreAndContinue(); + } else { + this->reportWarning(type + " is not allowed and has been ignored."); + return this->ignoreAndReturnToParent(); + } + } + std::vector* _pArray = nullptr; bool _arrayIsOpen = false; }; From 32f0c371eaa180bc1cac9d45c98880facf6080a5 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Fri, 8 Jan 2021 23:10:27 +1100 Subject: [PATCH 29/61] Raster image loading. --- .gitmodules | 3 + .../Cesium3DTiles/IPrepareRendererResources.h | 4 +- .../include/Cesium3DTiles/RasterOverlay.h | 2 + .../include/Cesium3DTiles/RasterOverlayTile.h | 4 +- .../Cesium3DTiles/RasterOverlayTileProvider.h | 9 +++ Cesium3DTiles/src/BingMapsRasterOverlay.cpp | 3 + Cesium3DTiles/src/RasterOverlayTile.cpp | 49 ++++++++++---- .../src/RasterOverlayTileProvider.cpp | 7 +- .../src/TileMapServiceRasterOverlay.cpp | 3 + CesiumGltfReader/CMakeLists.txt | 1 + CesiumGltfReader/include/CesiumGltf/Reader.h | 15 ++++- CesiumGltfReader/src/Reader.cpp | 67 +++++++++++++++++-- extern/stb | 1 + 13 files changed, 142 insertions(+), 26 deletions(-) create mode 160000 extern/stb diff --git a/.gitmodules b/.gitmodules index a3211153c..2cc824113 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,6 @@ [submodule "extern/glTF"] path = extern/glTF url = https://github.com/KhronosGroup/glTF.git +[submodule "extern/stb"] + path = extern/stb + url = https://github.com/nothings/stb.git diff --git a/Cesium3DTiles/include/Cesium3DTiles/IPrepareRendererResources.h b/Cesium3DTiles/include/Cesium3DTiles/IPrepareRendererResources.h index e6f5da93b..669064d33 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/IPrepareRendererResources.h +++ b/Cesium3DTiles/include/Cesium3DTiles/IPrepareRendererResources.h @@ -10,7 +10,7 @@ namespace CesiumGeometry { } namespace CesiumGltf { - struct Image; + struct ImageCesium; struct Model; } @@ -85,7 +85,7 @@ namespace Cesium3DTiles { * @returns Arbitrary data representing the result of the load process. This data is * passed to {@link prepareRasterInMainThread} as the `pLoadThreadResult` parameter. */ - virtual void* prepareRasterInLoadThread(const CesiumGltf::Image& image) = 0; + virtual void* prepareRasterInLoadThread(const CesiumGltf::ImageCesium& image) = 0; /** * @brief Further preprares a raster overlay tile. diff --git a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlay.h b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlay.h index 26b0e1860..a221759a8 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlay.h +++ b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlay.h @@ -82,6 +82,7 @@ namespace Cesium3DTiles { * @param asyncSystem The async system used to request assets and do work in threads. * @param pCreditSystem The {@link CreditSystem} to use when creating a per-TileProvider {@link Credit}. * @param pPrepareRendererResources The interface used to prepare raster images for rendering. + * @param pLogger The logger to which to send messages about the tile provider and tiles. */ void createTileProvider( const CesiumAsync::AsyncSystem& asyncSystem, @@ -99,6 +100,7 @@ namespace Cesium3DTiles { * @param asyncSystem The async system used to request assets and do work in threads. * @param pCreditSystem The {@link CreditSystem} to use when creating a per-TileProvider {@link Credit}. * @param pPrepareRendererResources The interface used to prepare raster images for rendering. + * @param pLogger The logger to which to send messages about the tile provider and tiles. * @param pOwner The overlay that owns this overlay, or nullptr if this overlay is not aggregated. * @param callback The callback that receives the new tile provider when it is ready. */ diff --git a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTile.h b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTile.h index fb81b7c81..25c75304c 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTile.h +++ b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTile.h @@ -127,7 +127,7 @@ namespace Cesium3DTiles { * * @return The image data. */ - const CesiumGltf::Image& getImage() const noexcept { return this->_image; } + const CesiumGltf::ImageCesium& getImage() const noexcept { return this->_image; } /** * @brief Create the renderer resources for the loaded image. @@ -170,7 +170,7 @@ namespace Cesium3DTiles { CesiumGeometry::QuadtreeTileID _tileID; std::vector _tileCredits; std::atomic _state; - CesiumGltf::Image _image; + CesiumGltf::ImageCesium _image; void* _pRendererResources; uint32_t _references; }; diff --git a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTileProvider.h b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTileProvider.h index c56bc3231..b3da38c54 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTileProvider.h +++ b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTileProvider.h @@ -10,6 +10,7 @@ #include "CesiumUtility/IntrusivePointer.h" #include #include +#include namespace Cesium3DTiles { @@ -41,6 +42,7 @@ namespace Cesium3DTiles { * @param asyncSystem The async system used to request assets and do work in threads. * @param credit The {@link Credit} for this tile provider, if it exists. * @param pPrepareRendererResources The interface used to prepare raster images for rendering. + * @param pLogger The logger to which to send messages about the tile provider and tiles. * @param projection The {@link CesiumGeospatial::Projection}. * @param tilingScheme The {@link CesiumGeometry::QuadtreeTilingScheme}. * @param coverageRectangle The {@link CesiumGeometry::Rectangle}. @@ -54,6 +56,7 @@ namespace Cesium3DTiles { const CesiumAsync::AsyncSystem& asyncSystem, std::optional credit, std::shared_ptr pPrepareRendererResources, + std::shared_ptr pLogger, const CesiumGeospatial::Projection& projection, const CesiumGeometry::QuadtreeTilingScheme& tilingScheme, const CesiumGeometry::Rectangle& coverageRectangle, @@ -92,6 +95,11 @@ namespace Cesium3DTiles { */ const std::shared_ptr& getPrepareRendererResources() const noexcept { return this->_pPrepareRendererResources; } + /** + * @brief Gets the logger to which to send messages about the tile provider and tiles. + */ + const std::shared_ptr& getLogger() const noexcept { return this->_pLogger; } + /** * @brief Returns the {@link CesiumGeospatial::Projection} of this instance. */ @@ -231,6 +239,7 @@ namespace Cesium3DTiles { CesiumAsync::AsyncSystem _asyncSystem; std::optional _credit; std::shared_ptr _pPrepareRendererResources; + std::shared_ptr _pLogger; CesiumGeospatial::Projection _projection; CesiumGeometry::QuadtreeTilingScheme _tilingScheme; CesiumGeometry::Rectangle _coverageRectangle; diff --git a/Cesium3DTiles/src/BingMapsRasterOverlay.cpp b/Cesium3DTiles/src/BingMapsRasterOverlay.cpp index 6e56a0ae4..da0fa691d 100644 --- a/Cesium3DTiles/src/BingMapsRasterOverlay.cpp +++ b/Cesium3DTiles/src/BingMapsRasterOverlay.cpp @@ -59,6 +59,7 @@ namespace Cesium3DTiles { Credit bingCredit, const std::vector& perTileCredits, std::shared_ptr pPrepareRendererResources, + std::shared_ptr pLogger, const std::string& baseUrl, const std::string& urlTemplate, const std::vector& subdomains, @@ -73,6 +74,7 @@ namespace Cesium3DTiles { asyncSystem, bingCredit, pPrepareRendererResources, + pLogger, WebMercatorProjection(), QuadtreeTilingScheme( WebMercatorProjection::computeMaximumProjectedRectangle(Ellipsoid::WGS84), @@ -295,6 +297,7 @@ namespace Cesium3DTiles { bingCredit, credits, pPrepareRendererResources, + pLogger, baseUrl, urlTemplate, subdomains, diff --git a/Cesium3DTiles/src/RasterOverlayTile.cpp b/Cesium3DTiles/src/RasterOverlayTile.cpp index cd7b7b0c9..569e3841c 100644 --- a/Cesium3DTiles/src/RasterOverlayTile.cpp +++ b/Cesium3DTiles/src/RasterOverlayTile.cpp @@ -5,6 +5,7 @@ #include "Cesium3DTiles/TilesetExternals.h" #include "CesiumAsync/IAssetResponse.h" #include "CesiumAsync/ITaskProcessor.h" +#include "CesiumGltf/Reader.h" using namespace CesiumAsync; @@ -48,7 +49,7 @@ namespace Cesium3DTiles { {} LoadState state; - CesiumGltf::Image image; + CesiumGltf::ImageCesium image; std::string warnings; std::string errors; void* pRendererResources; @@ -63,7 +64,8 @@ namespace Cesium3DTiles { tileRectangle = pTileProvider->getTilingScheme().tileToRectangle(this->getID()), projection = pTileProvider->getProjection(), cutoutsCollection = overlay.getCutouts(), - pPrepareRendererResources = pTileProvider->getPrepareRendererResources() + pPrepareRendererResources = pTileProvider->getPrepareRendererResources(), + pLogger = pTileProvider->getLogger() ]( std::unique_ptr pRequest ) { @@ -76,22 +78,35 @@ namespace Cesium3DTiles { return LoadResult(LoadState::Failed); } - LoadResult result; - gsl::span data = pResponse->data(); - // bool success = CesiumGltf::LoadImageData(&result.image, 0, &result.errors, &result.warnings, 0, 0, data.data(), static_cast(data.size()), nullptr); - bool success = false; + CesiumGltf::ImageReaderResult loadedImage = CesiumGltf::readImage(data); + + if (!loadedImage.image.has_value()) { + SPDLOG_LOGGER_ERROR(pLogger, "Failed to load image: {}", loadedImage.errors); + + LoadResult result; + result.pRendererResources = nullptr; + result.state = LoadState::Failed; + return result; + } - const int bytesPerPixel = 4; - if (success && result.image.cesium.pixelData.size() >= static_cast(result.image.cesium.width * result.image.cesium.height * bytesPerPixel)) { + if (!loadedImage.warnings.empty()) { + SPDLOG_LOGGER_WARN(pLogger, "Warnings while loading image: {}", loadedImage.warnings); + } + + CesiumGltf::ImageCesium& image = loadedImage.image.value(); + + int32_t bytesPerPixel = image.channels * image.bytesPerChannel; + + if (image.pixelData.size() >= static_cast(image.width * image.height * bytesPerPixel)) { double tileWidth = tileRectangle.computeWidth(); double tileHeight = tileRectangle.computeHeight(); gsl::span cutouts = cutoutsCollection.getCutouts(); - std::vector& imageData = result.image.cesium.pixelData; - int width = result.image.cesium.width; - int height = result.image.cesium.height; + std::vector& imageData = image.pixelData; + int width = image.width; + int height = image.height; for (const CesiumGeospatial::GlobeRectangle& rectangle : cutouts) { CesiumGeometry::Rectangle cutoutRectangle = projectRectangleSimple(projection, rectangle); @@ -128,15 +143,21 @@ namespace Cesium3DTiles { } } - result.pRendererResources = pPrepareRendererResources->prepareRasterInLoadThread(result.image); + void* pRendererResources = pPrepareRendererResources->prepareRasterInLoadThread(image); + LoadResult result; result.state = LoadState::Loaded; + result.image = std::move(image); + result.pRendererResources = pRendererResources; + result.errors = std::move(loadedImage.errors); + result.warnings = std::move(loadedImage.warnings); + return result; } else { + LoadResult result; result.pRendererResources = nullptr; result.state = LoadState::Failed; + return result; } - - return result; }).thenInMainThread([this](LoadResult&& result) { result.pRendererResources = result.pRendererResources; this->_image = std::move(result.image); diff --git a/Cesium3DTiles/src/RasterOverlayTileProvider.cpp b/Cesium3DTiles/src/RasterOverlayTileProvider.cpp index c6c16871f..e42f83822 100644 --- a/Cesium3DTiles/src/RasterOverlayTileProvider.cpp +++ b/Cesium3DTiles/src/RasterOverlayTileProvider.cpp @@ -17,6 +17,7 @@ namespace Cesium3DTiles { _asyncSystem(asyncSystem), _credit(std::nullopt), _pPrepareRendererResources(nullptr), + _pLogger(nullptr), _projection(CesiumGeospatial::GeographicProjection()), _tilingScheme(CesiumGeometry::QuadtreeTilingScheme(CesiumGeometry::Rectangle(0.0, 0.0, 0.0, 0.0), 1, 1)), _coverageRectangle(0.0, 0.0, 0.0, 0.0), @@ -37,6 +38,7 @@ namespace Cesium3DTiles { const AsyncSystem& asyncSystem, std::optional credit, std::shared_ptr pPrepareRendererResources, + std::shared_ptr pLogger, const CesiumGeospatial::Projection& projection, const CesiumGeometry::QuadtreeTilingScheme& tilingScheme, const CesiumGeometry::Rectangle& coverageRectangle, @@ -49,6 +51,7 @@ namespace Cesium3DTiles { _asyncSystem(asyncSystem), _credit(credit), _pPrepareRendererResources(pPrepareRendererResources), + _pLogger(pLogger), _projection(projection), _tilingScheme(tilingScheme), _coverageRectangle(coverageRectangle), @@ -353,7 +356,7 @@ namespace Cesium3DTiles { } void RasterOverlayTileProvider::notifyTileLoaded(RasterOverlayTile* pTile) noexcept { - this->_tileDataBytes += pTile->getImage().cesium.pixelData.size(); + this->_tileDataBytes += pTile->getImage().pixelData.size(); --this->_tilesCurrentlyLoading; } @@ -364,7 +367,7 @@ namespace Cesium3DTiles { assert(it != this->_tiles.end()); assert(it->second.get() == pTile); - this->_tileDataBytes -= pTile->getImage().cesium.pixelData.size(); + this->_tileDataBytes -= pTile->getImage().pixelData.size(); RasterOverlay& overlay = pTile->getOverlay(); diff --git a/Cesium3DTiles/src/TileMapServiceRasterOverlay.cpp b/Cesium3DTiles/src/TileMapServiceRasterOverlay.cpp index b08fd683e..679083ac3 100644 --- a/Cesium3DTiles/src/TileMapServiceRasterOverlay.cpp +++ b/Cesium3DTiles/src/TileMapServiceRasterOverlay.cpp @@ -22,6 +22,7 @@ namespace Cesium3DTiles { const AsyncSystem& asyncSystem, std::optional credit, std::shared_ptr pPrepareRendererResources, + std::shared_ptr pLogger, const CesiumGeospatial::Projection& projection, const CesiumGeometry::QuadtreeTilingScheme& tilingScheme, const CesiumGeometry::Rectangle& coverageRectangle, @@ -38,6 +39,7 @@ namespace Cesium3DTiles { asyncSystem, credit, pPrepareRendererResources, + pLogger, projection, tilingScheme, coverageRectangle, @@ -247,6 +249,7 @@ namespace Cesium3DTiles { asyncSystem, credit, pPrepareRendererResources, + pLogger, projection, tilingScheme, coverageRectangle, diff --git a/CesiumGltfReader/CMakeLists.txt b/CesiumGltfReader/CMakeLists.txt index 2af5ce8db..511485a07 100644 --- a/CesiumGltfReader/CMakeLists.txt +++ b/CesiumGltfReader/CMakeLists.txt @@ -20,6 +20,7 @@ target_include_directories( PUBLIC include PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../extern/stb src generated ) diff --git a/CesiumGltfReader/include/CesiumGltf/Reader.h b/CesiumGltfReader/include/CesiumGltf/Reader.h index 92bf585c1..b2f0cecb3 100644 --- a/CesiumGltfReader/include/CesiumGltf/Reader.h +++ b/CesiumGltfReader/include/CesiumGltf/Reader.h @@ -11,5 +11,18 @@ namespace CesiumGltf { std::string warnings; }; - ModelReaderResult readModel(const gsl::span& data); + struct ReadModelOptions { + bool decodeDataUris = true; + bool decodeEmbeddedImages = true; + }; + + ModelReaderResult readModel(const gsl::span& data, const ReadModelOptions& options = ReadModelOptions()); + + struct ImageReaderResult { + std::optional image; + std::string errors; + std::string warnings; + }; + + ImageReaderResult readImage(const gsl::span& data); } diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 680f005be..5937ca008 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -4,6 +4,10 @@ #include #include +#define STB_IMAGE_IMPLEMENTATION +#define STBI_FAILURE_USERMSG +#include + using namespace CesiumGltf; namespace { @@ -271,12 +275,65 @@ namespace { return result; } + + // template + // const T& getSafe(const std::vector& items, int64_t index) { + // static T default; + // if (index < 0 || index >= static_cast(items.size())) { + // return default; + // } else { + // return items[index]; + // } + // } + + // gsl::span safeSubspan(const gsl::span& s, int64_t offset, int64_t count) { + + // } + + // void postprocess(Model& model, const ReadModelOptions& options) { + // if (options.decodeEmbeddedImages) { + // for (Image& image : model.images) { + // const BufferView& bufferView = getSafe(model.bufferViews, image.bufferView); + // const Buffer& buffer = getSafe(model.buffers, bufferView.buffer); + // if (buffer.cesium.data.size() == 0) { + // continue; + // } + + // gsl::span bufferSpan(buffer.cesium.data); + // bufferSpan.subspan() + // } + // } + // } +} + +ModelReaderResult CesiumGltf::readModel(const gsl::span& data, const ReadModelOptions& /* options */) { + ModelReaderResult result = isBinaryGltf(data) ? readBinaryModel(data) : readJsonModel(data); + + // if (result.model) { + // postprocess(result.model.value(), options); + // } + + return result; } -ModelReaderResult CesiumGltf::readModel(const gsl::span& data) { - if (isBinaryGltf(data)) { - return readBinaryModel(data); +ImageReaderResult CesiumGltf::readImage(const gsl::span& data) { + ImageReaderResult result; + + result.image.emplace(); + ImageCesium& image = result.image.value(); + + image.bytesPerChannel = 1; + image.channels = 4; + + int channelsInFile; + stbi_uc* pImage = stbi_load_from_memory(data.data(), static_cast(data.size()), &image.width, &image.height, &channelsInFile, image.channels); + if (pImage) { + image.pixelData.assign(pImage, pImage + image.width * image.height * image.channels * image.bytesPerChannel); + stbi_image_free(pImage); } else { - return readJsonModel(data); + result.image.reset(); + result.errors = stbi_failure_reason(); } -} + + return result; +} \ No newline at end of file diff --git a/extern/stb b/extern/stb new file mode 160000 index 000000000..b42009b3b --- /dev/null +++ b/extern/stb @@ -0,0 +1 @@ +Subproject commit b42009b3b9d4ca35bc703f5310eedc74f584be58 From 2b2c4a8b1684091a462ffd69466440485b116b6e Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 11 Jan 2021 18:05:02 +1100 Subject: [PATCH 30/61] Add support for extensions, especially Draco. --- .../include/CesiumGltf/ExtensibleObject.h | 34 ++++++++++- .../CesiumGltf/KHR_draco_mesh_compression.h | 26 +++++++++ .../generated/AccessorJsonHandler.cpp | 1 + .../AccessorSparseIndicesJsonHandler.cpp | 1 + .../generated/AccessorSparseJsonHandler.cpp | 1 + .../AccessorSparseValuesJsonHandler.cpp | 1 + .../generated/AnimationChannelJsonHandler.cpp | 1 + .../AnimationChannelTargetJsonHandler.cpp | 1 + .../generated/AnimationJsonHandler.cpp | 1 + .../generated/AnimationSamplerJsonHandler.cpp | 1 + .../generated/AssetJsonHandler.cpp | 1 + .../generated/BufferJsonHandler.cpp | 1 + .../generated/BufferViewJsonHandler.cpp | 1 + .../generated/CameraJsonHandler.cpp | 1 + .../CameraOrthographicJsonHandler.cpp | 1 + .../CameraPerspectiveJsonHandler.cpp | 1 + .../generated/ImageJsonHandler.cpp | 1 + .../KHR_draco_mesh_compressionJsonHandler.cpp | 39 +++++++++++++ .../KHR_draco_mesh_compressionJsonHandler.h | 29 ++++++++++ .../generated/MaterialJsonHandler.cpp | 1 + .../MaterialNormalTextureInfoJsonHandler.cpp | 1 + ...aterialOcclusionTextureInfoJsonHandler.cpp | 1 + ...aterialPBRMetallicRoughnessJsonHandler.cpp | 1 + .../generated/MeshJsonHandler.cpp | 1 + .../generated/MeshPrimitiveJsonHandler.cpp | 15 +++++ .../generated/MeshPrimitiveJsonHandler.h | 11 ++++ .../generated/ModelJsonHandler.cpp | 1 + .../generated/NodeJsonHandler.cpp | 1 + .../generated/SamplerJsonHandler.cpp | 1 + .../generated/SceneJsonHandler.cpp | 1 + .../generated/SkinJsonHandler.cpp | 1 + .../generated/TextureInfoJsonHandler.cpp | 1 + .../generated/TextureJsonHandler.cpp | 1 + CesiumGltfReader/include/CesiumGltf/Reader.h | 1 + CesiumGltfReader/src/Reader.cpp | 12 ++-- extern/glTF | 2 +- .../generate-gltf-classes/.vscode/launch.json | 3 +- tools/generate-gltf-classes/SchemaCache.js | 14 ++++- .../createExtensionsProperty.js | 56 +++++++++++++++++++ tools/generate-gltf-classes/generate.js | 23 +++++++- tools/generate-gltf-classes/index.js | 55 +++++++++++++++++- .../generate-gltf-classes/resolveProperty.js | 1 + 42 files changed, 332 insertions(+), 16 deletions(-) create mode 100644 CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h create mode 100644 CesiumGltfReader/generated/KHR_draco_mesh_compressionJsonHandler.cpp create mode 100644 CesiumGltfReader/generated/KHR_draco_mesh_compressionJsonHandler.h create mode 100644 tools/generate-gltf-classes/createExtensionsProperty.js diff --git a/CesiumGltf/include/CesiumGltf/ExtensibleObject.h b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h index 0e95ea5f9..ffd4f89d0 100644 --- a/CesiumGltf/include/CesiumGltf/ExtensibleObject.h +++ b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h @@ -1,11 +1,43 @@ #pragma once +#include +#include + namespace CesiumGltf { /** * @brief The base class for objects in a glTF that have extensions and extras. */ struct ExtensibleObject { - // TODO: extensions // TODO: extras + + /** + * @brief Gets an extension given its static type. + * + * @tparam T The type of the extension. + * @return A pointer to the extension, or nullptr if the extension is not attached to this object. + */ + template + const T* getExtension() const noexcept { + for (const std::any& extension : extensions) { + const T* p = std::any_cast(&extension); + if (p) { + return p; + } + } + return nullptr; + } + + /** @copydoc ExtensionObject::getExtension */ + template + T* getExtension() noexcept { + return const_cast(this->getExtension()); + } + + /** + * @brief The extensions attached to this object. + * + * Use {@link getExtension} to get the extension with a particular static type. + */ + std::vector extensions; }; } diff --git a/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h b/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h new file mode 100644 index 000000000..015990699 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h @@ -0,0 +1,26 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/ExtensibleObject.h" +#include +#include + +namespace CesiumGltf { + /** + * @brief undefined + */ + struct KHR_draco_mesh_compression : public ExtensibleObject { + + /** + * @brief The index of the bufferView. + */ + int32_t bufferView; + + /** + * @brief A dictionary object, where each key corresponds to an attribute and its unique attribute id stored in the compressed geometry. + */ + std::unordered_map attributes; + + }; +} diff --git a/CesiumGltfReader/generated/AccessorJsonHandler.cpp b/CesiumGltfReader/generated/AccessorJsonHandler.cpp index 6a09a2c65..0dfc2b530 100644 --- a/CesiumGltfReader/generated/AccessorJsonHandler.cpp +++ b/CesiumGltfReader/generated/AccessorJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "AccessorJsonHandler.h" #include "CesiumGltf/Accessor.h" + #include #include diff --git a/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp index 0c2904005..76b31df82 100644 --- a/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp +++ b/CesiumGltfReader/generated/AccessorSparseIndicesJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "AccessorSparseIndicesJsonHandler.h" #include "CesiumGltf/AccessorSparseIndices.h" + #include #include diff --git a/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp b/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp index e613c44b0..dd6c756e3 100644 --- a/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp +++ b/CesiumGltfReader/generated/AccessorSparseJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "AccessorSparseJsonHandler.h" #include "CesiumGltf/AccessorSparse.h" + #include #include diff --git a/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp index 3ff2abd49..460922bfa 100644 --- a/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp +++ b/CesiumGltfReader/generated/AccessorSparseValuesJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "AccessorSparseValuesJsonHandler.h" #include "CesiumGltf/AccessorSparseValues.h" + #include #include diff --git a/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp b/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp index a1f34cb9e..733852867 100644 --- a/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp +++ b/CesiumGltfReader/generated/AnimationChannelJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "AnimationChannelJsonHandler.h" #include "CesiumGltf/AnimationChannel.h" + #include #include diff --git a/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp index 34ef520ce..4dc419960 100644 --- a/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp +++ b/CesiumGltfReader/generated/AnimationChannelTargetJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "AnimationChannelTargetJsonHandler.h" #include "CesiumGltf/AnimationChannelTarget.h" + #include #include diff --git a/CesiumGltfReader/generated/AnimationJsonHandler.cpp b/CesiumGltfReader/generated/AnimationJsonHandler.cpp index b91a03d3e..800ff7726 100644 --- a/CesiumGltfReader/generated/AnimationJsonHandler.cpp +++ b/CesiumGltfReader/generated/AnimationJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "AnimationJsonHandler.h" #include "CesiumGltf/Animation.h" + #include #include diff --git a/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp index 6ce50c5d4..1d13d31c1 100644 --- a/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp +++ b/CesiumGltfReader/generated/AnimationSamplerJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "AnimationSamplerJsonHandler.h" #include "CesiumGltf/AnimationSampler.h" + #include #include diff --git a/CesiumGltfReader/generated/AssetJsonHandler.cpp b/CesiumGltfReader/generated/AssetJsonHandler.cpp index 6451ed7a7..ef5191038 100644 --- a/CesiumGltfReader/generated/AssetJsonHandler.cpp +++ b/CesiumGltfReader/generated/AssetJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "AssetJsonHandler.h" #include "CesiumGltf/Asset.h" + #include #include diff --git a/CesiumGltfReader/generated/BufferJsonHandler.cpp b/CesiumGltfReader/generated/BufferJsonHandler.cpp index 1e99f0615..fd0e25d48 100644 --- a/CesiumGltfReader/generated/BufferJsonHandler.cpp +++ b/CesiumGltfReader/generated/BufferJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "BufferJsonHandler.h" #include "CesiumGltf/Buffer.h" + #include #include diff --git a/CesiumGltfReader/generated/BufferViewJsonHandler.cpp b/CesiumGltfReader/generated/BufferViewJsonHandler.cpp index 14854983c..e794f862a 100644 --- a/CesiumGltfReader/generated/BufferViewJsonHandler.cpp +++ b/CesiumGltfReader/generated/BufferViewJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "BufferViewJsonHandler.h" #include "CesiumGltf/BufferView.h" + #include #include diff --git a/CesiumGltfReader/generated/CameraJsonHandler.cpp b/CesiumGltfReader/generated/CameraJsonHandler.cpp index 5725f6082..be6085f8b 100644 --- a/CesiumGltfReader/generated/CameraJsonHandler.cpp +++ b/CesiumGltfReader/generated/CameraJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "CameraJsonHandler.h" #include "CesiumGltf/Camera.h" + #include #include diff --git a/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp index 84df21893..69a93076e 100644 --- a/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp +++ b/CesiumGltfReader/generated/CameraOrthographicJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "CameraOrthographicJsonHandler.h" #include "CesiumGltf/CameraOrthographic.h" + #include #include diff --git a/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp index 759e03216..4063f141c 100644 --- a/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp +++ b/CesiumGltfReader/generated/CameraPerspectiveJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "CameraPerspectiveJsonHandler.h" #include "CesiumGltf/CameraPerspective.h" + #include #include diff --git a/CesiumGltfReader/generated/ImageJsonHandler.cpp b/CesiumGltfReader/generated/ImageJsonHandler.cpp index 971e367fa..4eccf7046 100644 --- a/CesiumGltfReader/generated/ImageJsonHandler.cpp +++ b/CesiumGltfReader/generated/ImageJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "ImageJsonHandler.h" #include "CesiumGltf/Image.h" + #include #include diff --git a/CesiumGltfReader/generated/KHR_draco_mesh_compressionJsonHandler.cpp b/CesiumGltfReader/generated/KHR_draco_mesh_compressionJsonHandler.cpp new file mode 100644 index 000000000..9a2104443 --- /dev/null +++ b/CesiumGltfReader/generated/KHR_draco_mesh_compressionJsonHandler.cpp @@ -0,0 +1,39 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#include "KHR_draco_mesh_compressionJsonHandler.h" +#include "CesiumGltf/KHR_draco_mesh_compression.h" + +#include +#include + +using namespace CesiumGltf; + +void KHR_draco_mesh_compressionJsonHandler::reset(IJsonHandler* pParent, KHR_draco_mesh_compression* pObject) { + ExtensibleObjectJsonHandler::reset(pParent, pObject); + this->_pObject = pObject; +} + +KHR_draco_mesh_compression* KHR_draco_mesh_compressionJsonHandler::getObject() { + return this->_pObject; +} + +void KHR_draco_mesh_compressionJsonHandler::reportWarning(const std::string& warning, std::vector&& context) { + if (this->getCurrentKey()) { + context.emplace_back(std::string(".") + this->getCurrentKey()); + } + this->parent()->reportWarning(warning, std::move(context)); +} + +IJsonHandler* KHR_draco_mesh_compressionJsonHandler::Key(const char* str, size_t /*length*/, bool /*copy*/) { + assert(this->_pObject); + return this->KHR_draco_mesh_compressionKey(str, *this->_pObject); +} + +IJsonHandler* KHR_draco_mesh_compressionJsonHandler::KHR_draco_mesh_compressionKey(const char* str, KHR_draco_mesh_compression& o) { + using namespace std::string_literals; + + if ("bufferView"s == str) return property("bufferView", this->_bufferView, o.bufferView); + if ("attributes"s == str) return property("attributes", this->_attributes, o.attributes); + + return this->ExtensibleObjectKey(str, *this->_pObject); +} diff --git a/CesiumGltfReader/generated/KHR_draco_mesh_compressionJsonHandler.h b/CesiumGltfReader/generated/KHR_draco_mesh_compressionJsonHandler.h new file mode 100644 index 000000000..8312d7991 --- /dev/null +++ b/CesiumGltfReader/generated/KHR_draco_mesh_compressionJsonHandler.h @@ -0,0 +1,29 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "DictionaryJsonHandler.h" +#include "ExtensibleObjectJsonHandler.h" +#include "IntegerJsonHandler.h" + +namespace CesiumGltf { + struct KHR_draco_mesh_compression; + + class KHR_draco_mesh_compressionJsonHandler : public ExtensibleObjectJsonHandler { + public: + void reset(IJsonHandler* pHandler, KHR_draco_mesh_compression* pObject); + KHR_draco_mesh_compression* getObject(); + virtual void reportWarning(const std::string& warning, std::vector&& context = std::vector()) override; + + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + + protected: + IJsonHandler* KHR_draco_mesh_compressionKey(const char* str, KHR_draco_mesh_compression& o); + + private: + + KHR_draco_mesh_compression* _pObject; + IntegerJsonHandler _bufferView; + DictionaryJsonHandler> _attributes; + }; +} diff --git a/CesiumGltfReader/generated/MaterialJsonHandler.cpp b/CesiumGltfReader/generated/MaterialJsonHandler.cpp index 4cdad2554..1065e9097 100644 --- a/CesiumGltfReader/generated/MaterialJsonHandler.cpp +++ b/CesiumGltfReader/generated/MaterialJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "MaterialJsonHandler.h" #include "CesiumGltf/Material.h" + #include #include diff --git a/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp index 730f35b45..ba1e5158d 100644 --- a/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp +++ b/CesiumGltfReader/generated/MaterialNormalTextureInfoJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "MaterialNormalTextureInfoJsonHandler.h" #include "CesiumGltf/MaterialNormalTextureInfo.h" + #include #include diff --git a/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp index e6d4334d6..160b19b8a 100644 --- a/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp +++ b/CesiumGltfReader/generated/MaterialOcclusionTextureInfoJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "MaterialOcclusionTextureInfoJsonHandler.h" #include "CesiumGltf/MaterialOcclusionTextureInfo.h" + #include #include diff --git a/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp index 05587cbcd..faacfce39 100644 --- a/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp +++ b/CesiumGltfReader/generated/MaterialPBRMetallicRoughnessJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "MaterialPBRMetallicRoughnessJsonHandler.h" #include "CesiumGltf/MaterialPBRMetallicRoughness.h" + #include #include diff --git a/CesiumGltfReader/generated/MeshJsonHandler.cpp b/CesiumGltfReader/generated/MeshJsonHandler.cpp index 6413019a9..9988f139d 100644 --- a/CesiumGltfReader/generated/MeshJsonHandler.cpp +++ b/CesiumGltfReader/generated/MeshJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "MeshJsonHandler.h" #include "CesiumGltf/Mesh.h" + #include #include diff --git a/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp index 0512d67b7..311be506e 100644 --- a/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp +++ b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "MeshPrimitiveJsonHandler.h" #include "CesiumGltf/MeshPrimitive.h" +#include "CesiumGltf/KHR_draco_mesh_compression.h" #include #include @@ -36,6 +37,20 @@ IJsonHandler* MeshPrimitiveJsonHandler::MeshPrimitiveKey(const char* str, MeshPr if ("material"s == str) return property("material", this->_material, o.material); if ("mode"s == str) return property("mode", this->_mode, o.mode); if ("targets"s == str) return property("targets", this->_targets, o.targets); + if ("extensions"s == str) return property("extensions", this->_extensions, o.extensions); return this->ExtensibleObjectKey(str, *this->_pObject); } + +void MeshPrimitiveJsonHandler::ExtensionsJsonHandler::reset(IJsonHandler* pParent, std::vector* pExtensions) { + ObjectJsonHandler::reset(pParent); + this->_pExtensions = pExtensions; +} + +IJsonHandler* MeshPrimitiveJsonHandler::ExtensionsJsonHandler::Key(const char* str, size_t /* length */, bool /* copy */) { + using namespace std::string_literals; + + if ("KHR_draco_mesh_compression"s == str) return property("KHR_draco_mesh_compression", this->_KHR_draco_mesh_compression, std::any_cast(this->_pExtensions->emplace_back(KHR_draco_mesh_compression()))); + + return this->ignoreAndContinue(); +} diff --git a/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h index 8503e032c..5bd507fcd 100644 --- a/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h +++ b/CesiumGltfReader/generated/MeshPrimitiveJsonHandler.h @@ -7,6 +7,7 @@ #include "DictionaryJsonHandler.h" #include "ExtensibleObjectJsonHandler.h" #include "IntegerJsonHandler.h" +#include "KHR_draco_mesh_compressionJsonHandler.h" namespace CesiumGltf { struct MeshPrimitive; @@ -23,6 +24,15 @@ namespace CesiumGltf { IJsonHandler* MeshPrimitiveKey(const char* str, MeshPrimitive& o); private: + class ExtensionsJsonHandler : public ObjectJsonHandler { + public: + void reset(IJsonHandler* pParent, std::vector* pExtensions); + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + std::vector* _pExtensions = nullptr; + KHR_draco_mesh_compressionJsonHandler _KHR_draco_mesh_compression; + }; MeshPrimitive* _pObject; DictionaryJsonHandler> _attributes; @@ -30,5 +40,6 @@ namespace CesiumGltf { IntegerJsonHandler _material; IntegerJsonHandler _mode; ArrayJsonHandler, DictionaryJsonHandler>> _targets; + ExtensionsJsonHandler _extensions; }; } diff --git a/CesiumGltfReader/generated/ModelJsonHandler.cpp b/CesiumGltfReader/generated/ModelJsonHandler.cpp index 5625afd53..5265cf3b0 100644 --- a/CesiumGltfReader/generated/ModelJsonHandler.cpp +++ b/CesiumGltfReader/generated/ModelJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "ModelJsonHandler.h" #include "CesiumGltf/Model.h" + #include #include diff --git a/CesiumGltfReader/generated/NodeJsonHandler.cpp b/CesiumGltfReader/generated/NodeJsonHandler.cpp index 337f7099c..a34eb4188 100644 --- a/CesiumGltfReader/generated/NodeJsonHandler.cpp +++ b/CesiumGltfReader/generated/NodeJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "NodeJsonHandler.h" #include "CesiumGltf/Node.h" + #include #include diff --git a/CesiumGltfReader/generated/SamplerJsonHandler.cpp b/CesiumGltfReader/generated/SamplerJsonHandler.cpp index e226228c2..4e52069f0 100644 --- a/CesiumGltfReader/generated/SamplerJsonHandler.cpp +++ b/CesiumGltfReader/generated/SamplerJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "SamplerJsonHandler.h" #include "CesiumGltf/Sampler.h" + #include #include diff --git a/CesiumGltfReader/generated/SceneJsonHandler.cpp b/CesiumGltfReader/generated/SceneJsonHandler.cpp index 92500c230..01c9f5248 100644 --- a/CesiumGltfReader/generated/SceneJsonHandler.cpp +++ b/CesiumGltfReader/generated/SceneJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "SceneJsonHandler.h" #include "CesiumGltf/Scene.h" + #include #include diff --git a/CesiumGltfReader/generated/SkinJsonHandler.cpp b/CesiumGltfReader/generated/SkinJsonHandler.cpp index ad6bf1ef4..fb8aefeb9 100644 --- a/CesiumGltfReader/generated/SkinJsonHandler.cpp +++ b/CesiumGltfReader/generated/SkinJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "SkinJsonHandler.h" #include "CesiumGltf/Skin.h" + #include #include diff --git a/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp b/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp index 789479327..96b325d4b 100644 --- a/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp +++ b/CesiumGltfReader/generated/TextureInfoJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "TextureInfoJsonHandler.h" #include "CesiumGltf/TextureInfo.h" + #include #include diff --git a/CesiumGltfReader/generated/TextureJsonHandler.cpp b/CesiumGltfReader/generated/TextureJsonHandler.cpp index 5484f3310..308e576aa 100644 --- a/CesiumGltfReader/generated/TextureJsonHandler.cpp +++ b/CesiumGltfReader/generated/TextureJsonHandler.cpp @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #include "TextureJsonHandler.h" #include "CesiumGltf/Texture.h" + #include #include diff --git a/CesiumGltfReader/include/CesiumGltf/Reader.h b/CesiumGltfReader/include/CesiumGltf/Reader.h index b2f0cecb3..0cffab4a7 100644 --- a/CesiumGltfReader/include/CesiumGltf/Reader.h +++ b/CesiumGltfReader/include/CesiumGltf/Reader.h @@ -14,6 +14,7 @@ namespace CesiumGltf { struct ReadModelOptions { bool decodeDataUris = true; bool decodeEmbeddedImages = true; + bool decodeDraco = true; }; ModelReaderResult readModel(const gsl::span& data, const ReadModelOptions& options = ReadModelOptions()); diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 5937ca008..e8fba3463 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -290,7 +290,7 @@ namespace { // } - // void postprocess(Model& model, const ReadModelOptions& options) { + void postprocess(Model& /* model */, const ReadModelOptions& /* options */) { // if (options.decodeEmbeddedImages) { // for (Image& image : model.images) { // const BufferView& bufferView = getSafe(model.bufferViews, image.bufferView); @@ -303,15 +303,15 @@ namespace { // bufferSpan.subspan() // } // } - // } + } } -ModelReaderResult CesiumGltf::readModel(const gsl::span& data, const ReadModelOptions& /* options */) { +ModelReaderResult CesiumGltf::readModel(const gsl::span& data, const ReadModelOptions& options) { ModelReaderResult result = isBinaryGltf(data) ? readBinaryModel(data) : readJsonModel(data); - // if (result.model) { - // postprocess(result.model.value(), options); - // } + if (result.model) { + postprocess(result.model.value(), options); + } return result; } diff --git a/extern/glTF b/extern/glTF index fa4e11c77..b238d8405 160000 --- a/extern/glTF +++ b/extern/glTF @@ -1 +1 @@ -Subproject commit fa4e11c77c906362f8ac3a22506c4d07f27fcb20 +Subproject commit b238d84053ef3090f9818f8a4ae5d7f0f90dbe4d diff --git a/tools/generate-gltf-classes/.vscode/launch.json b/tools/generate-gltf-classes/.vscode/launch.json index 01b82159d..f94c85919 100644 --- a/tools/generate-gltf-classes/.vscode/launch.json +++ b/tools/generate-gltf-classes/.vscode/launch.json @@ -15,7 +15,8 @@ "args": [ "--schema", "../../extern/glTF/specification/2.0/schema/", "--output", "test_output/model", - "--readerOutput", "test_output/reader" + "--readerOutput", "test_output/reader", + "--extensions", "../../extern/glTF/extensions/2.0" ] } ] diff --git a/tools/generate-gltf-classes/SchemaCache.js b/tools/generate-gltf-classes/SchemaCache.js index 9f6e8190f..d89f8f926 100644 --- a/tools/generate-gltf-classes/SchemaCache.js +++ b/tools/generate-gltf-classes/SchemaCache.js @@ -2,8 +2,9 @@ const path = require("path"); const fs = require("fs"); class SchemaCache { - constructor(schemaPath) { + constructor(schemaPath, extensionPath) { this.schemaPath = schemaPath; + this.extensionPath = extensionPath; this.cache = {}; } @@ -17,6 +18,17 @@ class SchemaCache { this.cache[name] = result; return result; } + + loadExtension(name) { + const existing = this.cache[name]; + if (existing) { + return existing; + } + + const result = JSON.parse(fs.readFileSync(path.join(this.extensionPath, name), "utf-8")); + this.cache[name] = result; + return result; + } } module.exports = SchemaCache; diff --git a/tools/generate-gltf-classes/createExtensionsProperty.js b/tools/generate-gltf-classes/createExtensionsProperty.js new file mode 100644 index 000000000..17e916637 --- /dev/null +++ b/tools/generate-gltf-classes/createExtensionsProperty.js @@ -0,0 +1,56 @@ +const unindent = require("./unindent"); + +function createExtensionsProperty(extensions, name, schema) { + if (!extensions) { + return undefined; + } + + return { + name: "extensions", + headers: [], + readerHeaders: extensions.map(extension => `"${extension.className}JsonHandler.h"`), + readerHeadersImpl: extensions.map(extension => `"CesiumGltf/${extension.className}.h"`), + type: undefined, + readerType: "ExtensionsJsonHandler", + schemas: [], + localTypes: [], + readerLocalTypes: [createExtensionType(extensions)], + readerLocalTypesImpl: [createExtensionTypeImpl(name, extensions)], + briefDoc: undefined, + fullDoc: undefined + }; +} + +function createExtensionType(extensions) { + return unindent(` + class ExtensionsJsonHandler : public ObjectJsonHandler { + public: + void reset(IJsonHandler* pParent, std::vector* pExtensions); + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + + private: + std::vector* _pExtensions = nullptr; + ${extensions.map(extension => `${extension.className}JsonHandler _${extension.name};`).join("\n")} + }; + `); + return "Extensions!!"; +} + +function createExtensionTypeImpl(name, extensions) { + return unindent(` + void ${name}JsonHandler::ExtensionsJsonHandler::reset(IJsonHandler* pParent, std::vector* pExtensions) { + ObjectJsonHandler::reset(pParent); + this->_pExtensions = pExtensions; + } + + IJsonHandler* ${name}JsonHandler::ExtensionsJsonHandler::Key(const char* str, size_t /* length */, bool /* copy */) { + using namespace std::string_literals; + + ${extensions.map(extension => `if ("${extension.name}"s == str) return property("${extension.name}", this->_${extension.name}, std::any_cast<${extension.className}&>(this->_pExtensions->emplace_back(${extension.className}())));`).join("\n")} + + return this->ignoreAndContinue(); + } + `); +} + +module.exports = createExtensionsProperty; diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index 8e54ea391..ab86aa8c7 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -1,10 +1,11 @@ -const path = require("path"); +const createExtensionsProperty = require("./createExtensionsProperty"); const fs = require("fs"); +const getNameFromSchema = require("./getNameFromSchema"); +const indent = require("./indent"); const lodash = require("lodash"); +const path = require("path"); const resolveProperty = require("./resolveProperty"); -const getNameFromSchema = require("./getNameFromSchema"); const unindent = require("./unindent"); -const indent = require("./indent"); function generate(options, schema) { const { schemaCache, nameMapping, outputDir, readerOutputDir, cesiumProperties } = options; @@ -25,6 +26,11 @@ function generate(options, schema) { ) .filter((property) => property !== undefined); + const extensionsProperty = createExtensionsProperty(options.extensions[schema.title], name, schema); + if (extensionsProperty) { + properties.push(extensionsProperty); + } + const localTypes = lodash.uniq( lodash.flatten(properties.map((property) => property.localTypes)) ); @@ -56,6 +62,7 @@ function generate(options, schema) { ${indent( properties .map((property) => formatProperty(property)) + .filter(propertyText => propertyText !== undefined) .join("\n\n"), 16 )} @@ -123,11 +130,17 @@ function generate(options, schema) { lodash.flatten(properties.map((property) => property.readerLocalTypesImpl)) ); + const readerHeadersImpl = lodash.uniq( + [...lodash.flatten(properties.map((property) => property.readerHeadersImpl))] + ); + readerHeadersImpl.sort(); + const readerImpl = ` // This file was generated by generate-gltf-classes. // DO NOT EDIT THIS FILE! #include "${name}JsonHandler.h" #include "CesiumGltf/${name}.h" + ${readerHeadersImpl.map((header) => `#include ${header}`).join("\n")} #include #include @@ -179,6 +192,10 @@ function generate(options, schema) { } function formatProperty(property) { + if (!property.type) { + return undefined; + } + let result = ""; result += `/**\n * @brief ${property.briefDoc || property.name}\n`; diff --git a/tools/generate-gltf-classes/index.js b/tools/generate-gltf-classes/index.js index c6ec72194..d3ad5d25d 100644 --- a/tools/generate-gltf-classes/index.js +++ b/tools/generate-gltf-classes/index.js @@ -21,6 +21,12 @@ const argv = yargs.options({ description: "The output directory for the generated reader files.", demandOption: true, type: "string" + }, + extensions: { + alias: "e", + description: "The extensions directory.", + demandOption: true, + type: "string" } }).argv; @@ -39,7 +45,7 @@ const cesiumProperties = { "Image": true }; -const schemaCache = new SchemaCache(argv.schema); +const schemaCache = new SchemaCache(argv.schema, argv.extensions); const modelSchema = schemaCache.load("glTF.schema.json"); const options = { @@ -47,12 +53,55 @@ const options = { nameMapping, cesiumProperties, outputDir: argv.output, - readerOutputDir: argv.readerOutput + readerOutputDir: argv.readerOutput, + // key: Title of the element name that is extended (e.g. "Mesh Primitive") + // value: Array of extension type names. + extensions: {} }; +let schemas = [modelSchema]; + +const extensionInfo = { + "KHR_draco_mesh_compression": { + extensionName: "KHR_draco_mesh_compression", + schema: "Khronos/KHR_draco_mesh_compression/schema/mesh.primitive.KHR_draco_mesh_compression.schema.json", + attachTo: [ + "mesh.primitive" + ] + } +}; + +for (const extensionClassName of Object.keys(extensionInfo)) { + const extension = extensionInfo[extensionClassName]; + const extensionSchema = schemaCache.loadExtension(extension.schema); + if (!extensionSchema) { + console.warn(`Could not load schema ${inExtensions[extensionClassName]} for extension class ${extensionClassName}.`); + continue; + } + + nameMapping[extensionSchema.title] = extensionClassName; + schemas.push(...generate(options, extensionSchema)); + + for (const objectToExtend of extension.attachTo) { + const objectToExtendSchema = schemaCache.load(`${objectToExtend}.schema.json`); + if (!objectToExtendSchema) { + console.warn("Could not load schema for ${objectToExtend}."); + continue; + } + + if (!options.extensions[objectToExtend]) { + options.extensions[objectToExtendSchema.title] = []; + } + + options.extensions[objectToExtendSchema.title].push({ + name: extension.extensionName, + className: extensionClassName + }); + } +} + const processed = {}; -let schemas = [modelSchema]; while (schemas.length > 0) { const schema = schemas.pop(); if (processed[schema.title]) { diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index 732ba7e6a..2aa5d0baf 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -139,6 +139,7 @@ function propertyDefaults(propertyName, propertyDetails) { name: propertyName, headers: [], readerHeaders: [], + readerHeadersImpl: [], type: "", readerType: "", schemas: [], From 6a6d2d94de099c109690b9a7079bb442786b3911 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Tue, 12 Jan 2021 21:40:35 +1100 Subject: [PATCH 31/61] Draco loading. --- Cesium3DTiles/CMakeLists.txt | 2 +- CesiumGltf/include/CesiumGltf/AccessorView.h | 114 ++++++ .../include/CesiumGltf/AccessorWriter.h | 42 +++ .../include/CesiumGltf/ExtensibleObject.h | 2 +- CesiumGltf/include/CesiumGltf/Helpers.h | 93 +++++ CesiumGltf/src/Helpers.cpp | 51 +++ CesiumGltfReader/CMakeLists.txt | 6 +- CesiumGltfReader/src/Reader.cpp | 8 +- CesiumGltfReader/src/decodeDraco.cpp | 347 ++++++++++++++++++ CesiumGltfReader/src/decodeDraco.h | 7 + 10 files changed, 667 insertions(+), 5 deletions(-) create mode 100644 CesiumGltf/include/CesiumGltf/AccessorView.h create mode 100644 CesiumGltf/include/CesiumGltf/AccessorWriter.h create mode 100644 CesiumGltf/include/CesiumGltf/Helpers.h create mode 100644 CesiumGltf/src/Helpers.cpp create mode 100644 CesiumGltfReader/src/decodeDraco.cpp create mode 100644 CesiumGltfReader/src/decodeDraco.h diff --git a/Cesium3DTiles/CMakeLists.txt b/Cesium3DTiles/CMakeLists.txt index 44352d53e..520368d26 100644 --- a/Cesium3DTiles/CMakeLists.txt +++ b/Cesium3DTiles/CMakeLists.txt @@ -16,11 +16,11 @@ target_sources( target_include_directories( Cesium3DTiles SYSTEM PUBLIC - # Same with RapidJSON ${CMAKE_CURRENT_SOURCE_DIR}/../extern/rapidjson/include # Draco's CMake doesn't use target_include_directories, so we need to manually add draco's include dirs here. ${CMAKE_CURRENT_SOURCE_DIR}/../extern/draco/src + ${CMAKE_BINARY_DIR} PUBLIC include diff --git a/CesiumGltf/include/CesiumGltf/AccessorView.h b/CesiumGltf/include/CesiumGltf/AccessorView.h new file mode 100644 index 000000000..a1868659b --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AccessorView.h @@ -0,0 +1,114 @@ +#pragma once + +#include "CesiumGltf/Model.h" +#include "CesiumGltf/Helpers.h" +#include + +namespace CesiumGltf { + + /** + * @brief A view on the data of one accessor of a glTF asset. + * + * It provides the actual accessor data like an array of elements. + * The type of the accessor elements is determined by the template + * parameter. Instances are created from an input glTF model + * and an accessor index, and the {@link operator[]()} + * can be used to access the elements: + * + * ``` + * CesiumGltf::Model model; + * GltfAccessor positions(model, accessorIndex) + * glm::vec3 position = positions[i]; + * ``` + * + * @tparam T The type of the elements in the accessor. + */ + template + class AccessorView final { + private: + uint8_t* _pData; + int64_t _stride; + int64_t _offset; + int64_t _size; + + public: + typedef T value_type; + + /** + * @brief Creates a new instance. + * + * The resulting instance will provide the data of the specified + * accessor from the given model. + * + * @param model The glTF model. + * @param accessorID The ID (index) of the accessor. + * @throws An `std::runtime_error` may be thrown when there are + * inconsistencies in the given model. This may refer to the model + * itself, or to cases where the size of the template parameter `T` + * does not match the size of the elements of the specified accessor. + */ + AccessorView(const CesiumGltf::Model& model, int32_t accessorID) { + const CesiumGltf::Accessor& accessor = model.accessors[accessorID]; + const CesiumGltf::BufferView& bufferView = model.bufferViews[accessor.bufferView]; + const CesiumGltf::Buffer& buffer = model.buffers[bufferView.buffer]; + + const std::vector& data = buffer.cesium.data; + int64_t bufferBytes = data.size(); + if (bufferView.byteOffset + bufferView.byteLength > bufferBytes) { + throw std::runtime_error("bufferView does not fit in buffer."); + } + + int64_t accessorByteStride = computeByteStride(accessor, bufferView); + if (accessorByteStride == -1) { + throw std::runtime_error("cannot compute accessor byteStride."); + } + + int64_t accessorComponentElements = computeNumberOfComponents(accessor.type); + int64_t accessorComponentBytes = computeByteSizeOfComponent(accessor.componentType); + int64_t accessorBytesPerStride = accessorComponentElements * accessorComponentBytes; + + if (sizeof(T) != accessorBytesPerStride) { + throw std::runtime_error("sizeof(T) does not much accessor bytes."); + } + + int64_t accessorBytes = accessorByteStride * accessor.count; + int64_t bytesRemainingInBufferView = bufferView.byteLength - (accessor.byteOffset + accessorByteStride * (accessor.count - 1) + accessorBytesPerStride); + if (accessorBytes > bufferView.byteLength || bytesRemainingInBufferView < 0) { + throw std::runtime_error("accessor does not fit in bufferView."); + } + + this->_stride = accessorByteStride; + this->_offset = accessor.byteOffset + bufferView.byteOffset; + this->_size = accessor.count; + this->_pData = &buffer.cesium.data.data(); + } + + /** + * @brief Provides the specified accessor element. + * + * @param i The index of the element. + * @returns The constant reference to the accessor element. + * @throws A `std::range_error` if the given index is negative + * or not smaller than the {@link size} of this accessor. + */ + const T& operator[](int64_t i) const { + if (i < 0 || i >= this->_size) { + throw std::range_error("index out of range"); + } + + return *reinterpret_cast(this->_pBufferViewData + i * this->_stride + this->_offset); + } + + /** + * @brief Returns the size (number of elements) of this accessor. + * + * This is the number of elements of type `T` that this accessor contains. + * + * @returns The size. + */ + int64_t size() const noexcept { + return this->_size; + } + }; + +} diff --git a/CesiumGltf/include/CesiumGltf/AccessorWriter.h b/CesiumGltf/include/CesiumGltf/AccessorWriter.h new file mode 100644 index 000000000..4cd1d7e4e --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AccessorWriter.h @@ -0,0 +1,42 @@ +#pragma once + +#include "Gltf.h" +#include "GltfAccessor.h" + +#include + +namespace CesiumGltf { + + /** + * @brief Provides write access to an {@link AccessorView}. + */ + template + class AccessorWriter final { + private: + AccessorView _accessor; + + public: + + /** @copydoc AccessorView::AccessorView */ + AccessorWriter(CesiumGltf::Model& model, int32_t accessorID) : + _accessor(model, accessorID) + { + } + + /** @copydoc AccessorView::operator[]() */ + const T& operator[](size_t i) const { + return this->_accessor[i]; + } + + /** @copydoc AccessorView::operator[]() */ + T& operator[](size_t i) { + return const_cast(this->_accessor[i]); + } + + /** @copydoc AccessorView::size */ + size_t size() const noexcept { + return this->_accessor.size(); + } + }; + +} \ No newline at end of file diff --git a/CesiumGltf/include/CesiumGltf/ExtensibleObject.h b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h index ffd4f89d0..ecddd72b6 100644 --- a/CesiumGltf/include/CesiumGltf/ExtensibleObject.h +++ b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h @@ -30,7 +30,7 @@ namespace CesiumGltf { /** @copydoc ExtensionObject::getExtension */ template T* getExtension() noexcept { - return const_cast(this->getExtension()); + return const_cast(const_cast(this)->getExtension()); } /** diff --git a/CesiumGltf/include/CesiumGltf/Helpers.h b/CesiumGltf/include/CesiumGltf/Helpers.h new file mode 100644 index 000000000..c2577a542 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Helpers.h @@ -0,0 +1,93 @@ +#pragma once + +#include "CesiumGltf/Accessor.h" +#include + +namespace CesiumGltf { + struct BufferView; + + /** + * @brief Computes the number of components for a given accessor type. + * + * For example `CesiumGltf::Accessor::Type::SCALAR` has 1 component while + * `CesiumGltf::Accessor::Type::VEC4` has 4 components. + * + * @param type The accessor type. + * @return The number of components. + */ + int8_t computeNumberOfComponents(CesiumGltf::Accessor::Type type); + + /** + * @brief Returns the number of bytes for a given accessor component type. + * + * For example `CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT` is 2 bytes while + * `CesiumGltf::Accessor::ComponentType::FLOAT` is 4 bytes. + * + * @param componentType The accessor component type. + * @return The number of bytes for the component type. + */ + int8_t computeByteSizeOfComponent(CesiumGltf::Accessor::ComponentType componentType); + + /** + * @brief Computes the stride for a given {@link Accessor} and {@link BufferView}. + * + * The stride is the number of bytes between the same elements of successive vertices. + * + * @param accessor The accessor. + * @param bufferView The buffer view. + * @return The stride in bytes. + */ + int64_t computeByteStride(const CesiumGltf::Accessor& accessor, const CesiumGltf::BufferView& bufferView); + + /** + * @brief Safely gets the element with a given index, returning a default instance if the index is outside the range. + * + * @tparam T The type of the array. + * @param items The array. + * @param index The index of the array element to retrieve. + * @return The requested element, or a default instance if the index is invalid. + */ + template + static const T& getSafe(const std::vector& items, int32_t index) { + static T default; + if (index < 0 || static_cast(index) >= pItems->size()) { + return default; + } else { + return items[index]; + } + } + + /** + * @brief Safely gets a pointer to the element with a given index, returning `nullptr` if the index is outside the range. + * + * @tparam T The type of the array. + * @param items The array. + * @param index The index of the array element to retrieve. + * @return A pointer to the requested element, or `nullptr` if the index is invalid. + */ + template + static const T* getSafe(const std::vector* pItems, int32_t index) { + if (index < 0 || static_cast(index) >= pItems->size()) { + return nullptr; + } else { + return &(*pItems)[index]; + } + } + + /** + * @brief Safely gets a pointer to the element with a given index, returning `nullptr` if the index is outside the range. + * + * @tparam T The type of the array. + * @param items The array. + * @param index The index of the array element to retrieve. + * @return A pointer to the requested element, or `nullptr` if the index is invalid. + */ + template + static T* getSafe(std::vector* pItems, int32_t index) { + if (index < 0 || static_cast(index) >= pItems->size()) { + return nullptr; + } else { + return &(*pItems)[index]; + } + } +} diff --git a/CesiumGltf/src/Helpers.cpp b/CesiumGltf/src/Helpers.cpp new file mode 100644 index 000000000..56b683b84 --- /dev/null +++ b/CesiumGltf/src/Helpers.cpp @@ -0,0 +1,51 @@ +#include "CesiumGltf/Helpers.h" +#include "CesiumGltf/BufferView.h" + +namespace CesiumGltf { + +int8_t computeNumberOfComponents(CesiumGltf::Accessor::Type type) { + switch (type) { + case CesiumGltf::Accessor::Type::SCALAR: + return 1; + case CesiumGltf::Accessor::Type::VEC2: + return 2; + case CesiumGltf::Accessor::Type::VEC3: + return 3; + case CesiumGltf::Accessor::Type::VEC4: + return 4; + case CesiumGltf::Accessor::Type::MAT2: + return 4; + case CesiumGltf::Accessor::Type::MAT3: + return 9; + case CesiumGltf::Accessor::Type::MAT4: + return 16; + default: + return 0; + } +} + +int8_t computeByteSizeOfComponent(CesiumGltf::Accessor::ComponentType componentType) { + switch (componentType) { + case CesiumGltf::Accessor::ComponentType::BYTE: + case CesiumGltf::Accessor::ComponentType::UNSIGNED_BYTE: + return 1; + case CesiumGltf::Accessor::ComponentType::SHORT: + case CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT: + return 2; + case CesiumGltf::Accessor::ComponentType::UNSIGNED_INT: + case CesiumGltf::Accessor::ComponentType::FLOAT: + return 4; + default: + return 0; + } +} + +int64_t computeByteStride(const CesiumGltf::Accessor& accessor, const CesiumGltf::BufferView& bufferView) { + if (bufferView.byteStride <= 0) { + return computeNumberOfComponents(accessor.type) * computeByteSizeOfComponent(accessor.componentType); + } else { + return bufferView.byteStride; + } +} + +} \ No newline at end of file diff --git a/CesiumGltfReader/CMakeLists.txt b/CesiumGltfReader/CMakeLists.txt index 511485a07..fc4985c49 100644 --- a/CesiumGltfReader/CMakeLists.txt +++ b/CesiumGltfReader/CMakeLists.txt @@ -17,6 +17,10 @@ target_include_directories( CesiumGltfReader SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../extern/rapidjson/include + + # Draco's CMake doesn't use target_include_directories, so we need to manually add draco's include dirs here. + ${CMAKE_CURRENT_SOURCE_DIR}/../extern/draco/src + ${CMAKE_BINARY_DIR} PUBLIC include PRIVATE @@ -25,4 +29,4 @@ target_include_directories( generated ) -target_link_libraries(CesiumGltfReader PUBLIC CesiumGltf GSL) +target_link_libraries(CesiumGltfReader PUBLIC CesiumGltf GSL draco) diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index e8fba3463..44d0532bd 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -1,6 +1,7 @@ #include "CesiumGltf/Reader.h" #include "JsonHandler.h" #include "ModelJsonHandler.h" +#include "decodeDraco.h" #include #include @@ -290,7 +291,10 @@ namespace { // } - void postprocess(Model& /* model */, const ReadModelOptions& /* options */) { + void postprocess(ModelReaderResult& readModel, const ReadModelOptions& options) { + if (options.decodeDraco) { + decodeDraco(readModel); + } // if (options.decodeEmbeddedImages) { // for (Image& image : model.images) { // const BufferView& bufferView = getSafe(model.bufferViews, image.bufferView); @@ -310,7 +314,7 @@ ModelReaderResult CesiumGltf::readModel(const gsl::span& data, co ModelReaderResult result = isBinaryGltf(data) ? readBinaryModel(data) : readJsonModel(data); if (result.model) { - postprocess(result.model.value(), options); + postprocess(result, options); } return result; diff --git a/CesiumGltfReader/src/decodeDraco.cpp b/CesiumGltfReader/src/decodeDraco.cpp new file mode 100644 index 000000000..05339a093 --- /dev/null +++ b/CesiumGltfReader/src/decodeDraco.cpp @@ -0,0 +1,347 @@ +#include "decodeDraco.h" +#include "CesiumGltf/Model.h" +#include "CesiumGltf/KHR_draco_mesh_compression.h" +#include "CesiumGltf/Reader.h" +#include "CesiumGltf/Helpers.h" +#include + +#pragma warning(push) +#pragma warning(disable:4127) +#include +#include +#pragma warning(pop) + + +namespace { + using namespace CesiumGltf; + + std::unique_ptr decodeBufferViewToDracoMesh( + ModelReaderResult& readModel, + MeshPrimitive& /* primitive */, + KHR_draco_mesh_compression& draco + ) { + Model& model = readModel.model.value(); + + if (draco.bufferView < 0 || draco.bufferView >= model.bufferViews.size()) { + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "Draco bufferView index is invalid."; + return nullptr; + } + + BufferView& bufferView = model.bufferViews[draco.bufferView]; + + if (bufferView.buffer < 0 || bufferView.buffer >= model.buffers.size()) { + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "Draco bufferView has an invalid buffer index."; + return nullptr; + } + + Buffer& buffer = model.buffers[bufferView.buffer]; + + if (bufferView.byteOffset < 0 || bufferView.byteLength < 0 || bufferView.byteOffset + bufferView.byteLength > static_cast(buffer.cesium.data.size())) { + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "Draco bufferView extends beyond its buffer."; + return nullptr; + } + + gsl::span data(buffer.cesium.data.data() + bufferView.byteOffset, bufferView.byteLength); + + draco::DecoderBuffer decodeBuffer; + decodeBuffer.Init(reinterpret_cast(data.data()), data.size()); + + draco::Decoder decoder; + draco::Mesh mesh; + draco::StatusOr> result = decoder.DecodeMeshFromBuffer(&decodeBuffer); + if (!result.ok()) { + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "Draco decoding failed: "; + readModel.warnings += result.status().error_msg_string(); + return nullptr; + } + + return std::move(result).value(); + } + + template + void copyData(const TSource* pSource, TDestination* pDestination, int64_t length) { + std::transform(pSource, pSource + length, pDestination, [](auto x) { return static_cast(x); }); + } + + template + void copyData(const T* pSource, T* pDestination, int64_t length) { + std::copy(pSource, pSource + length, pDestination); + } + + void copyDecodedIndices( + ModelReaderResult& readModel, + MeshPrimitive& primitive, + draco::Mesh* pMesh + ) { + Model& model = readModel.model.value(); + + if (primitive.indices < 0) { + return; + } + + Accessor* pIndicesAccessor = getSafe(&model.accessors, primitive.indices); + if (!pIndicesAccessor) { + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "Primitive indices accessor ID is invalid."; + return; + } + + if (pIndicesAccessor->count > pMesh->num_faces() * 3) { + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "There are fewer decoded Draco indices than are expected by the accessor."; + + pIndicesAccessor->count = pMesh->num_faces() * 3; + } + + pIndicesAccessor->bufferView = static_cast(model.bufferViews.size()); + BufferView& indicesBufferView = model.bufferViews.emplace_back(); + + indicesBufferView.buffer = static_cast(model.buffers.size()); + Buffer& indicesBuffer = model.buffers.emplace_back(); + + int64_t indexBytes = computeByteSizeOfComponent(pIndicesAccessor->componentType); + int64_t indicesBytes = pIndicesAccessor->count * indexBytes; + + indicesBuffer.cesium.data.resize(indicesBytes); + indicesBuffer.byteLength = indicesBytes; + indicesBufferView.byteLength = indicesBytes; + indicesBufferView.byteStride = indexBytes; + indicesBufferView.byteOffset = 0; + indicesBufferView.target = BufferView::Target::ELEMENT_ARRAY_BUFFER; + pIndicesAccessor->type = Accessor::Type::SCALAR; + + static_assert(sizeof(draco::PointIndex) == sizeof(uint32_t)); + + const uint32_t* pSourceIndices = reinterpret_cast(&pMesh->face(draco::FaceIndex(0))[0]); + + switch (pIndicesAccessor->componentType) { + case Accessor::ComponentType::BYTE: + copyData(pSourceIndices, reinterpret_cast(indicesBuffer.cesium.data.data()), pIndicesAccessor->count); + break; + case Accessor::ComponentType::UNSIGNED_BYTE: + copyData(pSourceIndices, reinterpret_cast(indicesBuffer.cesium.data.data()), pIndicesAccessor->count); + break; + case Accessor::ComponentType::SHORT: + copyData(pSourceIndices, reinterpret_cast(indicesBuffer.cesium.data.data()), pIndicesAccessor->count); + break; + case Accessor::ComponentType::UNSIGNED_SHORT: + copyData(pSourceIndices, reinterpret_cast(indicesBuffer.cesium.data.data()), pIndicesAccessor->count); + break; + case Accessor::ComponentType::UNSIGNED_INT: + copyData(pSourceIndices, reinterpret_cast(indicesBuffer.cesium.data.data()), pIndicesAccessor->count); + break; + case Accessor::ComponentType::FLOAT: + copyData(pSourceIndices, reinterpret_cast(indicesBuffer.cesium.data.data()), pIndicesAccessor->count); + break; + } + } + + void copyDecodedAttribute( + ModelReaderResult& readModel, + MeshPrimitive& /* primitive */, + Accessor* pAccessor, + const draco::Mesh* pMesh, + const draco::PointAttribute* pAttribute + ) { + Model& model = readModel.model.value(); + + switch (pAttribute->data_type()) { + case draco::DataType::DT_INT8: + pAccessor->componentType = Accessor::ComponentType::BYTE; + break; + case draco::DataType::DT_UINT8: + pAccessor->componentType = Accessor::ComponentType::UNSIGNED_BYTE; + break; + case draco::DataType::DT_INT16: + pAccessor->componentType = Accessor::ComponentType::SHORT; + break; + case draco::DataType::DT_UINT16: + pAccessor->componentType = Accessor::ComponentType::UNSIGNED_SHORT; + break; + case draco::DataType::DT_UINT32: + pAccessor->componentType = Accessor::ComponentType::UNSIGNED_INT; + break; + case draco::DataType::DT_FLOAT32: + pAccessor->componentType = Accessor::ComponentType::FLOAT; + break; + default: + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "Unsupported Draco data type: " + std::to_string(pAttribute->data_type()); + return; + } + + switch (pAttribute->num_components()) { + case 1: + pAccessor->type = Accessor::Type::SCALAR; + break; + case 2: + pAccessor->type = Accessor::Type::VEC2; + break; + case 3: + pAccessor->type = Accessor::Type::VEC3; + break; + case 4: + // Could be a vector or a matrix. If the accessor is already one of those, keep it. + // Otherwise go with VEC4. + pAccessor->type = + pAccessor->type == Accessor::Type::VEC4 || pAccessor->type == Accessor::Type::MAT2 + ? pAccessor->type + : Accessor::Type::VEC4; + break; + case 9: + pAccessor->type = Accessor::Type::MAT3; + break; + case 16: + pAccessor->type = Accessor::Type::MAT4; + break; + default: + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "Unsupported number of components for Draco attribute: " + std::to_string(pAttribute->num_components()); + return; + } + + if (pAccessor->count > pMesh->num_points()) { + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "There are fewer decoded Draco indices than are expected by the accessor."; + + pAccessor->count = pMesh->num_points(); + } + + pAccessor->bufferView = static_cast(model.bufferViews.size()); + BufferView& bufferView = model.bufferViews.emplace_back(); + + bufferView.buffer = static_cast(model.buffers.size()); + Buffer& buffer = model.buffers.emplace_back(); + + int64_t stride = computeNumberOfComponents(pAccessor->type) * computeByteSizeOfComponent(pAccessor->componentType); + int64_t sizeBytes = pAccessor->count * stride; + + buffer.cesium.data.resize(sizeBytes); + buffer.byteLength = sizeBytes; + bufferView.byteLength = sizeBytes; + bufferView.byteStride = stride; + bufferView.byteOffset = 0; + pAccessor->byteOffset = 0; + + auto doCopy = [pMesh, pAttribute](auto pOut) { + for (draco::PointIndex i(0); i < pMesh->num_points(); ++i) { + draco::AttributeValueIndex valueIndex = pAttribute->mapped_index(i); + if (!pAttribute->ConvertValue(valueIndex, pOut)) { + } + + pOut += pAttribute->num_components(); + } + }; + + switch (pAccessor->componentType) { + case Accessor::ComponentType::BYTE: + doCopy(reinterpret_cast(buffer.cesium.data.data())); + break; + case Accessor::ComponentType::UNSIGNED_BYTE: + doCopy(reinterpret_cast(buffer.cesium.data.data())); + break; + case Accessor::ComponentType::SHORT: + doCopy(reinterpret_cast(buffer.cesium.data.data())); + break; + case Accessor::ComponentType::UNSIGNED_SHORT: + doCopy(reinterpret_cast(buffer.cesium.data.data())); + break; + case Accessor::ComponentType::UNSIGNED_INT: + doCopy(reinterpret_cast(buffer.cesium.data.data())); + break; + case Accessor::ComponentType::FLOAT: + doCopy(reinterpret_cast(buffer.cesium.data.data())); + break; + } + } + + void decodePrimitive( + ModelReaderResult& readModel, + MeshPrimitive& primitive, + KHR_draco_mesh_compression& draco, + std::unordered_map>& bufferViewToMesh + ) { + Model& model = readModel.model.value(); + + draco::Mesh* pMesh; + + auto cachedIt = bufferViewToMesh.find(draco.bufferView); + if (cachedIt != bufferViewToMesh.end()) { + pMesh = cachedIt->second.get(); + } else { + std::unique_ptr pNewMesh = decodeBufferViewToDracoMesh(readModel, primitive, draco); + if (!pNewMesh) { + return; + } + + pMesh = pNewMesh.get(); + bufferViewToMesh.emplace(draco.bufferView, std::move(pNewMesh)); + } + + copyDecodedIndices(readModel, primitive, pMesh); + + for (const std::pair& attribute : draco.attributes) { + auto primitiveAttrIt = primitive.attributes.find(attribute.first); + if (primitiveAttrIt == primitive.attributes.end()) { + // The primitive does not use this attribute. The KHR_draco_mesh_compression spec + // says this shouldn't happen, so warn. + if (!readModel.warnings.empty()) { + readModel.warnings += "\n"; + } + readModel.warnings += "Draco extension has the " + attribute.first + " attribute, but the primitive does not have that attribute."; + continue; + } + + int32_t primitiveAttrIndex = primitiveAttrIt->second; + Accessor* pAccessor = getSafe(&model.accessors, primitiveAttrIndex); + if (!pAccessor) { + if (!readModel.warnings.empty()) { + readModel.warnings += "\n"; + } + readModel.warnings += "Primitive attribute's accessor index is invalid."; + continue; + } + + int32_t dracoAttrIndex = attribute.second; + const draco::PointAttribute* pAttribute = pMesh->GetAttributeByUniqueId(dracoAttrIndex); + if (pAttribute == nullptr) { + if (!readModel.warnings.empty()) { + readModel.warnings += "\n"; + } + readModel.warnings += "Draco attribute with unique ID " + std::to_string(dracoAttrIndex) + " does not exist."; + continue; + } + + copyDecodedAttribute(readModel, primitive, pAccessor, pMesh, pAttribute); + } + } +} + +namespace CesiumGltf { + +void decodeDraco(CesiumGltf::ModelReaderResult& readModel) { + if (!readModel.model) { + return; + } + + Model& model = readModel.model.value(); + + std::unordered_map> bufferViewToMesh; + + for (Mesh& mesh : model.meshes) { + for (MeshPrimitive& primitive : mesh.primitives) { + KHR_draco_mesh_compression* pDraco = primitive.getExtension(); + if (!pDraco) { + continue; + } + + decodePrimitive(readModel, primitive, *pDraco, bufferViewToMesh); + } + } +} + +} \ No newline at end of file diff --git a/CesiumGltfReader/src/decodeDraco.h b/CesiumGltfReader/src/decodeDraco.h new file mode 100644 index 000000000..d925e1939 --- /dev/null +++ b/CesiumGltfReader/src/decodeDraco.h @@ -0,0 +1,7 @@ +#pragma once + +namespace CesiumGltf { + struct ModelReaderResult; + + void decodeDraco(ModelReaderResult& readModel); +} From c999c7628bee774317f99f9b0ec8804afb144e8d Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Tue, 12 Jan 2021 21:57:42 +1100 Subject: [PATCH 32/61] Load embedded images. --- CesiumGltf/include/CesiumGltf/Helpers.h | 2 +- CesiumGltfReader/src/Reader.cpp | 49 ++++++++++++------------- CesiumGltfReader/src/decodeDraco.cpp | 4 +- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/CesiumGltf/include/CesiumGltf/Helpers.h b/CesiumGltf/include/CesiumGltf/Helpers.h index c2577a542..b37d8d638 100644 --- a/CesiumGltf/include/CesiumGltf/Helpers.h +++ b/CesiumGltf/include/CesiumGltf/Helpers.h @@ -50,7 +50,7 @@ namespace CesiumGltf { template static const T& getSafe(const std::vector& items, int32_t index) { static T default; - if (index < 0 || static_cast(index) >= pItems->size()) { + if (index < 0 || static_cast(index) >= items.size()) { return default; } else { return items[index]; diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 44d0532bd..45368815b 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -1,3 +1,4 @@ +#include "CesiumGltf/Helpers.h" #include "CesiumGltf/Reader.h" #include "JsonHandler.h" #include "ModelJsonHandler.h" @@ -277,36 +278,32 @@ namespace { return result; } - // template - // const T& getSafe(const std::vector& items, int64_t index) { - // static T default; - // if (index < 0 || index >= static_cast(items.size())) { - // return default; - // } else { - // return items[index]; - // } - // } - - // gsl::span safeSubspan(const gsl::span& s, int64_t offset, int64_t count) { - - // } - void postprocess(ModelReaderResult& readModel, const ReadModelOptions& options) { + Model& model = readModel.model.value(); + + if (options.decodeEmbeddedImages) { + for (Image& image : model.images) { + const BufferView& bufferView = getSafe(model.bufferViews, image.bufferView); + const Buffer& buffer = getSafe(model.buffers, bufferView.buffer); + + if (bufferView.byteOffset + bufferView.byteLength > static_cast(buffer.cesium.data.size())) { + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "Image bufferView's byteLength is more than the available bytes."; + continue; + } + + gsl::span bufferSpan(buffer.cesium.data); + gsl::span bufferViewSpan = bufferSpan.subspan(bufferView.byteOffset, bufferView.byteLength); + ImageReaderResult imageResult = readImage(bufferViewSpan); + if (imageResult.image) { + image.cesium = std::move(imageResult.image.value()); + } + } + } + if (options.decodeDraco) { decodeDraco(readModel); } - // if (options.decodeEmbeddedImages) { - // for (Image& image : model.images) { - // const BufferView& bufferView = getSafe(model.bufferViews, image.bufferView); - // const Buffer& buffer = getSafe(model.buffers, bufferView.buffer); - // if (buffer.cesium.data.size() == 0) { - // continue; - // } - - // gsl::span bufferSpan(buffer.cesium.data); - // bufferSpan.subspan() - // } - // } } } diff --git a/CesiumGltfReader/src/decodeDraco.cpp b/CesiumGltfReader/src/decodeDraco.cpp index 05339a093..e6f630166 100644 --- a/CesiumGltfReader/src/decodeDraco.cpp +++ b/CesiumGltfReader/src/decodeDraco.cpp @@ -230,9 +230,7 @@ namespace { auto doCopy = [pMesh, pAttribute](auto pOut) { for (draco::PointIndex i(0); i < pMesh->num_points(); ++i) { draco::AttributeValueIndex valueIndex = pAttribute->mapped_index(i); - if (!pAttribute->ConvertValue(valueIndex, pOut)) { - } - + pAttribute->ConvertValue(valueIndex, pOut); pOut += pAttribute->num_components(); } }; From e28f181d6cb5e6da3decc8d9861af0c80ecd016a Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 13 Jan 2021 15:50:48 +1100 Subject: [PATCH 33/61] Remove unnecessary map. --- CesiumGltfReader/src/decodeDraco.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/CesiumGltfReader/src/decodeDraco.cpp b/CesiumGltfReader/src/decodeDraco.cpp index e6f630166..5e86b468c 100644 --- a/CesiumGltfReader/src/decodeDraco.cpp +++ b/CesiumGltfReader/src/decodeDraco.cpp @@ -328,8 +328,6 @@ void decodeDraco(CesiumGltf::ModelReaderResult& readModel) { Model& model = readModel.model.value(); - std::unordered_map> bufferViewToMesh; - for (Mesh& mesh : model.meshes) { for (MeshPrimitive& primitive : mesh.primitives) { KHR_draco_mesh_compression* pDraco = primitive.getExtension(); From cc973071ad3b1a4e74d8ea774afc0fbd706dd04f Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 13 Jan 2021 15:55:46 +1100 Subject: [PATCH 34/61] Cleanup. --- CesiumGltfReader/src/decodeDraco.cpp | 91 +++++----------------------- 1 file changed, 15 insertions(+), 76 deletions(-) diff --git a/CesiumGltfReader/src/decodeDraco.cpp b/CesiumGltfReader/src/decodeDraco.cpp index 5e86b468c..84a9ba804 100644 --- a/CesiumGltfReader/src/decodeDraco.cpp +++ b/CesiumGltfReader/src/decodeDraco.cpp @@ -149,61 +149,6 @@ namespace { ) { Model& model = readModel.model.value(); - switch (pAttribute->data_type()) { - case draco::DataType::DT_INT8: - pAccessor->componentType = Accessor::ComponentType::BYTE; - break; - case draco::DataType::DT_UINT8: - pAccessor->componentType = Accessor::ComponentType::UNSIGNED_BYTE; - break; - case draco::DataType::DT_INT16: - pAccessor->componentType = Accessor::ComponentType::SHORT; - break; - case draco::DataType::DT_UINT16: - pAccessor->componentType = Accessor::ComponentType::UNSIGNED_SHORT; - break; - case draco::DataType::DT_UINT32: - pAccessor->componentType = Accessor::ComponentType::UNSIGNED_INT; - break; - case draco::DataType::DT_FLOAT32: - pAccessor->componentType = Accessor::ComponentType::FLOAT; - break; - default: - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "Unsupported Draco data type: " + std::to_string(pAttribute->data_type()); - return; - } - - switch (pAttribute->num_components()) { - case 1: - pAccessor->type = Accessor::Type::SCALAR; - break; - case 2: - pAccessor->type = Accessor::Type::VEC2; - break; - case 3: - pAccessor->type = Accessor::Type::VEC3; - break; - case 4: - // Could be a vector or a matrix. If the accessor is already one of those, keep it. - // Otherwise go with VEC4. - pAccessor->type = - pAccessor->type == Accessor::Type::VEC4 || pAccessor->type == Accessor::Type::MAT2 - ? pAccessor->type - : Accessor::Type::VEC4; - break; - case 9: - pAccessor->type = Accessor::Type::MAT3; - break; - case 16: - pAccessor->type = Accessor::Type::MAT4; - break; - default: - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "Unsupported number of components for Draco attribute: " + std::to_string(pAttribute->num_components()); - return; - } - if (pAccessor->count > pMesh->num_points()) { if (!readModel.warnings.empty()) readModel.warnings += "\n"; readModel.warnings += "There are fewer decoded Draco indices than are expected by the accessor."; @@ -217,7 +162,8 @@ namespace { bufferView.buffer = static_cast(model.buffers.size()); Buffer& buffer = model.buffers.emplace_back(); - int64_t stride = computeNumberOfComponents(pAccessor->type) * computeByteSizeOfComponent(pAccessor->componentType); + int8_t numberOfComponents = computeNumberOfComponents(pAccessor->type); + int64_t stride = numberOfComponents * computeByteSizeOfComponent(pAccessor->componentType); int64_t sizeBytes = pAccessor->count * stride; buffer.cesium.data.resize(sizeBytes); @@ -227,10 +173,10 @@ namespace { bufferView.byteOffset = 0; pAccessor->byteOffset = 0; - auto doCopy = [pMesh, pAttribute](auto pOut) { + auto doCopy = [pMesh, pAttribute, numberOfComponents](auto pOut) { for (draco::PointIndex i(0); i < pMesh->num_points(); ++i) { draco::AttributeValueIndex valueIndex = pAttribute->mapped_index(i); - pAttribute->ConvertValue(valueIndex, pOut); + pAttribute->ConvertValue(valueIndex, numberOfComponents, pOut); pOut += pAttribute->num_components(); } }; @@ -254,33 +200,26 @@ namespace { case Accessor::ComponentType::FLOAT: doCopy(reinterpret_cast(buffer.cesium.data.data())); break; + default: + if (!readModel.warnings.empty()) readModel.warnings += "\n"; + readModel.warnings += "Accessor uses an unknown componentType: " + std::to_string(int32_t(pAccessor->componentType)); + break; } } void decodePrimitive( ModelReaderResult& readModel, MeshPrimitive& primitive, - KHR_draco_mesh_compression& draco, - std::unordered_map>& bufferViewToMesh + KHR_draco_mesh_compression& draco ) { Model& model = readModel.model.value(); - draco::Mesh* pMesh; - - auto cachedIt = bufferViewToMesh.find(draco.bufferView); - if (cachedIt != bufferViewToMesh.end()) { - pMesh = cachedIt->second.get(); - } else { - std::unique_ptr pNewMesh = decodeBufferViewToDracoMesh(readModel, primitive, draco); - if (!pNewMesh) { - return; - } - - pMesh = pNewMesh.get(); - bufferViewToMesh.emplace(draco.bufferView, std::move(pNewMesh)); + std::unique_ptr pMesh = decodeBufferViewToDracoMesh(readModel, primitive, draco); + if (!pMesh) { + return; } - copyDecodedIndices(readModel, primitive, pMesh); + copyDecodedIndices(readModel, primitive, pMesh.get()); for (const std::pair& attribute : draco.attributes) { auto primitiveAttrIt = primitive.attributes.find(attribute.first); @@ -314,7 +253,7 @@ namespace { continue; } - copyDecodedAttribute(readModel, primitive, pAccessor, pMesh, pAttribute); + copyDecodedAttribute(readModel, primitive, pAccessor, pMesh.get(), pAttribute); } } } @@ -335,7 +274,7 @@ void decodeDraco(CesiumGltf::ModelReaderResult& readModel) { continue; } - decodePrimitive(readModel, primitive, *pDraco, bufferViewToMesh); + decodePrimitive(readModel, primitive, *pDraco); } } } From 082087551ec10ae322550d86f37039f93542b12a Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 13 Jan 2021 17:16:06 +1100 Subject: [PATCH 35/61] Default glTF IDs to -1. --- CesiumGltf/include/CesiumGltf/Accessor.h | 2 +- CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h | 2 +- CesiumGltf/include/CesiumGltf/AccessorSparseValues.h | 2 +- CesiumGltf/include/CesiumGltf/AnimationChannel.h | 2 +- CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h | 2 +- CesiumGltf/include/CesiumGltf/AnimationSampler.h | 4 ++-- CesiumGltf/include/CesiumGltf/BufferView.h | 2 +- CesiumGltf/include/CesiumGltf/Image.h | 2 +- .../include/CesiumGltf/KHR_draco_mesh_compression.h | 2 +- CesiumGltf/include/CesiumGltf/MeshPrimitive.h | 4 ++-- CesiumGltf/include/CesiumGltf/Model.h | 2 +- CesiumGltf/include/CesiumGltf/Node.h | 6 +++--- CesiumGltf/include/CesiumGltf/Skin.h | 4 ++-- CesiumGltf/include/CesiumGltf/Texture.h | 4 ++-- CesiumGltf/include/CesiumGltf/TextureInfo.h | 2 +- tools/generate-gltf-classes/generate.js | 8 +++++++- tools/generate-gltf-classes/resolveProperty.js | 2 ++ 17 files changed, 30 insertions(+), 22 deletions(-) diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index d09a1633f..7ee6a678c 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -47,7 +47,7 @@ namespace CesiumGltf { * * When not defined, accessor must be initialized with zeros; `sparse` property or extensions could override zeros with actual values. */ - int32_t bufferView; + int32_t bufferView = -1; /** * @brief The offset relative to the start of the bufferView in bytes. diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h index fa691f3cd..fd1915a5e 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h @@ -21,7 +21,7 @@ namespace CesiumGltf { /** * @brief The index of the bufferView with sparse indices. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target. */ - int32_t bufferView; + int32_t bufferView = -1; /** * @brief The offset relative to the start of the bufferView in bytes. Must be aligned. diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h index a62d1bc90..de6d9ea89 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h @@ -14,7 +14,7 @@ namespace CesiumGltf { /** * @brief The index of the bufferView with sparse values. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target. */ - int32_t bufferView; + int32_t bufferView = -1; /** * @brief The offset relative to the start of the bufferView in bytes. Must be aligned. diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannel.h b/CesiumGltf/include/CesiumGltf/AnimationChannel.h index 126306e74..0c3484c20 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationChannel.h +++ b/CesiumGltf/include/CesiumGltf/AnimationChannel.h @@ -17,7 +17,7 @@ namespace CesiumGltf { * * The index of a sampler in this animation used to compute the value for the target, e.g., a node's translation, rotation, or scale (TRS). */ - int32_t sampler; + int32_t sampler = -1; /** * @brief The index of the node and TRS property to target. diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h index 046dd89bb..9f4389b44 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h +++ b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h @@ -23,7 +23,7 @@ namespace CesiumGltf { /** * @brief The index of the node to target. */ - int32_t node; + int32_t node = -1; /** * @brief The name of the node's TRS property to modify, or the "weights" of the Morph Targets it instantiates. For the "translation" property, the values that are provided by the sampler are the translation along the x, y, and z axes. For the "rotation" property, the values are a quaternion in the order (x, y, z, w), where w is the scalar. For the "scale" property, the values are the scaling factors along the x, y, and z axes. diff --git a/CesiumGltf/include/CesiumGltf/AnimationSampler.h b/CesiumGltf/include/CesiumGltf/AnimationSampler.h index 91716d0d6..c150973ad 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationSampler.h +++ b/CesiumGltf/include/CesiumGltf/AnimationSampler.h @@ -23,7 +23,7 @@ namespace CesiumGltf { * * That accessor must have componentType `FLOAT`. The values represent time in seconds with `time[0] >= 0.0`, and strictly increasing values, i.e., `time[n + 1] > time[n]`. */ - int32_t input; + int32_t input = -1; /** * @brief Interpolation algorithm. @@ -35,7 +35,7 @@ namespace CesiumGltf { * * The index of an accessor containing keyframe output values. When targeting translation or scale paths, the `accessor.componentType` of the output values must be `FLOAT`. When targeting rotation or morph weights, the `accessor.componentType` of the output values must be `FLOAT` or normalized integer. For weights, each output element stores `SCALAR` values with a count equal to the number of morph targets. */ - int32_t output; + int32_t output = -1; }; } diff --git a/CesiumGltf/include/CesiumGltf/BufferView.h b/CesiumGltf/include/CesiumGltf/BufferView.h index 0e8eec307..f970cbf05 100644 --- a/CesiumGltf/include/CesiumGltf/BufferView.h +++ b/CesiumGltf/include/CesiumGltf/BufferView.h @@ -19,7 +19,7 @@ namespace CesiumGltf { /** * @brief The index of the buffer. */ - int32_t buffer; + int32_t buffer = -1; /** * @brief The offset into the buffer in bytes. diff --git a/CesiumGltf/include/CesiumGltf/Image.h b/CesiumGltf/include/CesiumGltf/Image.h index e9f29ac2d..22097b1f5 100644 --- a/CesiumGltf/include/CesiumGltf/Image.h +++ b/CesiumGltf/include/CesiumGltf/Image.h @@ -33,7 +33,7 @@ namespace CesiumGltf { /** * @brief The index of the bufferView that contains the image. Use this instead of the image's uri property. */ - int32_t bufferView; + int32_t bufferView = -1; /** * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. diff --git a/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h b/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h index 015990699..eed688e17 100644 --- a/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h +++ b/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h @@ -15,7 +15,7 @@ namespace CesiumGltf { /** * @brief The index of the bufferView. */ - int32_t bufferView; + int32_t bufferView = -1; /** * @brief A dictionary object, where each key corresponds to an attribute and its unique attribute id stored in the compressed geometry. diff --git a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h index 4f0bae603..a62f6a5ba 100644 --- a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h +++ b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h @@ -38,12 +38,12 @@ namespace CesiumGltf { * * The index of the accessor that contains mesh indices. When this is not defined, the primitives should be rendered without indices using `drawArrays()`. When defined, the accessor must contain indices: the `bufferView` referenced by the accessor should have a `target` equal to 34963 (ELEMENT_ARRAY_BUFFER); `componentType` must be 5121 (UNSIGNED_BYTE), 5123 (UNSIGNED_SHORT) or 5125 (UNSIGNED_INT), the latter may require enabling additional hardware support; `type` must be `"SCALAR"`. For triangle primitives, the front face has a counter-clockwise (CCW) winding order. Values of the index accessor must not include the maximum value for the given component type, which triggers primitive restart in several graphics APIs and would require client implementations to rebuild the index buffer. Primitive restart values are disallowed and all index values must refer to actual vertices. As a result, the index accessor's values must not exceed the following maxima: BYTE `< 255`, UNSIGNED_SHORT `< 65535`, UNSIGNED_INT `< 4294967295`. */ - int32_t indices; + int32_t indices = -1; /** * @brief The index of the material to apply to this primitive when rendering. */ - int32_t material; + int32_t material = -1; /** * @brief The type of primitives to render. diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index b6cffa30b..57374f7dc 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -111,7 +111,7 @@ namespace CesiumGltf { /** * @brief The index of the default scene. */ - int32_t scene; + int32_t scene = -1; /** * @brief An array of scenes. diff --git a/CesiumGltf/include/CesiumGltf/Node.h b/CesiumGltf/include/CesiumGltf/Node.h index a18d31aea..8ef9f0150 100644 --- a/CesiumGltf/include/CesiumGltf/Node.h +++ b/CesiumGltf/include/CesiumGltf/Node.h @@ -15,7 +15,7 @@ namespace CesiumGltf { /** * @brief The index of the camera referenced by this node. */ - int32_t camera; + int32_t camera = -1; /** * @brief The indices of this node's children. @@ -27,7 +27,7 @@ namespace CesiumGltf { * * When a skin is referenced by a node within a scene, all joints used by the skin must belong to the same scene. */ - int32_t skin; + int32_t skin = -1; /** * @brief A floating-point 4x4 transformation matrix stored in column-major order. @@ -37,7 +37,7 @@ namespace CesiumGltf { /** * @brief The index of the mesh in this node. */ - int32_t mesh; + int32_t mesh = -1; /** * @brief The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar. diff --git a/CesiumGltf/include/CesiumGltf/Skin.h b/CesiumGltf/include/CesiumGltf/Skin.h index 331bca601..f69c1b460 100644 --- a/CesiumGltf/include/CesiumGltf/Skin.h +++ b/CesiumGltf/include/CesiumGltf/Skin.h @@ -15,14 +15,14 @@ namespace CesiumGltf { /** * @brief The index of the accessor containing the floating-point 4x4 inverse-bind matrices. The default is that each matrix is a 4x4 identity matrix, which implies that inverse-bind matrices were pre-applied. */ - int32_t inverseBindMatrices; + int32_t inverseBindMatrices = -1; /** * @brief The index of the node used as a skeleton root. * * The node must be the closest common root of the joints hierarchy or a direct or indirect parent node of the closest common root. */ - int32_t skeleton; + int32_t skeleton = -1; /** * @brief Indices of skeleton nodes, used as joints in this skin. diff --git a/CesiumGltf/include/CesiumGltf/Texture.h b/CesiumGltf/include/CesiumGltf/Texture.h index 2c8518a05..9767d3f37 100644 --- a/CesiumGltf/include/CesiumGltf/Texture.h +++ b/CesiumGltf/include/CesiumGltf/Texture.h @@ -14,12 +14,12 @@ namespace CesiumGltf { /** * @brief The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used. */ - int32_t sampler; + int32_t sampler = -1; /** * @brief The index of the image used by this texture. When undefined, it is expected that an extension or other mechanism will supply an alternate texture source, otherwise behavior is undefined. */ - int32_t source; + int32_t source = -1; }; } diff --git a/CesiumGltf/include/CesiumGltf/TextureInfo.h b/CesiumGltf/include/CesiumGltf/TextureInfo.h index 5cacd3f4d..f49285c78 100644 --- a/CesiumGltf/include/CesiumGltf/TextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/TextureInfo.h @@ -14,7 +14,7 @@ namespace CesiumGltf { /** * @brief The index of the texture. */ - int32_t index; + int32_t index = -1; /** * @brief The set index of texture's TEXCOORD attribute used for texture coordinate mapping. diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index ab86aa8c7..dccf81afc 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -205,7 +205,13 @@ function formatProperty(property) { result += ` */\n`; - result += `${property.type} ${property.name};`; + result += `${property.type} ${property.name}`; + + if (property.defaultValue && property.defaultValue.length > 0) { + result += " = " + property.defaultValue; + } + + result += ";"; return result; } diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index 2aa5d0baf..ac9ef7588 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -82,6 +82,7 @@ function resolveProperty( return { ...propertyDefaults(propertyName, propertyDetails), type: "int32_t", + defaultValue: "-1", headers: [""], readerHeaders: [`"IntegerJsonHandler.h"`], readerType: "IntegerJsonHandler", @@ -141,6 +142,7 @@ function propertyDefaults(propertyName, propertyDetails) { readerHeaders: [], readerHeadersImpl: [], type: "", + defaultValue: "", readerType: "", schemas: [], localTypes: [], From cb297c4db68f50915f82ce84147b4a6ebc304075 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 13 Jan 2021 17:47:08 +1100 Subject: [PATCH 36/61] More defaults. --- .../include/CesiumGltf/AnimationSampler.h | 2 +- CesiumGltf/include/CesiumGltf/Material.h | 6 +++--- .../CesiumGltf/MaterialNormalTextureInfo.h | 2 +- .../CesiumGltf/MaterialOcclusionTextureInfo.h | 2 +- .../CesiumGltf/MaterialPBRMetallicRoughness.h | 6 +++--- CesiumGltf/include/CesiumGltf/MeshPrimitive.h | 2 +- CesiumGltf/include/CesiumGltf/Node.h | 8 ++++---- CesiumGltf/include/CesiumGltf/Sampler.h | 4 ++-- tools/generate-gltf-classes/generate.js | 2 +- tools/generate-gltf-classes/resolveProperty.js | 18 ++++++++++++++++-- 10 files changed, 33 insertions(+), 19 deletions(-) diff --git a/CesiumGltf/include/CesiumGltf/AnimationSampler.h b/CesiumGltf/include/CesiumGltf/AnimationSampler.h index c150973ad..458ef00fb 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationSampler.h +++ b/CesiumGltf/include/CesiumGltf/AnimationSampler.h @@ -28,7 +28,7 @@ namespace CesiumGltf { /** * @brief Interpolation algorithm. */ - Interpolation interpolation; + Interpolation interpolation = Interpolation::LINEAR; /** * @brief The index of an accessor, containing keyframe output values. diff --git a/CesiumGltf/include/CesiumGltf/Material.h b/CesiumGltf/include/CesiumGltf/Material.h index 8ff89627f..c85420386 100644 --- a/CesiumGltf/include/CesiumGltf/Material.h +++ b/CesiumGltf/include/CesiumGltf/Material.h @@ -53,21 +53,21 @@ namespace CesiumGltf { * * The RGB components of the emissive color of the material. These values are linear. If an emissiveTexture is specified, this value is multiplied with the texel values. */ - std::vector emissiveFactor; + std::vector emissiveFactor = { 0,0,0 }; /** * @brief The alpha rendering mode of the material. * * The material's alpha rendering mode enumeration specifying the interpretation of the alpha value of the main factor and texture. */ - AlphaMode alphaMode; + AlphaMode alphaMode = AlphaMode::OPAQUE; /** * @brief The alpha cutoff value of the material. * * Specifies the cutoff threshold when in `MASK` mode. If the alpha value is greater than or equal to this value then it is rendered as fully opaque, otherwise, it is rendered as fully transparent. A value greater than 1.0 will render the entire material as fully transparent. This value is ignored for other modes. */ - double alphaCutoff; + double alphaCutoff = 0.5; /** * @brief Specifies whether the material is double sided. diff --git a/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h index 2b645ca32..8bf8dec38 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h @@ -15,7 +15,7 @@ namespace CesiumGltf { * * The scalar multiplier applied to each normal vector of the texture. This value scales the normal vector using the formula: `scaledNormal = normalize(( * 2.0 - 1.0) * vec3(, , 1.0))`. This value is ignored if normalTexture is not specified. This value is linear. */ - double scale; + double scale = 1; }; } diff --git a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h index cbba82b41..5875eada6 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h @@ -15,7 +15,7 @@ namespace CesiumGltf { * * A value of 0.0 means no occlusion. A value of 1.0 means full occlusion. This value affects the resulting color using the formula: `occludedColor = lerp(color, color * , )`. This value is ignored if the corresponding texture is not specified. This value is linear. */ - double strength; + double strength = 1; }; } diff --git a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h index c2f42bc04..ed0ceea61 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h +++ b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h @@ -17,7 +17,7 @@ namespace CesiumGltf { * * The RGBA components of the base color of the material. The fourth component (A) is the alpha coverage of the material. The `alphaMode` property specifies how alpha is interpreted. These values are linear. If a baseColorTexture is specified, this value is multiplied with the texel values. */ - std::vector baseColorFactor; + std::vector baseColorFactor = { 1,1,1,1 }; /** * @brief The base color texture. @@ -31,14 +31,14 @@ namespace CesiumGltf { * * A value of 1.0 means the material is a metal. A value of 0.0 means the material is a dielectric. Values in between are for blending between metals and dielectrics such as dirty metallic surfaces. This value is linear. If a metallicRoughnessTexture is specified, this value is multiplied with the metallic texel values. */ - double metallicFactor; + double metallicFactor = 1; /** * @brief The roughness of the material. * * A value of 1.0 means the material is completely rough. A value of 0.0 means the material is completely smooth. This value is linear. If a metallicRoughnessTexture is specified, this value is multiplied with the roughness texel values. */ - double roughnessFactor; + double roughnessFactor = 1; /** * @brief The metallic-roughness texture. diff --git a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h index a62f6a5ba..13ff0d94d 100644 --- a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h +++ b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h @@ -50,7 +50,7 @@ namespace CesiumGltf { * * All valid values correspond to WebGL enums. */ - Mode mode; + Mode mode = Mode(4); /** * @brief An array of Morph Targets, each Morph Target is a dictionary mapping attributes (only `POSITION`, `NORMAL`, and `TANGENT` supported) to their deviations in the Morph Target. diff --git a/CesiumGltf/include/CesiumGltf/Node.h b/CesiumGltf/include/CesiumGltf/Node.h index 8ef9f0150..ff9540cbb 100644 --- a/CesiumGltf/include/CesiumGltf/Node.h +++ b/CesiumGltf/include/CesiumGltf/Node.h @@ -32,7 +32,7 @@ namespace CesiumGltf { /** * @brief A floating-point 4x4 transformation matrix stored in column-major order. */ - std::vector matrix; + std::vector matrix = { 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1 }; /** * @brief The index of the mesh in this node. @@ -42,17 +42,17 @@ namespace CesiumGltf { /** * @brief The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar. */ - std::vector rotation; + std::vector rotation = { 0,0,0,1 }; /** * @brief The node's non-uniform scale, given as the scaling factors along the x, y, and z axes. */ - std::vector scale; + std::vector scale = { 1,1,1 }; /** * @brief The node's translation along the x, y, and z axes. */ - std::vector translation; + std::vector translation = { 0,0,0 }; /** * @brief The weights of the instantiated Morph Target. Number of elements must match number of Morph Targets of used mesh. diff --git a/CesiumGltf/include/CesiumGltf/Sampler.h b/CesiumGltf/include/CesiumGltf/Sampler.h index bebb10132..179bf6fa9 100644 --- a/CesiumGltf/include/CesiumGltf/Sampler.h +++ b/CesiumGltf/include/CesiumGltf/Sampler.h @@ -64,14 +64,14 @@ namespace CesiumGltf { * * S (U) wrapping mode. All valid values correspond to WebGL enums. */ - WrapS wrapS; + WrapS wrapS = WrapS(10497); /** * @brief t wrapping mode. * * T (V) wrapping mode. All valid values correspond to WebGL enums. */ - WrapT wrapT; + WrapT wrapT = WrapT(10497); }; } diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index dccf81afc..f2265bc3e 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -207,7 +207,7 @@ function formatProperty(property) { result += `${property.type} ${property.name}`; - if (property.defaultValue && property.defaultValue.length > 0) { + if (property.defaultValue !== undefined) { result += " = " + property.defaultValue; } diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index ac9ef7588..ff2d5f913 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -82,7 +82,7 @@ function resolveProperty( return { ...propertyDefaults(propertyName, propertyDetails), type: "int32_t", - defaultValue: "-1", + defaultValue: -1, headers: [""], readerHeaders: [`"IntegerJsonHandler.h"`], readerType: "IntegerJsonHandler", @@ -142,7 +142,7 @@ function propertyDefaults(propertyName, propertyDetails) { readerHeaders: [], readerHeadersImpl: [], type: "", - defaultValue: "", + defaultValue: propertyDetails.default ? propertyDetails.default.toString() : undefined, readerType: "", schemas: [], localTypes: [], @@ -179,6 +179,7 @@ function resolveArray( schemas: itemProperty.schemas, localTypes: itemProperty.localTypes, type: `std::vector<${itemProperty.type}>`, + defaultValue: propertyDetails.default ? `{ ${propertyDetails.default} }` : undefined, readerHeaders: [`"ArrayJsonHandler.h"`, ...itemProperty.readerHeaders], readerType: `ArrayJsonHandler<${itemProperty.type}, ${itemProperty.readerType}>`, }; @@ -256,6 +257,7 @@ function resolveEnum( `), ], type: enumName, + defaultValue: createEnumDefault(enumName, propertyDetails), readerHeaders: [`"CesiumGltf/${parentName}.h"`], readerLocalTypes: readerTypes, readerLocalTypesImpl: createEnumReaderTypeImpl( @@ -276,6 +278,18 @@ function resolveEnum( return result; } +function createEnumDefault(enumName, propertyDetails) { + if (propertyDetails.default === undefined) { + return undefined; + } + + if (propertyDetails.anyOf[0].type === "integer") { + return `${enumName}(${propertyDetails.default})`; + } else { + return `${enumName}::${propertyDetails.default}`; + } +} + function createEnum(enumDetails) { if (!enumDetails.enum || enumDetails.enum.length === 0) { return undefined; From edb8fe209b31ef778abfd1671d5ee56dea68c93b Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 14 Jan 2021 17:44:19 +1100 Subject: [PATCH 37/61] Add extras, reactivate support for RTC_CENTER. --- Cesium3DTiles/src/Batched3DModelContent.cpp | 43 +++---- .../include/CesiumGltf/ExtensibleObject.h | 8 ++ CesiumGltf/include/CesiumGltf/JsonValue.h | 67 ++++++++++ CesiumGltf/src/JsonValue.cpp | 30 +++++ CesiumGltfReader/src/DictionaryJsonHandler.h | 2 +- .../src/ExtensibleObjectJsonHandler.cpp | 8 +- .../src/ExtensibleObjectJsonHandler.h | 5 + .../src/JsonObjectJsonHandler.cpp | 118 ++++++++++++++++++ CesiumGltfReader/src/JsonObjectJsonHandler.h | 41 ++++++ 9 files changed, 294 insertions(+), 28 deletions(-) create mode 100644 CesiumGltf/include/CesiumGltf/JsonValue.h create mode 100644 CesiumGltf/src/JsonValue.cpp create mode 100644 CesiumGltfReader/src/JsonObjectJsonHandler.cpp create mode 100644 CesiumGltfReader/src/JsonObjectJsonHandler.h diff --git a/Cesium3DTiles/src/Batched3DModelContent.cpp b/Cesium3DTiles/src/Batched3DModelContent.cpp index 69a7e39e9..04be4b938 100644 --- a/Cesium3DTiles/src/Batched3DModelContent.cpp +++ b/Cesium3DTiles/src/Batched3DModelContent.cpp @@ -40,7 +40,7 @@ namespace Cesium3DTiles { void parseFeatureTableJsonData( const std::shared_ptr& pLogger, - CesiumGltf::Model& /*gltf*/, + CesiumGltf::Model& gltf, const gsl::span& featureTableJsonData) { rapidjson::Document document; @@ -50,30 +50,23 @@ namespace Cesium3DTiles { return; } - // auto rtcIt = document.FindMember("RTC_CENTER"); - // if ( - // rtcIt != document.MemberEnd() && - // rtcIt->value.IsArray() && - // rtcIt->value.Size() == 3 && - // rtcIt->value[0].IsDouble() && - // rtcIt->value[1].IsDouble() && - // rtcIt->value[2].IsDouble() - // ) { - // // Add the RTC_CENTER value to the glTF itself. - // CesiumGltf::Value::Object extras; - // if (gltf.extras.IsObject()) { - // extras = gltf.extras.Get(); - // } - - // rapidjson::Value& rtcValue = rtcIt->value; - // extras["RTC_CENTER"] = CesiumGltf::Value(CesiumGltf::Value::Array{ - // CesiumGltf::Value(rtcValue[0].GetDouble()), - // CesiumGltf::Value(rtcValue[1].GetDouble()), - // CesiumGltf::Value(rtcValue[2].GetDouble()) - // }); - - // gltf.extras = CesiumGltf::Value(extras); - // } + auto rtcIt = document.FindMember("RTC_CENTER"); + if ( + rtcIt != document.MemberEnd() && + rtcIt->value.IsArray() && + rtcIt->value.Size() == 3 && + rtcIt->value[0].IsDouble() && + rtcIt->value[1].IsDouble() && + rtcIt->value[2].IsDouble() + ) { + // Add the RTC_CENTER value to the glTF itself. + rapidjson::Value& rtcValue = rtcIt->value; + gltf.extras["RTC_CENTER"] = { + rtcValue[0].GetDouble(), + rtcValue[1].GetDouble(), + rtcValue[2].GetDouble() + }; + } } } diff --git a/CesiumGltf/include/CesiumGltf/ExtensibleObject.h b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h index ecddd72b6..79a58b064 100644 --- a/CesiumGltf/include/CesiumGltf/ExtensibleObject.h +++ b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h @@ -1,5 +1,6 @@ #pragma once +#include "CesiumGltf/JsonValue.h" #include #include @@ -39,5 +40,12 @@ namespace CesiumGltf { * Use {@link getExtension} to get the extension with a particular static type. */ std::vector extensions; + + /** + * @brief Application-specific data. + * + * **Implementation Note:** Although extras may have any type, it is common for applications to store and access custom data as key/value pairs. As best practice, extras should be an Object rather than a primitive value for best portability. + */ + JsonValue::Object extras; }; } diff --git a/CesiumGltf/include/CesiumGltf/JsonValue.h b/CesiumGltf/include/CesiumGltf/JsonValue.h new file mode 100644 index 000000000..6da0b05b5 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/JsonValue.h @@ -0,0 +1,67 @@ +#pragma once + +#include +#include +#include + +namespace CesiumGltf { + class JsonValue final { + public: + using Null = nullptr_t; + using Number = double; + using Bool = bool; + using String = std::string; + using Object = std::unordered_map; + using Array = std::vector; + + JsonValue() : value() {} + JsonValue(nullptr_t) : value(nullptr) {} + JsonValue(double v) : value(v) {} + JsonValue(bool v) : value(v) {} + JsonValue(const std::string& v) : value(v) {} + JsonValue(std::string&& v) : value(std::move(v)) {} + JsonValue(const char* v) : value(std::string(v)) {} + JsonValue(const std::unordered_map& v) : value(v) {} + JsonValue(std::unordered_map&& v) : value(std::move(v)) {} + JsonValue(const std::vector& v) : value(v) {} + JsonValue(std::vector&& v) : value(std::move(v)) {} + + JsonValue(std::initializer_list v) : + value(std::vector(v)) {} + JsonValue(std::initializer_list> v) : + value(std::unordered_map(v)) {} + + /** + * @brief Gets the number from the value, or a default if the value does not contain a number. + * + * @param default The default value to return if the value is not a number. + * @return The number. + */ + double getNumber(double default) const; + + /** + * @brief Gets the bool from the value, or a default if the value does not contain a bool. + * + * @param default The default value to return if the value is not a bool. + * @return The bool. + */ + bool getBool(bool default) const; + + /** + * @brief Gets the string from the value, or a default if the value does not contain a string. + * + * @param default The default value to return if the value is not a string. + * @return The string. + */ + std::string getString(const std::string& default) const; + + std::variant< + Null, + Number, + Bool, + String, + Object, + Array + > value; + }; +} diff --git a/CesiumGltf/src/JsonValue.cpp b/CesiumGltf/src/JsonValue.cpp new file mode 100644 index 000000000..7a895b63a --- /dev/null +++ b/CesiumGltf/src/JsonValue.cpp @@ -0,0 +1,30 @@ +#include "CesiumGltf/JsonValue.h" + +using namespace CesiumGltf; + +double JsonValue::getNumber(double default) const { + const double* p = std::get_if(&this->value); + if (p) { + return *p; + } else { + return default; + } +} + +bool JsonValue::getBool(bool default) const { + const bool* p = std::get_if(&this->value); + if (p) { + return *p; + } else { + return default; + } +} + +std::string JsonValue::getString(const std::string& default) const { + const std::string* p = std::get_if(&this->value); + if (p) { + return *p; + } else { + return default; + } +} diff --git a/CesiumGltfReader/src/DictionaryJsonHandler.h b/CesiumGltfReader/src/DictionaryJsonHandler.h index 6863c9593..b55e868b5 100644 --- a/CesiumGltfReader/src/DictionaryJsonHandler.h +++ b/CesiumGltfReader/src/DictionaryJsonHandler.h @@ -18,7 +18,7 @@ namespace CesiumGltf { virtual IJsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { assert(this->_pDictionary); - auto it = this->_pDictionary->emplace(str, -1).first; + auto it = this->_pDictionary->emplace(str, T()).first; return this->property( it->first.c_str(), diff --git a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp index 67f702f85..053ddf3f9 100644 --- a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp +++ b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.cpp @@ -1,4 +1,5 @@ #include "ExtensibleObjectJsonHandler.h" +#include "CesiumGltf/ExtensibleObject.h" using namespace CesiumGltf; @@ -6,7 +7,10 @@ void ExtensibleObjectJsonHandler::reset(IJsonHandler* pParent, ExtensibleObject* ObjectJsonHandler::reset(pParent); } -IJsonHandler* ExtensibleObjectJsonHandler::ExtensibleObjectKey(const char* /*str*/, ExtensibleObject& /*o*/) { - // TODO: handle extensions and extras. +IJsonHandler* ExtensibleObjectJsonHandler::ExtensibleObjectKey(const char* str, ExtensibleObject& o) { + using namespace std::string_literals; + + if ("extras"s == str) return property("extras", this->_extras, o.extras); + return this->ignoreAndContinue(); } \ No newline at end of file diff --git a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h index e1de12f62..53a0d185a 100644 --- a/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h +++ b/CesiumGltfReader/src/ExtensibleObjectJsonHandler.h @@ -1,6 +1,8 @@ #pragma once #include "ObjectJsonHandler.h" +#include "DictionaryJsonHandler.h" +#include "JsonObjectJsonHandler.h" namespace CesiumGltf { struct ExtensibleObject; @@ -9,5 +11,8 @@ namespace CesiumGltf { protected: void reset(IJsonHandler* pParent, ExtensibleObject* pObject); IJsonHandler* ExtensibleObjectKey(const char* str, ExtensibleObject& o); + + private: + DictionaryJsonHandler _extras; }; } diff --git a/CesiumGltfReader/src/JsonObjectJsonHandler.cpp b/CesiumGltfReader/src/JsonObjectJsonHandler.cpp new file mode 100644 index 000000000..43f5f5949 --- /dev/null +++ b/CesiumGltfReader/src/JsonObjectJsonHandler.cpp @@ -0,0 +1,118 @@ +#include "JsonObjectJsonHandler.h" + +using namespace CesiumGltf; + +namespace { + template + void addOrReplace(JsonValue& json, T value) { + JsonValue::Array* pArray = std::get_if(&json.value); + if (pArray) { + pArray->emplace_back(value); + } else { + json = value; + } + } +} + +void JsonObjectJsonHandler::reset(IJsonHandler* pParent, JsonValue* pValue) { + JsonHandler::reset(pParent); + this->_stack.clear(); + this->_stack.push_back(pValue); +} + +IJsonHandler* JsonObjectJsonHandler::Null() { + addOrReplace(*this->_stack.back(), JsonValue::Null()); + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::Bool(bool b) { + addOrReplace(*this->_stack.back(), b); + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::Int(int i) { + addOrReplace(*this->_stack.back(), JsonValue::Number(i)); + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::Uint(unsigned i) { + addOrReplace(*this->_stack.back(), JsonValue::Number(i)); + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::Int64(int64_t i) { + addOrReplace(*this->_stack.back(), JsonValue::Number(i)); + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::Uint64(uint64_t i) { + addOrReplace(*this->_stack.back(), JsonValue::Number(i)); + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::Double(double d) { + addOrReplace(*this->_stack.back(), d); + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::RawNumber(const char* /* str */, size_t /* length */, bool /* copy */) { + return nullptr; +} + +IJsonHandler* JsonObjectJsonHandler::String(const char* str, size_t /* length */, bool /* copy */) { + *this->_stack.back() = str; + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::StartObject() { + JsonValue& current = *this->_stack.back(); + JsonValue::Array* pArray = std::get_if(¤t.value); + if (pArray) { + JsonValue& newArray = pArray->emplace_back(JsonValue::Object()); + this->_stack.emplace_back(&newArray); + } else { + current = JsonValue::Object(); + } + + return this; +} + +IJsonHandler* JsonObjectJsonHandler::Key(const char* str, size_t /* length */, bool /* copy */) { + JsonValue& json = *this->_stack.back(); + JsonValue::Object* pObject = std::get_if(&json.value); + + auto it = pObject->emplace(str, JsonValue()).first; + this->_stack.push_back(&it->second); + + return property( + it->first.c_str(), + *this, + it->second + ); +} + +IJsonHandler* JsonObjectJsonHandler::EndObject(size_t /* memberCount */) { + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::StartArray() { + JsonValue& current = *this->_stack.back(); + JsonValue::Array* pArray = std::get_if(¤t.value); + if (pArray) { + JsonValue& newArray = pArray->emplace_back(JsonValue::Array()); + this->_stack.emplace_back(&newArray); + } else { + current = JsonValue::Array(); + } + + return this; +} + +IJsonHandler* JsonObjectJsonHandler::EndArray(size_t /* elementCount */) { + return this->doneElement(); +} + +IJsonHandler* JsonObjectJsonHandler::doneElement() { + this->_stack.pop_back(); + return this->_stack.empty() ? this->parent() : this; +} \ No newline at end of file diff --git a/CesiumGltfReader/src/JsonObjectJsonHandler.h b/CesiumGltfReader/src/JsonObjectJsonHandler.h new file mode 100644 index 000000000..9007136c2 --- /dev/null +++ b/CesiumGltfReader/src/JsonObjectJsonHandler.h @@ -0,0 +1,41 @@ +#pragma once + +#include "CesiumGltf/JsonValue.h" +#include "JsonHandler.h" + +namespace CesiumGltf { + + class JsonObjectJsonHandler : public JsonHandler { + public: + void reset(IJsonHandler* pParent, JsonValue* pValue); + + virtual IJsonHandler* Null() override; + virtual IJsonHandler* Bool(bool b) override; + virtual IJsonHandler* Int(int i) override; + virtual IJsonHandler* Uint(unsigned i) override; + virtual IJsonHandler* Int64(int64_t i) override; + virtual IJsonHandler* Uint64(uint64_t i) override; + virtual IJsonHandler* Double(double d) override; + virtual IJsonHandler* RawNumber(const char* str, size_t length, bool copy) override; + virtual IJsonHandler* String(const char* str, size_t length, bool copy) override; + virtual IJsonHandler* StartObject() override; + virtual IJsonHandler* Key(const char* str, size_t length, bool copy) override; + virtual IJsonHandler* EndObject(size_t memberCount) override; + virtual IJsonHandler* StartArray() override; + virtual IJsonHandler* EndArray(size_t elementCount) override; + + private: + template + IJsonHandler* property(const char* currentKey, TAccessor& accessor, TProperty& value) { + this->_currentKey = currentKey; + accessor.reset(this, &value); + return &accessor; + } + + IJsonHandler* doneElement(); + + std::vector _stack; + const char* _currentKey; + }; + +} From 11ea3103b086ae9d5080368a34f71cd300ccab82 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Sun, 17 Jan 2021 00:18:00 +1100 Subject: [PATCH 38/61] Optional properties, thorough initialization. --- .../include/Cesium3DTiles/GltfAccessor.h | 6 +- CesiumGltf/include/CesiumGltf/Accessor.h | 13 ++-- .../include/CesiumGltf/AccessorSparse.h | 2 +- .../CesiumGltf/AccessorSparseIndices.h | 4 +- .../include/CesiumGltf/AccessorSparseValues.h | 2 +- .../CesiumGltf/AnimationChannelTarget.h | 2 +- CesiumGltf/include/CesiumGltf/Asset.h | 7 +- CesiumGltf/include/CesiumGltf/Buffer.h | 5 +- CesiumGltf/include/CesiumGltf/BufferView.h | 9 +-- CesiumGltf/include/CesiumGltf/Camera.h | 7 +- .../include/CesiumGltf/CameraOrthographic.h | 8 +-- .../include/CesiumGltf/CameraPerspective.h | 9 +-- CesiumGltf/include/CesiumGltf/Image.h | 5 +- CesiumGltf/include/CesiumGltf/Material.h | 11 ++-- .../CesiumGltf/MaterialPBRMetallicRoughness.h | 5 +- CesiumGltf/include/CesiumGltf/Sampler.h | 5 +- CesiumGltf/include/CesiumGltf/TextureInfo.h | 2 +- CesiumGltf/src/Helpers.cpp | 6 +- CesiumGltfReader/src/ObjectJsonHandler.h | 16 ++++- CesiumGltfReader/src/Reader.cpp | 2 +- tools/generate-gltf-classes/generate.js | 6 +- .../generate-gltf-classes/resolveProperty.js | 64 +++++++++++++------ 22 files changed, 124 insertions(+), 72 deletions(-) diff --git a/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h b/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h index f4f72b6bd..fb3f56555 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h +++ b/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h @@ -188,10 +188,10 @@ namespace Cesium3DTiles { } static int64_t computeByteStride(const CesiumGltf::Accessor& accessor, const CesiumGltf::BufferView& bufferView) { - if (bufferView.byteStride <= 0) { - return computeNumberOfComponents(accessor.type) * computeByteSizeOfComponent(accessor.componentType); + if (bufferView.byteStride) { + return bufferView.byteStride.value(); } else { - return bufferView.byteStride; + return computeNumberOfComponents(accessor.type) * computeByteSizeOfComponent(accessor.componentType); } } }; diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index 7ee6a678c..1f39920ba 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -5,6 +5,7 @@ #include "CesiumGltf/AccessorSparse.h" #include "CesiumGltf/NamedObject.h" #include +#include #include namespace CesiumGltf { @@ -54,33 +55,33 @@ namespace CesiumGltf { * * This must be a multiple of the size of the component datatype. */ - int64_t byteOffset; + int64_t byteOffset = 0; /** * @brief The datatype of components in the attribute. * * All valid values correspond to WebGL enums. The corresponding typed arrays are `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Uint32Array`, and `Float32Array`, respectively. 5125 (UNSIGNED_INT) is only allowed when the accessor contains indices, i.e., the accessor is only referenced by `primitive.indices`. */ - ComponentType componentType; + ComponentType componentType = ComponentType(); /** * @brief Specifies whether integer data values should be normalized. * * Specifies whether integer data values should be normalized (`true`) to [0, 1] (for unsigned types) or [-1, 1] (for signed types), or converted directly (`false`) when they are accessed. This property is defined only for accessors that contain vertex attributes or animation output data. */ - bool normalized; + bool normalized = false; /** * @brief The number of attributes referenced by this accessor. * * The number of attributes referenced by this accessor, not to be confused with the number of bytes or number of components. */ - int64_t count; + int64_t count = int64_t(); /** * @brief Specifies if the attribute is a scalar, vector, or matrix. */ - Type type; + Type type = Type(); /** * @brief Maximum value of each component in this attribute. @@ -103,7 +104,7 @@ namespace CesiumGltf { /** * @brief Sparse storage of attributes that deviate from their initialization value. */ - AccessorSparse sparse; + std::optional sparse; }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparse.h b/CesiumGltf/include/CesiumGltf/AccessorSparse.h index 11d285e89..f8a494c00 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparse.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparse.h @@ -18,7 +18,7 @@ namespace CesiumGltf { * * The number of attributes encoded in this sparse accessor. */ - int64_t count; + int64_t count = int64_t(); /** * @brief Index array of size `count` that points to those accessor attributes that deviate from their initialization value. Indices must strictly increase. diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h index fd1915a5e..39b923453 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h @@ -26,14 +26,14 @@ namespace CesiumGltf { /** * @brief The offset relative to the start of the bufferView in bytes. Must be aligned. */ - int64_t byteOffset; + int64_t byteOffset = 0; /** * @brief The indices data type. * * Valid values correspond to WebGL enums: `5121` (UNSIGNED_BYTE), `5123` (UNSIGNED_SHORT), `5125` (UNSIGNED_INT). */ - ComponentType componentType; + ComponentType componentType = ComponentType(); }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h index de6d9ea89..07a7427b4 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h @@ -19,7 +19,7 @@ namespace CesiumGltf { /** * @brief The offset relative to the start of the bufferView in bytes. Must be aligned. */ - int64_t byteOffset; + int64_t byteOffset = 0; }; } diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h index 9f4389b44..916eea6b0 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h +++ b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h @@ -28,7 +28,7 @@ namespace CesiumGltf { /** * @brief The name of the node's TRS property to modify, or the "weights" of the Morph Targets it instantiates. For the "translation" property, the values that are provided by the sampler are the translation along the x, y, and z axes. For the "rotation" property, the values are a quaternion in the order (x, y, z, w), where w is the scalar. For the "scale" property, the values are the scaling factors along the x, y, and z axes. */ - Path path; + Path path = Path(); }; } diff --git a/CesiumGltf/include/CesiumGltf/Asset.h b/CesiumGltf/include/CesiumGltf/Asset.h index 331e97270..e107a32ed 100644 --- a/CesiumGltf/include/CesiumGltf/Asset.h +++ b/CesiumGltf/include/CesiumGltf/Asset.h @@ -3,6 +3,7 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include #include namespace CesiumGltf { @@ -14,12 +15,12 @@ namespace CesiumGltf { /** * @brief A copyright message suitable for display to credit the content creator. */ - std::string copyright; + std::optional copyright; /** * @brief Tool that generated this glTF model. Useful for debugging. */ - std::string generator; + std::optional generator; /** * @brief The glTF version that this asset targets. @@ -29,7 +30,7 @@ namespace CesiumGltf { /** * @brief The minimum glTF version that this asset targets. */ - std::string minVersion; + std::optional minVersion; }; } diff --git a/CesiumGltf/include/CesiumGltf/Buffer.h b/CesiumGltf/include/CesiumGltf/Buffer.h index 0b58845da..f76b67912 100644 --- a/CesiumGltf/include/CesiumGltf/Buffer.h +++ b/CesiumGltf/include/CesiumGltf/Buffer.h @@ -5,6 +5,7 @@ #include "CesiumGltf/BufferCesium.h" #include "CesiumGltf/NamedObject.h" #include +#include #include namespace CesiumGltf { @@ -18,12 +19,12 @@ namespace CesiumGltf { * * Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. */ - std::string uri; + std::optional uri; /** * @brief The length of the buffer in bytes. */ - int64_t byteLength; + int64_t byteLength = int64_t(); /** * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. diff --git a/CesiumGltf/include/CesiumGltf/BufferView.h b/CesiumGltf/include/CesiumGltf/BufferView.h index f970cbf05..bc4d23195 100644 --- a/CesiumGltf/include/CesiumGltf/BufferView.h +++ b/CesiumGltf/include/CesiumGltf/BufferView.h @@ -4,6 +4,7 @@ #include "CesiumGltf/NamedObject.h" #include +#include namespace CesiumGltf { /** @@ -24,24 +25,24 @@ namespace CesiumGltf { /** * @brief The offset into the buffer in bytes. */ - int64_t byteOffset; + int64_t byteOffset = 0; /** * @brief The length of the bufferView in bytes. */ - int64_t byteLength; + int64_t byteLength = int64_t(); /** * @brief The stride, in bytes. * * The stride, in bytes, between vertex attributes. When this is not defined, data is tightly packed. When two or more accessors use the same bufferView, this field must be defined. */ - int64_t byteStride; + std::optional byteStride; /** * @brief The target that the GPU buffer should be bound to. */ - Target target; + std::optional target; }; } diff --git a/CesiumGltf/include/CesiumGltf/Camera.h b/CesiumGltf/include/CesiumGltf/Camera.h index 6eb8e7c94..ce0d56300 100644 --- a/CesiumGltf/include/CesiumGltf/Camera.h +++ b/CesiumGltf/include/CesiumGltf/Camera.h @@ -5,6 +5,7 @@ #include "CesiumGltf/CameraOrthographic.h" #include "CesiumGltf/CameraPerspective.h" #include "CesiumGltf/NamedObject.h" +#include namespace CesiumGltf { /** @@ -20,19 +21,19 @@ namespace CesiumGltf { /** * @brief An orthographic camera containing properties to create an orthographic projection matrix. */ - CameraOrthographic orthographic; + std::optional orthographic; /** * @brief A perspective camera containing properties to create a perspective projection matrix. */ - CameraPerspective perspective; + std::optional perspective; /** * @brief Specifies if the camera uses a perspective or orthographic projection. * * Based on this, either the camera's `perspective` or `orthographic` property will be defined. */ - Type type; + Type type = Type(); }; } diff --git a/CesiumGltf/include/CesiumGltf/CameraOrthographic.h b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h index efb7409c4..46b66a7be 100644 --- a/CesiumGltf/include/CesiumGltf/CameraOrthographic.h +++ b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h @@ -13,22 +13,22 @@ namespace CesiumGltf { /** * @brief The floating-point horizontal magnification of the view. Must not be zero. */ - double xmag; + double xmag = double(); /** * @brief The floating-point vertical magnification of the view. Must not be zero. */ - double ymag; + double ymag = double(); /** * @brief The floating-point distance to the far clipping plane. `zfar` must be greater than `znear`. */ - double zfar; + double zfar = double(); /** * @brief The floating-point distance to the near clipping plane. */ - double znear; + double znear = double(); }; } diff --git a/CesiumGltf/include/CesiumGltf/CameraPerspective.h b/CesiumGltf/include/CesiumGltf/CameraPerspective.h index 10d5df37b..78be30ca0 100644 --- a/CesiumGltf/include/CesiumGltf/CameraPerspective.h +++ b/CesiumGltf/include/CesiumGltf/CameraPerspective.h @@ -3,6 +3,7 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include namespace CesiumGltf { /** @@ -15,24 +16,24 @@ namespace CesiumGltf { * * When this is undefined, the aspect ratio of the canvas is used. */ - double aspectRatio; + std::optional aspectRatio; /** * @brief The floating-point vertical field of view in radians. */ - double yfov; + double yfov = double(); /** * @brief The floating-point distance to the far clipping plane. * * When defined, `zfar` must be greater than `znear`. If `zfar` is undefined, runtime must use infinite projection matrix. */ - double zfar; + std::optional zfar; /** * @brief The floating-point distance to the near clipping plane. */ - double znear; + double znear = double(); }; } diff --git a/CesiumGltf/include/CesiumGltf/Image.h b/CesiumGltf/include/CesiumGltf/Image.h index 22097b1f5..5ff467ceb 100644 --- a/CesiumGltf/include/CesiumGltf/Image.h +++ b/CesiumGltf/include/CesiumGltf/Image.h @@ -5,6 +5,7 @@ #include "CesiumGltf/ImageCesium.h" #include "CesiumGltf/NamedObject.h" #include +#include #include namespace CesiumGltf { @@ -23,12 +24,12 @@ namespace CesiumGltf { * * Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. The image format must be jpg or png. */ - std::string uri; + std::optional uri; /** * @brief The image's MIME type. Required if `bufferView` is defined. */ - MimeType mimeType; + std::optional mimeType; /** * @brief The index of the bufferView that contains the image. Use this instead of the image's uri property. diff --git a/CesiumGltf/include/CesiumGltf/Material.h b/CesiumGltf/include/CesiumGltf/Material.h index c85420386..9d63ad621 100644 --- a/CesiumGltf/include/CesiumGltf/Material.h +++ b/CesiumGltf/include/CesiumGltf/Material.h @@ -7,6 +7,7 @@ #include "CesiumGltf/MaterialPBRMetallicRoughness.h" #include "CesiumGltf/NamedObject.h" #include "CesiumGltf/TextureInfo.h" +#include #include namespace CesiumGltf { @@ -25,28 +26,28 @@ namespace CesiumGltf { /** * @brief A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology. When not specified, all the default values of `pbrMetallicRoughness` apply. */ - MaterialPBRMetallicRoughness pbrMetallicRoughness; + std::optional pbrMetallicRoughness; /** * @brief The normal map texture. * * A tangent space normal map. The texture contains RGB components in linear space. Each texel represents the XYZ components of a normal vector in tangent space. Red [0 to 255] maps to X [-1 to 1]. Green [0 to 255] maps to Y [-1 to 1]. Blue [128 to 255] maps to Z [1/255 to 1]. The normal vectors use the convention +X is right and +Y is up. +Z points toward the viewer. In GLSL, this vector would be unpacked like so: `vec3 normalVector = tex2D(, texCoord) * 2 - 1`. Client implementations should normalize the normal vectors before using them in lighting equations. */ - MaterialNormalTextureInfo normalTexture; + std::optional normalTexture; /** * @brief The occlusion map texture. * * The occlusion values are sampled from the R channel. Higher values indicate areas that should receive full indirect lighting and lower values indicate no indirect lighting. These values are linear. If other channels are present (GBA), they are ignored for occlusion calculations. */ - MaterialOcclusionTextureInfo occlusionTexture; + std::optional occlusionTexture; /** * @brief The emissive map texture. * * The emissive map controls the color and intensity of the light being emitted by the material. This texture contains RGB components encoded with the sRGB transfer function. If a fourth component (A) is present, it is ignored. */ - TextureInfo emissiveTexture; + std::optional emissiveTexture; /** * @brief The emissive color of the material. @@ -74,7 +75,7 @@ namespace CesiumGltf { * * When this value is false, back-face culling is enabled. When this value is true, back-face culling is disabled and double sided lighting is enabled. The back-face must have its normals reversed before the lighting equation is evaluated. */ - bool doubleSided; + bool doubleSided = false; }; } diff --git a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h index ed0ceea61..7b43d3f85 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h +++ b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h @@ -4,6 +4,7 @@ #include "CesiumGltf/ExtensibleObject.h" #include "CesiumGltf/TextureInfo.h" +#include #include namespace CesiumGltf { @@ -24,7 +25,7 @@ namespace CesiumGltf { * * The first three components (RGB) are encoded with the sRGB transfer function. They specify the base color of the material. If the fourth component (A) is present, it represents the linear alpha coverage of the material. Otherwise, an alpha of 1.0 is assumed. The `alphaMode` property specifies how alpha is interpreted. The stored texels must not be premultiplied. */ - TextureInfo baseColorTexture; + std::optional baseColorTexture; /** * @brief The metalness of the material. @@ -45,7 +46,7 @@ namespace CesiumGltf { * * The metalness values are sampled from the B channel. The roughness values are sampled from the G channel. These values are linear. If other channels are present (R or A), they are ignored for metallic-roughness calculations. */ - TextureInfo metallicRoughnessTexture; + std::optional metallicRoughnessTexture; }; } diff --git a/CesiumGltf/include/CesiumGltf/Sampler.h b/CesiumGltf/include/CesiumGltf/Sampler.h index 179bf6fa9..1fd97d8be 100644 --- a/CesiumGltf/include/CesiumGltf/Sampler.h +++ b/CesiumGltf/include/CesiumGltf/Sampler.h @@ -3,6 +3,7 @@ #pragma once #include "CesiumGltf/NamedObject.h" +#include namespace CesiumGltf { /** @@ -50,14 +51,14 @@ namespace CesiumGltf { * * Valid values correspond to WebGL enums: `9728` (NEAREST) and `9729` (LINEAR). */ - MagFilter magFilter; + std::optional magFilter; /** * @brief Minification filter. * * All valid values correspond to WebGL enums. */ - MinFilter minFilter; + std::optional minFilter; /** * @brief s wrapping mode. diff --git a/CesiumGltf/include/CesiumGltf/TextureInfo.h b/CesiumGltf/include/CesiumGltf/TextureInfo.h index f49285c78..deda7ae09 100644 --- a/CesiumGltf/include/CesiumGltf/TextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/TextureInfo.h @@ -21,7 +21,7 @@ namespace CesiumGltf { * * This integer value is used to construct a string in the format `TEXCOORD_` which is a reference to a key in mesh.primitives.attributes (e.g. A value of `0` corresponds to `TEXCOORD_0`). Mesh must have corresponding texture coordinate attributes for the material to be applicable to it. */ - int64_t texCoord; + int64_t texCoord = 0; }; } diff --git a/CesiumGltf/src/Helpers.cpp b/CesiumGltf/src/Helpers.cpp index 56b683b84..afd069233 100644 --- a/CesiumGltf/src/Helpers.cpp +++ b/CesiumGltf/src/Helpers.cpp @@ -41,10 +41,10 @@ int8_t computeByteSizeOfComponent(CesiumGltf::Accessor::ComponentType componentT } int64_t computeByteStride(const CesiumGltf::Accessor& accessor, const CesiumGltf::BufferView& bufferView) { - if (bufferView.byteStride <= 0) { - return computeNumberOfComponents(accessor.type) * computeByteSizeOfComponent(accessor.componentType); + if (bufferView.byteStride) { + return bufferView.byteStride.value(); } else { - return bufferView.byteStride; + return computeNumberOfComponents(accessor.type) * computeByteSizeOfComponent(accessor.componentType); } } diff --git a/CesiumGltfReader/src/ObjectJsonHandler.h b/CesiumGltfReader/src/ObjectJsonHandler.h index 10827f6ee..026aba6ed 100644 --- a/CesiumGltfReader/src/ObjectJsonHandler.h +++ b/CesiumGltfReader/src/ObjectJsonHandler.h @@ -1,6 +1,7 @@ #pragma once #include "JsonHandler.h" +#include namespace CesiumGltf { class ObjectJsonHandler : public JsonHandler { @@ -15,13 +16,26 @@ namespace CesiumGltf { template IJsonHandler* property(const char* currentKey, TAccessor& accessor, TProperty& value) { this->_currentKey = currentKey; - accessor.reset(this, &value); + + if constexpr (isOptional) { + value.emplace(); + accessor.reset(this, &value.value()); + } else { + accessor.reset(this, &value); + } + return &accessor; } const char* getCurrentKey() const; private: + template + static constexpr bool isOptional = false; + + template + static constexpr bool isOptional> = true; + int32_t _depth = 0; const char* _currentKey; }; diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 45368815b..1ccda0397 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -261,7 +261,7 @@ namespace { } Buffer& buffer = model.buffers[0]; - if (!buffer.uri.empty()) { + if (buffer.uri) { result.errors = "GLB has a binary chunk but the first buffer in the JSON chunk also has a 'uri'."; return result; } diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index f2265bc3e..7b945a9a0 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -20,9 +20,11 @@ function generate(options, schema) { base = getNameFromSchema(nameMapping, baseSchema); } + const required = schema.required || []; + const properties = Object.keys(schema.properties) .map((key) => - resolveProperty(schemaCache, nameMapping, name, key, schema.properties[key]) + resolveProperty(schemaCache, nameMapping, name, key, schema.properties[key], required) ) .filter((property) => property !== undefined); @@ -209,6 +211,8 @@ function formatProperty(property) { if (property.defaultValue !== undefined) { result += " = " + property.defaultValue; + } else if (property.needsInitialization) { + result += " = " + property.type + "()"; } result += ";"; diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index ff2d5f913..9bc20e364 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -8,48 +8,60 @@ function resolveProperty( nameMapping, parentName, propertyName, - propertyDetails + propertyDetails, + required ) { if (Object.keys(propertyDetails).length === 0) { // Ignore totally empty properties. return undefined; } + // If we don't know what's required, act as if everything is. + // Specifically this means we _don't_ make it optional. + const isRequired = required === undefined || required.includes(propertyName); + const makeOptional = !isRequired && propertyDetails.default === undefined; + if (propertyDetails.type == "array") { return resolveArray( schemaCache, nameMapping, parentName, propertyName, - propertyDetails + propertyDetails, + required ); } else if (propertyDetails.type == "integer") { return { ...propertyDefaults(propertyName, propertyDetails), - headers: [""], - type: "int64_t", + headers: ["", ...(makeOptional ? [""] : [])], + type: makeOptional ? "std::optional" : "int64_t", readerHeaders: [`"IntegerJsonHandler.h"`], readerType: "IntegerJsonHandler", + needsInitialization: !makeOptional }; } else if (propertyDetails.type == "number") { return { ...propertyDefaults(propertyName, propertyDetails), - type: "double", + headers: makeOptional ? [""] : [], + type: makeOptional ? "std::optional" : "double", readerHeaders: [`"DoubleJsonHandler.h"`], readerType: "DoubleJsonHandler", + needsInitialization: !makeOptional }; } else if (propertyDetails.type == "boolean") { return { ...propertyDefaults(propertyName, propertyDetails), - type: "bool", + headers: makeOptional ? [""] : [], + type: makeOptional ? "std::optional" : "bool", readerHeaders: `"BoolJsonHandler.h"`, readerType: "BoolJsonHandler", + needsInitialization: ~makeOptional }; } else if (propertyDetails.type == "string") { return { ...propertyDefaults(propertyName, propertyDetails), - type: "std::string", - headers: [""], + type: makeOptional ? "std::optional" : "std::string", + headers: ["", ...(makeOptional ? [""] : [])], readerHeaders: [`"StringJsonHandler.h"`], readerType: "StringJsonHandler", }; @@ -62,7 +74,8 @@ function resolveProperty( nameMapping, parentName, propertyName, - propertyDetails + propertyDetails, + required ); } else if ( propertyDetails.anyOf && @@ -74,7 +87,8 @@ function resolveProperty( nameMapping, parentName, propertyName, - propertyDetails + propertyDetails, + makeOptional ); } else if (propertyDetails.$ref) { const itemSchema = schemaCache.load(propertyDetails.$ref); @@ -89,10 +103,12 @@ function resolveProperty( }; } else { const type = getNameFromSchema(nameMapping, itemSchema); + const typeName = getNameFromSchema(nameMapping, itemSchema); + return { ...propertyDefaults(propertyName, propertyDetails), - type: getNameFromSchema(nameMapping, itemSchema), - headers: [`"CesiumGltf/${type}.h"`], + type: makeOptional ? `std::optional<${typeName}>` : typeName, + headers: [`"CesiumGltf/${type}.h"`, ...(makeOptional ? [""] : [])], readerType: `${type}JsonHandler`, readerHeaders: [`"${type}JsonHandler.h"`], schemas: [itemSchema], @@ -104,7 +120,8 @@ function resolveProperty( nameMapping, parentName, propertyName, - propertyDetails.allOf[0] + propertyDetails.allOf[0], + required, ); return { @@ -142,7 +159,7 @@ function propertyDefaults(propertyName, propertyDetails) { readerHeaders: [], readerHeadersImpl: [], type: "", - defaultValue: propertyDetails.default ? propertyDetails.default.toString() : undefined, + defaultValue: propertyDetails.default !== undefined ? propertyDetails.default.toString() : undefined, readerType: "", schemas: [], localTypes: [], @@ -158,14 +175,16 @@ function resolveArray( nameMapping, parentName, propertyName, - propertyDetails + propertyDetails, + required ) { const itemProperty = resolveProperty( schemaCache, nameMapping, parentName, propertyName + ".items", - propertyDetails.items + propertyDetails.items, + undefined ); if (!itemProperty) { @@ -190,14 +209,16 @@ function resolveDictionary( nameMapping, parentName, propertyName, - propertyDetails + propertyDetails, + required ) { const additional = resolveProperty( schemaCache, nameMapping, parentName, propertyName + ".additionalProperties", - propertyDetails.additionalProperties + propertyDetails.additionalProperties, + required ); if (!additional) { @@ -221,7 +242,8 @@ function resolveEnum( nameMapping, parentName, propertyName, - propertyDetails + propertyDetails, + makeOptional ) { if ( !propertyDetails.anyOf || @@ -256,7 +278,8 @@ function resolveEnum( }; `), ], - type: enumName, + type: makeOptional ? `std::optional<${enumName}>` : enumName, + headers: makeOptional ? [""] : [], defaultValue: createEnumDefault(enumName, propertyDetails), readerHeaders: [`"CesiumGltf/${parentName}.h"`], readerLocalTypes: readerTypes, @@ -266,6 +289,7 @@ function resolveEnum( propertyName, propertyDetails ), + needsInitialization: !makeOptional }; if (readerTypes.length > 0) { From c36a2710c3ec3f92ef05461f7e435ad242a17cb6 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 18 Jan 2021 22:51:20 +1100 Subject: [PATCH 39/61] Allow for augmentation of generated classes via inheritance. --- CesiumGltf/include/CesiumGltf/Accessor.h | 107 +------------- CesiumGltf/include/CesiumGltf/AccessorSpec.h | 110 ++++++++++++++ CesiumGltf/include/CesiumGltf/Buffer.h | 27 +--- CesiumGltf/include/CesiumGltf/BufferSpec.h | 29 ++++ CesiumGltf/include/CesiumGltf/Image.h | 37 +---- CesiumGltf/include/CesiumGltf/ImageSpec.h | 39 +++++ CesiumGltf/include/CesiumGltf/Model.h | 131 +---------------- CesiumGltf/include/CesiumGltf/ModelSpec.h | 134 ++++++++++++++++++ tools/generate-gltf-classes/generate.js | 31 +--- .../getNameFromSchema.js | 4 +- tools/generate-gltf-classes/glTF.json | 33 +++++ tools/generate-gltf-classes/index.js | 52 +++---- tools/generate-gltf-classes/package.json | 3 +- .../generate-gltf-classes/resolveProperty.js | 24 ++-- 14 files changed, 399 insertions(+), 362 deletions(-) create mode 100644 CesiumGltf/include/CesiumGltf/AccessorSpec.h create mode 100644 CesiumGltf/include/CesiumGltf/BufferSpec.h create mode 100644 CesiumGltf/include/CesiumGltf/ImageSpec.h create mode 100644 CesiumGltf/include/CesiumGltf/ModelSpec.h create mode 100644 tools/generate-gltf-classes/glTF.json diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index 1f39920ba..e5c7ef10f 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -1,110 +1,9 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! #pragma once -#include "CesiumGltf/AccessorSparse.h" -#include "CesiumGltf/NamedObject.h" -#include -#include -#include +#include "CesiumGltf/AccessorSpec.h" namespace CesiumGltf { - /** - * @brief A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides a typed view into a bufferView or a subset of a bufferView similar to how WebGL's `vertexAttribPointer()` defines an attribute in a buffer. - */ - struct Accessor : public NamedObject { - enum class ComponentType { - BYTE = 5120, - - UNSIGNED_BYTE = 5121, - - SHORT = 5122, - - UNSIGNED_SHORT = 5123, - - UNSIGNED_INT = 5125, - - FLOAT = 5126 - }; - - enum class Type { - SCALAR, - - VEC2, - - VEC3, - - VEC4, - - MAT2, - - MAT3, - - MAT4 - }; - - /** - * @brief The index of the bufferView. - * - * When not defined, accessor must be initialized with zeros; `sparse` property or extensions could override zeros with actual values. - */ - int32_t bufferView = -1; - - /** - * @brief The offset relative to the start of the bufferView in bytes. - * - * This must be a multiple of the size of the component datatype. - */ - int64_t byteOffset = 0; - - /** - * @brief The datatype of components in the attribute. - * - * All valid values correspond to WebGL enums. The corresponding typed arrays are `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Uint32Array`, and `Float32Array`, respectively. 5125 (UNSIGNED_INT) is only allowed when the accessor contains indices, i.e., the accessor is only referenced by `primitive.indices`. - */ - ComponentType componentType = ComponentType(); - - /** - * @brief Specifies whether integer data values should be normalized. - * - * Specifies whether integer data values should be normalized (`true`) to [0, 1] (for unsigned types) or [-1, 1] (for signed types), or converted directly (`false`) when they are accessed. This property is defined only for accessors that contain vertex attributes or animation output data. - */ - bool normalized = false; - - /** - * @brief The number of attributes referenced by this accessor. - * - * The number of attributes referenced by this accessor, not to be confused with the number of bytes or number of components. - */ - int64_t count = int64_t(); - - /** - * @brief Specifies if the attribute is a scalar, vector, or matrix. - */ - Type type = Type(); - - /** - * @brief Maximum value of each component in this attribute. - * - * Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. - * - * `normalized` property has no effect on array values: they always correspond to the actual values stored in the buffer. When accessor is sparse, this property must contain max values of accessor data with sparse substitution applied. - */ - std::vector max; - - /** - * @brief Minimum value of each component in this attribute. - * - * Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. - * - * `normalized` property has no effect on array values: they always correspond to the actual values stored in the buffer. When accessor is sparse, this property must contain min values of accessor data with sparse substitution applied. - */ - std::vector min; - - /** - * @brief Sparse storage of attributes that deviate from their initialization value. - */ - std::optional sparse; - + /** @copydoc AccessorSpec */ + struct Accessor : public AccessorSpec { }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorSpec.h b/CesiumGltf/include/CesiumGltf/AccessorSpec.h new file mode 100644 index 000000000..658039b67 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/AccessorSpec.h @@ -0,0 +1,110 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/AccessorSparse.h" +#include "CesiumGltf/NamedObject.h" +#include +#include +#include + +namespace CesiumGltf { + /** + * @brief A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides a typed view into a bufferView or a subset of a bufferView similar to how WebGL's `vertexAttribPointer()` defines an attribute in a buffer. + */ + struct AccessorSpec : public NamedObject { + enum class ComponentType { + BYTE = 5120, + + UNSIGNED_BYTE = 5121, + + SHORT = 5122, + + UNSIGNED_SHORT = 5123, + + UNSIGNED_INT = 5125, + + FLOAT = 5126 + }; + + enum class Type { + SCALAR, + + VEC2, + + VEC3, + + VEC4, + + MAT2, + + MAT3, + + MAT4 + }; + + /** + * @brief The index of the bufferView. + * + * When not defined, accessor must be initialized with zeros; `sparse` property or extensions could override zeros with actual values. + */ + int32_t bufferView = -1; + + /** + * @brief The offset relative to the start of the bufferView in bytes. + * + * This must be a multiple of the size of the component datatype. + */ + int64_t byteOffset = 0; + + /** + * @brief The datatype of components in the attribute. + * + * All valid values correspond to WebGL enums. The corresponding typed arrays are `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Uint32Array`, and `Float32Array`, respectively. 5125 (UNSIGNED_INT) is only allowed when the accessor contains indices, i.e., the accessor is only referenced by `primitive.indices`. + */ + ComponentType componentType = ComponentType(); + + /** + * @brief Specifies whether integer data values should be normalized. + * + * Specifies whether integer data values should be normalized (`true`) to [0, 1] (for unsigned types) or [-1, 1] (for signed types), or converted directly (`false`) when they are accessed. This property is defined only for accessors that contain vertex attributes or animation output data. + */ + bool normalized = false; + + /** + * @brief The number of attributes referenced by this accessor. + * + * The number of attributes referenced by this accessor, not to be confused with the number of bytes or number of components. + */ + int64_t count = int64_t(); + + /** + * @brief Specifies if the attribute is a scalar, vector, or matrix. + */ + Type type = Type(); + + /** + * @brief Maximum value of each component in this attribute. + * + * Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. + * + * `normalized` property has no effect on array values: they always correspond to the actual values stored in the buffer. When accessor is sparse, this property must contain max values of accessor data with sparse substitution applied. + */ + std::vector max; + + /** + * @brief Minimum value of each component in this attribute. + * + * Array elements must be treated as having the same data type as accessor's `componentType`. Both min and max arrays have the same length. The length is determined by the value of the type property; it can be 1, 2, 3, 4, 9, or 16. + * + * `normalized` property has no effect on array values: they always correspond to the actual values stored in the buffer. When accessor is sparse, this property must contain min values of accessor data with sparse substitution applied. + */ + std::vector min; + + /** + * @brief Sparse storage of attributes that deviate from their initialization value. + */ + std::optional sparse; + + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Buffer.h b/CesiumGltf/include/CesiumGltf/Buffer.h index f76b67912..6d1e90c3d 100644 --- a/CesiumGltf/include/CesiumGltf/Buffer.h +++ b/CesiumGltf/include/CesiumGltf/Buffer.h @@ -1,35 +1,14 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! #pragma once #include "CesiumGltf/BufferCesium.h" -#include "CesiumGltf/NamedObject.h" -#include -#include -#include +#include "CesiumGltf/BufferSpec.h" namespace CesiumGltf { - /** - * @brief A buffer points to binary geometry, animation, or skins. - */ - struct Buffer : public NamedObject { - - /** - * @brief The uri of the buffer. - * - * Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. - */ - std::optional uri; - - /** - * @brief The length of the buffer in bytes. - */ - int64_t byteLength = int64_t(); - + /** @copydoc BufferSpec */ + struct Buffer : public BufferSpec { /** * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. */ BufferCesium cesium; - }; } diff --git a/CesiumGltf/include/CesiumGltf/BufferSpec.h b/CesiumGltf/include/CesiumGltf/BufferSpec.h new file mode 100644 index 000000000..d8a5771c1 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/BufferSpec.h @@ -0,0 +1,29 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" +#include +#include +#include + +namespace CesiumGltf { + /** + * @brief A buffer points to binary geometry, animation, or skins. + */ + struct BufferSpec : public NamedObject { + + /** + * @brief The uri of the buffer. + * + * Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. + */ + std::optional uri; + + /** + * @brief The length of the buffer in bytes. + */ + int64_t byteLength = int64_t(); + + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Image.h b/CesiumGltf/include/CesiumGltf/Image.h index 5ff467ceb..9bfd81c23 100644 --- a/CesiumGltf/include/CesiumGltf/Image.h +++ b/CesiumGltf/include/CesiumGltf/Image.h @@ -1,45 +1,14 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! #pragma once #include "CesiumGltf/ImageCesium.h" -#include "CesiumGltf/NamedObject.h" -#include -#include -#include +#include "CesiumGltf/ImageSpec.h" namespace CesiumGltf { - /** - * @brief Image data used to create a texture. Image can be referenced by URI or `bufferView` index. `mimeType` is required in the latter case. - */ - struct Image : public NamedObject { - enum class MimeType { - image_jpeg, - - image_png - }; - - /** - * @brief The uri of the image. - * - * Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. The image format must be jpg or png. - */ - std::optional uri; - - /** - * @brief The image's MIME type. Required if `bufferView` is defined. - */ - std::optional mimeType; - - /** - * @brief The index of the bufferView that contains the image. Use this instead of the image's uri property. - */ - int32_t bufferView = -1; - + /** @copydoc ImageSpec */ + struct Image : public ImageSpec { /** * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. */ ImageCesium cesium; - }; } diff --git a/CesiumGltf/include/CesiumGltf/ImageSpec.h b/CesiumGltf/include/CesiumGltf/ImageSpec.h new file mode 100644 index 000000000..d76f42dd0 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/ImageSpec.h @@ -0,0 +1,39 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/NamedObject.h" +#include +#include +#include + +namespace CesiumGltf { + /** + * @brief Image data used to create a texture. Image can be referenced by URI or `bufferView` index. `mimeType` is required in the latter case. + */ + struct ImageSpec : public NamedObject { + enum class MimeType { + image_jpeg, + + image_png + }; + + /** + * @brief The uri of the image. + * + * Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. The image format must be jpg or png. + */ + std::optional uri; + + /** + * @brief The image's MIME type. Required if `bufferView` is defined. + */ + std::optional mimeType; + + /** + * @brief The index of the bufferView that contains the image. Use this instead of the image's uri property. + */ + int32_t bufferView = -1; + + }; +} diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index 57374f7dc..7c8fbfd57 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -1,134 +1,9 @@ -// This file was generated by generate-gltf-classes. -// DO NOT EDIT THIS FILE! #pragma once -#include "CesiumGltf/Accessor.h" -#include "CesiumGltf/Animation.h" -#include "CesiumGltf/Asset.h" -#include "CesiumGltf/Buffer.h" -#include "CesiumGltf/BufferView.h" -#include "CesiumGltf/Camera.h" -#include "CesiumGltf/ExtensibleObject.h" -#include "CesiumGltf/Image.h" -#include "CesiumGltf/Material.h" -#include "CesiumGltf/Mesh.h" -#include "CesiumGltf/Node.h" -#include "CesiumGltf/Sampler.h" -#include "CesiumGltf/Scene.h" -#include "CesiumGltf/Skin.h" -#include "CesiumGltf/Texture.h" -#include -#include -#include +#include "CesiumGltf/ModelSpec.h" namespace CesiumGltf { - /** - * @brief The root object for a glTF asset. - */ - struct Model : public ExtensibleObject { - - /** - * @brief Names of glTF extensions used somewhere in this asset. - */ - std::vector extensionsUsed; - - /** - * @brief Names of glTF extensions required to properly load this asset. - */ - std::vector extensionsRequired; - - /** - * @brief An array of accessors. - * - * An accessor is a typed view into a bufferView. - */ - std::vector accessors; - - /** - * @brief An array of keyframe animations. - */ - std::vector animations; - - /** - * @brief Metadata about the glTF asset. - */ - Asset asset; - - /** - * @brief An array of buffers. - * - * A buffer points to binary geometry, animation, or skins. - */ - std::vector buffers; - - /** - * @brief An array of bufferViews. - * - * A bufferView is a view into a buffer generally representing a subset of the buffer. - */ - std::vector bufferViews; - - /** - * @brief An array of cameras. - * - * A camera defines a projection matrix. - */ - std::vector cameras; - - /** - * @brief An array of images. - * - * An image defines data used to create a texture. - */ - std::vector images; - - /** - * @brief An array of materials. - * - * A material defines the appearance of a primitive. - */ - std::vector materials; - - /** - * @brief An array of meshes. - * - * A mesh is a set of primitives to be rendered. - */ - std::vector meshes; - - /** - * @brief An array of nodes. - */ - std::vector nodes; - - /** - * @brief An array of samplers. - * - * A sampler contains properties for texture filtering and wrapping modes. - */ - std::vector samplers; - - /** - * @brief The index of the default scene. - */ - int32_t scene = -1; - - /** - * @brief An array of scenes. - */ - std::vector scenes; - - /** - * @brief An array of skins. - * - * A skin is defined by joints and matrices. - */ - std::vector skins; - - /** - * @brief An array of textures. - */ - std::vector textures; - + /** @copydoc ModelSpec */ + struct Model : public ModelSpec { }; } diff --git a/CesiumGltf/include/CesiumGltf/ModelSpec.h b/CesiumGltf/include/CesiumGltf/ModelSpec.h new file mode 100644 index 000000000..c169cf018 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/ModelSpec.h @@ -0,0 +1,134 @@ +// This file was generated by generate-gltf-classes. +// DO NOT EDIT THIS FILE! +#pragma once + +#include "CesiumGltf/Accessor.h" +#include "CesiumGltf/Animation.h" +#include "CesiumGltf/Asset.h" +#include "CesiumGltf/Buffer.h" +#include "CesiumGltf/BufferView.h" +#include "CesiumGltf/Camera.h" +#include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Image.h" +#include "CesiumGltf/Material.h" +#include "CesiumGltf/Mesh.h" +#include "CesiumGltf/Node.h" +#include "CesiumGltf/Sampler.h" +#include "CesiumGltf/Scene.h" +#include "CesiumGltf/Skin.h" +#include "CesiumGltf/Texture.h" +#include +#include +#include + +namespace CesiumGltf { + /** + * @brief The root object for a glTF asset. + */ + struct ModelSpec : public ExtensibleObject { + + /** + * @brief Names of glTF extensions used somewhere in this asset. + */ + std::vector extensionsUsed; + + /** + * @brief Names of glTF extensions required to properly load this asset. + */ + std::vector extensionsRequired; + + /** + * @brief An array of accessors. + * + * An accessor is a typed view into a bufferView. + */ + std::vector accessors; + + /** + * @brief An array of keyframe animations. + */ + std::vector animations; + + /** + * @brief Metadata about the glTF asset. + */ + Asset asset; + + /** + * @brief An array of buffers. + * + * A buffer points to binary geometry, animation, or skins. + */ + std::vector buffers; + + /** + * @brief An array of bufferViews. + * + * A bufferView is a view into a buffer generally representing a subset of the buffer. + */ + std::vector bufferViews; + + /** + * @brief An array of cameras. + * + * A camera defines a projection matrix. + */ + std::vector cameras; + + /** + * @brief An array of images. + * + * An image defines data used to create a texture. + */ + std::vector images; + + /** + * @brief An array of materials. + * + * A material defines the appearance of a primitive. + */ + std::vector materials; + + /** + * @brief An array of meshes. + * + * A mesh is a set of primitives to be rendered. + */ + std::vector meshes; + + /** + * @brief An array of nodes. + */ + std::vector nodes; + + /** + * @brief An array of samplers. + * + * A sampler contains properties for texture filtering and wrapping modes. + */ + std::vector samplers; + + /** + * @brief The index of the default scene. + */ + int32_t scene = -1; + + /** + * @brief An array of scenes. + */ + std::vector scenes; + + /** + * @brief An array of skins. + * + * A skin is defined by joints and matrices. + */ + std::vector skins; + + /** + * @brief An array of textures. + */ + std::vector textures; + + }; +} diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index 7b945a9a0..26d8a7801 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -8,23 +8,24 @@ const resolveProperty = require("./resolveProperty"); const unindent = require("./unindent"); function generate(options, schema) { - const { schemaCache, nameMapping, outputDir, readerOutputDir, cesiumProperties } = options; + const { schemaCache, config, outputDir, readerOutputDir } = options; - const name = getNameFromSchema(nameMapping, schema); + const name = getNameFromSchema(config, schema); + const thisConfig = config.classes[schema.title] || {}; console.log(`Generating ${name}`); let base = "ExtensibleObject"; if (schema.allOf && schema.allOf.length > 0 && schema.allOf[0].$ref) { const baseSchema = schemaCache.load(schema.allOf[0].$ref); - base = getNameFromSchema(nameMapping, baseSchema); + base = getNameFromSchema(config, baseSchema); } const required = schema.required || []; const properties = Object.keys(schema.properties) .map((key) => - resolveProperty(schemaCache, nameMapping, name, key, schema.properties[key], required) + resolveProperty(schemaCache, config, name, key, schema.properties[key], required) ) .filter((property) => property !== undefined); @@ -41,10 +42,6 @@ function generate(options, schema) { [`"CesiumGltf/${base}.h"`, ...lodash.flatten(properties.map((property) => property.headers))] ); - if (cesiumProperties[name]) { - headers.push(`"CesiumGltf/${name}Cesium.h"`); - } - headers.sort(); const header = ` @@ -58,7 +55,7 @@ function generate(options, schema) { /** * @brief ${schema.description} */ - struct ${name} : public ${base} { + struct ${name}${thisConfig.toBeInherited ? "Spec" : ""} : public ${base} { ${indent(localTypes.join("\n\n"), 16)} ${indent( @@ -69,14 +66,13 @@ function generate(options, schema) { 16 )} - ${indent(getCesiumProperty(cesiumProperties, name, schema), 16)} }; } `; const headerOutputDir = path.join(outputDir, "include", "CesiumGltf"); fs.mkdirSync(headerOutputDir, { recursive: true }); - const headerOutputPath = path.join(headerOutputDir, name + ".h"); + const headerOutputPath = path.join(headerOutputDir, `${name}${thisConfig.toBeInherited ? "Spec" : ""}.h`); fs.writeFileSync(headerOutputPath, unindent(header), "utf-8"); const readerHeaders = lodash.uniq( @@ -228,17 +224,4 @@ function formatReaderPropertyImpl(property) { return `if ("${property.name}"s == str) return property("${property.name}", this->_${property.name}, o.${property.name});`; } -function getCesiumProperty(cesiumProperties, name, schema) { - if (!cesiumProperties[name]) { - return ""; - } - - return unindent(` - /** - * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. - */ - ${name}Cesium cesium; - `); -} - module.exports = generate; diff --git a/tools/generate-gltf-classes/getNameFromSchema.js b/tools/generate-gltf-classes/getNameFromSchema.js index 901f916fa..c864ffd8a 100644 --- a/tools/generate-gltf-classes/getNameFromSchema.js +++ b/tools/generate-gltf-classes/getNameFromSchema.js @@ -1,6 +1,6 @@ -function getNameFromSchema(nameMapping, schema) { +function getNameFromSchema(config, schema) { const title = schema.title; - return nameMapping[title] ? nameMapping[title] : title.replace(/\s/g, ""); + return config.classes[title] && config.classes[title].overrideName ? config.classes[title].overrideName : title.replace(/\s/g, ""); } module.exports = getNameFromSchema; \ No newline at end of file diff --git a/tools/generate-gltf-classes/glTF.json b/tools/generate-gltf-classes/glTF.json new file mode 100644 index 000000000..98b43b0c2 --- /dev/null +++ b/tools/generate-gltf-classes/glTF.json @@ -0,0 +1,33 @@ +{ + "classes": { + "glTF": { + "overrideName": "Model", + "toBeInherited": true + }, + "glTF Property": { + "overrideName": "ExtensibleObject" + }, + "glTF Child of Root Property": { + "overrideName": "NamedObject" + }, + "Buffer": { + "toBeInherited": true + }, + "Image": { + "toBeInherited": true + }, + "Accessor": { + "toBeInherited": true + } + }, + "extensions": [ + { + "className": "KHR_draco_mesh_compression", + "extensionName": "KHR_draco_mesh_compression", + "schema": "Khronos/KHR_draco_mesh_compression/schema/mesh.primitive.KHR_draco_mesh_compression.schema.json", + "attachTo": [ + "mesh.primitive" + ] + } + ] +} diff --git a/tools/generate-gltf-classes/index.js b/tools/generate-gltf-classes/index.js index d3ad5d25d..cd3d0a1c9 100644 --- a/tools/generate-gltf-classes/index.js +++ b/tools/generate-gltf-classes/index.js @@ -1,7 +1,8 @@ const yargs = require("yargs"); const path = require("path"); +const fs = require("fs"); const SchemaCache = require("./SchemaCache"); -const generate = require("./generate") +const generate = require("./generate"); const argv = yargs.options({ schema: { @@ -27,33 +28,25 @@ const argv = yargs.options({ description: "The extensions directory.", demandOption: true, type: "string" + }, + config: { + alias: "c", + description: "The path to the configuration options controlling code generation, expressed in a JSON file.", + demandOption: true, + type: "string" } }).argv; -const nameMapping = { - "glTF": "Model", - "glTF Id": "ExtensibleObject", - "glTFRootProperty": "NamedObject", - "glTF Property": "ExtensibleObject", - "glTF Child of Root Property": "NamedObject" -}; - -// Custom `cesium` properties will be added to these objects. -// e.g. Buffer will gain `BufferCesium cesium;` -const cesiumProperties = { - "Buffer": true, - "Image": true -}; - const schemaCache = new SchemaCache(argv.schema, argv.extensions); const modelSchema = schemaCache.load("glTF.schema.json"); +const config = JSON.parse(fs.readFileSync(argv.config, "utf-8")); + const options = { schemaCache, - nameMapping, - cesiumProperties, outputDir: argv.output, readerOutputDir: argv.readerOutput, + config: config, // key: Title of the element name that is extended (e.g. "Mesh Primitive") // value: Array of extension type names. extensions: {} @@ -61,25 +54,18 @@ const options = { let schemas = [modelSchema]; -const extensionInfo = { - "KHR_draco_mesh_compression": { - extensionName: "KHR_draco_mesh_compression", - schema: "Khronos/KHR_draco_mesh_compression/schema/mesh.primitive.KHR_draco_mesh_compression.schema.json", - attachTo: [ - "mesh.primitive" - ] - } -}; - -for (const extensionClassName of Object.keys(extensionInfo)) { - const extension = extensionInfo[extensionClassName]; +for (const extension of config.extensions) { const extensionSchema = schemaCache.loadExtension(extension.schema); if (!extensionSchema) { - console.warn(`Could not load schema ${inExtensions[extensionClassName]} for extension class ${extensionClassName}.`); + console.warn(`Could not load schema ${extension.schema} for extension class ${extension.className}.`); continue; } - nameMapping[extensionSchema.title] = extensionClassName; + if (!config.classes[extensionSchema.title]) { + config.classes[extensionSchema.title] = {}; + } + config.classes[extensionSchema.title].overrideName = extension.className; + schemas.push(...generate(options, extensionSchema)); for (const objectToExtend of extension.attachTo) { @@ -95,7 +81,7 @@ for (const extensionClassName of Object.keys(extensionInfo)) { options.extensions[objectToExtendSchema.title].push({ name: extension.extensionName, - className: extensionClassName + className: extension.className }); } } diff --git a/tools/generate-gltf-classes/package.json b/tools/generate-gltf-classes/package.json index b0ba3a874..5b17ed7a5 100644 --- a/tools/generate-gltf-classes/package.json +++ b/tools/generate-gltf-classes/package.json @@ -4,7 +4,8 @@ "description": "Generate CesiumGltf C++ classes from the glTF spec.", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "node index.js --schema ../../extern/glTF/specification/2.0/schema/ --output test_output/model --readerOutput test_output/reader --extensions ../../extern/glTF/extensions/2.0 --config glTF.json", + "generate": "node index.js --schema ../../extern/glTF/specification/2.0/schema/ --output ../../CesiumGltf --readerOutput ../../CesiumGltfReader --extensions ../../extern/glTF/extensions/2.0 --config glTF.json" }, "author": "CesiumGS, Inc.", "license": "UNLICENSED", diff --git a/tools/generate-gltf-classes/resolveProperty.js b/tools/generate-gltf-classes/resolveProperty.js index 9bc20e364..4e37551e2 100644 --- a/tools/generate-gltf-classes/resolveProperty.js +++ b/tools/generate-gltf-classes/resolveProperty.js @@ -5,7 +5,7 @@ const makeIdentifier = require("./makeIdentifier"); function resolveProperty( schemaCache, - nameMapping, + config, parentName, propertyName, propertyDetails, @@ -24,7 +24,7 @@ function resolveProperty( if (propertyDetails.type == "array") { return resolveArray( schemaCache, - nameMapping, + config, parentName, propertyName, propertyDetails, @@ -71,7 +71,7 @@ function resolveProperty( ) { return resolveDictionary( schemaCache, - nameMapping, + config, parentName, propertyName, propertyDetails, @@ -84,7 +84,7 @@ function resolveProperty( ) { return resolveEnum( schemaCache, - nameMapping, + config, parentName, propertyName, propertyDetails, @@ -102,8 +102,8 @@ function resolveProperty( readerType: "IntegerJsonHandler", }; } else { - const type = getNameFromSchema(nameMapping, itemSchema); - const typeName = getNameFromSchema(nameMapping, itemSchema); + const type = getNameFromSchema(config, itemSchema); + const typeName = getNameFromSchema(config, itemSchema); return { ...propertyDefaults(propertyName, propertyDetails), @@ -117,7 +117,7 @@ function resolveProperty( } else if (propertyDetails.allOf && propertyDetails.allOf.length == 1) { const nested = resolveProperty( schemaCache, - nameMapping, + config, parentName, propertyName, propertyDetails.allOf[0], @@ -172,7 +172,7 @@ function propertyDefaults(propertyName, propertyDetails) { function resolveArray( schemaCache, - nameMapping, + config, parentName, propertyName, propertyDetails, @@ -180,7 +180,7 @@ function resolveArray( ) { const itemProperty = resolveProperty( schemaCache, - nameMapping, + config, parentName, propertyName + ".items", propertyDetails.items, @@ -206,7 +206,7 @@ function resolveArray( function resolveDictionary( schemaCache, - nameMapping, + config, parentName, propertyName, propertyDetails, @@ -214,7 +214,7 @@ function resolveDictionary( ) { const additional = resolveProperty( schemaCache, - nameMapping, + config, parentName, propertyName + ".additionalProperties", propertyDetails.additionalProperties, @@ -239,7 +239,7 @@ function resolveDictionary( function resolveEnum( schemaCache, - nameMapping, + config, parentName, propertyName, propertyDetails, From 3bd988f0e4f9da69a45acf162c06b0795433eddd Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 18 Jan 2021 23:22:12 +1100 Subject: [PATCH 40/61] Remove Helpers entirely. --- CesiumGltf/include/CesiumGltf/Accessor.h | 72 +++++++++++++++ CesiumGltf/include/CesiumGltf/AccessorView.h | 1 - CesiumGltf/include/CesiumGltf/Helpers.h | 93 -------------------- CesiumGltf/include/CesiumGltf/Model.h | 51 +++++++++++ CesiumGltf/src/Accessor.cpp | 66 ++++++++++++++ CesiumGltf/src/Helpers.cpp | 51 ----------- CesiumGltfReader/src/Reader.cpp | 5 +- CesiumGltfReader/src/decodeDraco.cpp | 11 ++- 8 files changed, 196 insertions(+), 154 deletions(-) delete mode 100644 CesiumGltf/include/CesiumGltf/Helpers.h create mode 100644 CesiumGltf/src/Accessor.cpp delete mode 100644 CesiumGltf/src/Helpers.cpp diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index e5c7ef10f..5c0290434 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -1,9 +1,81 @@ #pragma once #include "CesiumGltf/AccessorSpec.h" +#include namespace CesiumGltf { + struct Model; + /** @copydoc AccessorSpec */ struct Accessor : public AccessorSpec { + /** + * @brief Computes the number of components for a given accessor type. + * + * For example `CesiumGltf::Accessor::Type::SCALAR` has 1 component while + * `CesiumGltf::Accessor::Type::VEC4` has 4 components. + * + * @param type The accessor type. + * @return The number of components. Returns 0 if {@link Accessor::type} is not a valid enumeration value. + */ + static int8_t computeNumberOfComponents(CesiumGltf::Accessor::Type type); + + /** + * @brief Computes the number of bytes for a given accessor component type. + * + * For example `CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT` is 2 bytes while + * `CesiumGltf::Accessor::ComponentType::FLOAT` is 4 bytes. + * + * @param componentType The accessor component type. + * @return The number of bytes for the component type. Returns 0 if {@link Accessor::componentType} is not a valid enumation value. + */ + static int8_t computeByteSizeOfComponent(CesiumGltf::Accessor::ComponentType componentType); + + /** + * @brief Computes the number of components for this accessor. + * + * For example if this accessor's {@link Accessor::type} is `CesiumGltf::Accessor::Type::SCALAR`, then it has 1 component, + * while if it's `CesiumGltf::Accessor::Type::VEC4` it has 4 components. + * + * @return The number of components in this accessor. Returns 0 if this accessor's {@link Accessor::type} does not have a valid + * enumeration value. + */ + int8_t computeNumberOfComponents() const; + + /** + * @brief Computes the number of bytes for this accessor's component type. + * + * For example if this accessor's {@link Accessor::componentType} is `CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT`, + * then the component type is 2 bytes, while if it's `CesiumGltf::Accessor::ComponentType::FLOAT` then it is 4 bytes. + * + * @return The number of bytes for this accessor's component type. Returns 0 if this accessor's {@link Accessor::componentType} does not + * have a valid enumeration value. + */ + int8_t computeByteSizeOfComponent() const; + + /** + * @brief Computes the total number of bytes for this accessor in each vertex. + * + * This is computed by multiplying {@link Accessor::computeByteSizeOfComponent} by {@link Accessor::computeNumberOfComponents}. + * + * @return The total number of bytes for this accessor in each vertex. Returns 0 if this accessor's {@link Accessor::type} or + * {@link Accessor::componentType} does not have a valid enumeration value. + */ + int64_t computeBytesPerVertex() const; + + /** + * @brief Computes this accessor's stride. + * + * The stride is the number of bytes between the same elements of successive vertices. The returned + * value will be at least as large as {@link Accessor::computeBytesPerVertex}, but maybe be larger if + * this accessor's data is interleaved with other accessors. + * + * The behavior is undefined if this accessor is not part of the given model. + * + * @param model The model that this accessor is a part of. + * @return The stride in bytes. Returns 0 if this accessor's {@link Accessor::type} or + * {@link Accessor::componentType} does not have a valid enumeration value, or if + * {@link Accessor::bufferView} does not refer to a valid {@link BufferView}. + */ + int64_t computeByteStride(const CesiumGltf::Model& model) const; }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorView.h b/CesiumGltf/include/CesiumGltf/AccessorView.h index a1868659b..73026bb93 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorView.h +++ b/CesiumGltf/include/CesiumGltf/AccessorView.h @@ -1,7 +1,6 @@ #pragma once #include "CesiumGltf/Model.h" -#include "CesiumGltf/Helpers.h" #include namespace CesiumGltf { diff --git a/CesiumGltf/include/CesiumGltf/Helpers.h b/CesiumGltf/include/CesiumGltf/Helpers.h deleted file mode 100644 index b37d8d638..000000000 --- a/CesiumGltf/include/CesiumGltf/Helpers.h +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once - -#include "CesiumGltf/Accessor.h" -#include - -namespace CesiumGltf { - struct BufferView; - - /** - * @brief Computes the number of components for a given accessor type. - * - * For example `CesiumGltf::Accessor::Type::SCALAR` has 1 component while - * `CesiumGltf::Accessor::Type::VEC4` has 4 components. - * - * @param type The accessor type. - * @return The number of components. - */ - int8_t computeNumberOfComponents(CesiumGltf::Accessor::Type type); - - /** - * @brief Returns the number of bytes for a given accessor component type. - * - * For example `CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT` is 2 bytes while - * `CesiumGltf::Accessor::ComponentType::FLOAT` is 4 bytes. - * - * @param componentType The accessor component type. - * @return The number of bytes for the component type. - */ - int8_t computeByteSizeOfComponent(CesiumGltf::Accessor::ComponentType componentType); - - /** - * @brief Computes the stride for a given {@link Accessor} and {@link BufferView}. - * - * The stride is the number of bytes between the same elements of successive vertices. - * - * @param accessor The accessor. - * @param bufferView The buffer view. - * @return The stride in bytes. - */ - int64_t computeByteStride(const CesiumGltf::Accessor& accessor, const CesiumGltf::BufferView& bufferView); - - /** - * @brief Safely gets the element with a given index, returning a default instance if the index is outside the range. - * - * @tparam T The type of the array. - * @param items The array. - * @param index The index of the array element to retrieve. - * @return The requested element, or a default instance if the index is invalid. - */ - template - static const T& getSafe(const std::vector& items, int32_t index) { - static T default; - if (index < 0 || static_cast(index) >= items.size()) { - return default; - } else { - return items[index]; - } - } - - /** - * @brief Safely gets a pointer to the element with a given index, returning `nullptr` if the index is outside the range. - * - * @tparam T The type of the array. - * @param items The array. - * @param index The index of the array element to retrieve. - * @return A pointer to the requested element, or `nullptr` if the index is invalid. - */ - template - static const T* getSafe(const std::vector* pItems, int32_t index) { - if (index < 0 || static_cast(index) >= pItems->size()) { - return nullptr; - } else { - return &(*pItems)[index]; - } - } - - /** - * @brief Safely gets a pointer to the element with a given index, returning `nullptr` if the index is outside the range. - * - * @tparam T The type of the array. - * @param items The array. - * @param index The index of the array element to retrieve. - * @return A pointer to the requested element, or `nullptr` if the index is invalid. - */ - template - static T* getSafe(std::vector* pItems, int32_t index) { - if (index < 0 || static_cast(index) >= pItems->size()) { - return nullptr; - } else { - return &(*pItems)[index]; - } - } -} diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index 7c8fbfd57..8de11d58c 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -5,5 +5,56 @@ namespace CesiumGltf { /** @copydoc ModelSpec */ struct Model : public ModelSpec { + /** + * @brief Safely gets the element with a given index, returning a default instance if the index is outside the range. + * + * @tparam T The type of the array. + * @param items The array. + * @param index The index of the array element to retrieve. + * @return The requested element, or a default instance if the index is invalid. + */ + template + static const T& getSafe(const std::vector& items, int32_t index) { + static T default; + if (index < 0 || static_cast(index) >= items.size()) { + return default; + } else { + return items[index]; + } + } + + /** + * @brief Safely gets a pointer to the element with a given index, returning `nullptr` if the index is outside the range. + * + * @tparam T The type of the array. + * @param items The array. + * @param index The index of the array element to retrieve. + * @return A pointer to the requested element, or `nullptr` if the index is invalid. + */ + template + static const T* getSafe(const std::vector* pItems, int32_t index) { + if (index < 0 || static_cast(index) >= pItems->size()) { + return nullptr; + } else { + return &(*pItems)[index]; + } + } + + /** + * @brief Safely gets a pointer to the element with a given index, returning `nullptr` if the index is outside the range. + * + * @tparam T The type of the array. + * @param items The array. + * @param index The index of the array element to retrieve. + * @return A pointer to the requested element, or `nullptr` if the index is invalid. + */ + template + static T* getSafe(std::vector* pItems, int32_t index) { + if (index < 0 || static_cast(index) >= pItems->size()) { + return nullptr; + } else { + return &(*pItems)[index]; + } + } }; } diff --git a/CesiumGltf/src/Accessor.cpp b/CesiumGltf/src/Accessor.cpp new file mode 100644 index 000000000..6836c03a0 --- /dev/null +++ b/CesiumGltf/src/Accessor.cpp @@ -0,0 +1,66 @@ +#include "CesiumGltf/Accessor.h" +#include "CesiumGltf/Model.h" + +using namespace CesiumGltf; + +/*static*/ int8_t Accessor::computeNumberOfComponents(CesiumGltf::Accessor::Type type) { + switch (type) { + case CesiumGltf::Accessor::Type::SCALAR: + return 1; + case CesiumGltf::Accessor::Type::VEC2: + return 2; + case CesiumGltf::Accessor::Type::VEC3: + return 3; + case CesiumGltf::Accessor::Type::VEC4: + return 4; + case CesiumGltf::Accessor::Type::MAT2: + return 4; + case CesiumGltf::Accessor::Type::MAT3: + return 9; + case CesiumGltf::Accessor::Type::MAT4: + return 16; + default: + return 0; + } +} + +/*static*/ int8_t Accessor::computeByteSizeOfComponent(CesiumGltf::Accessor::ComponentType componentType) { + switch (componentType) { + case CesiumGltf::Accessor::ComponentType::BYTE: + case CesiumGltf::Accessor::ComponentType::UNSIGNED_BYTE: + return 1; + case CesiumGltf::Accessor::ComponentType::SHORT: + case CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT: + return 2; + case CesiumGltf::Accessor::ComponentType::UNSIGNED_INT: + case CesiumGltf::Accessor::ComponentType::FLOAT: + return 4; + default: + return 0; + } +} + +int8_t Accessor::computeNumberOfComponents() const { + return Accessor::computeNumberOfComponents(this->type); +} + +int8_t Accessor::computeByteSizeOfComponent() const { + return Accessor::computeByteSizeOfComponent(this->componentType); +} + +int64_t Accessor::computeBytesPerVertex() const { + return this->computeByteSizeOfComponent() * this->computeNumberOfComponents(); +} + +int64_t Accessor::computeByteStride(const CesiumGltf::Model& model) const { + const BufferView* pBufferView = Model::getSafe(&model.bufferViews, this->bufferView); + if (!pBufferView) { + return 0; + } + + if (pBufferView->byteStride) { + return pBufferView->byteStride.value(); + } else { + return computeNumberOfComponents(this->type) * computeByteSizeOfComponent(this->componentType); + } +} diff --git a/CesiumGltf/src/Helpers.cpp b/CesiumGltf/src/Helpers.cpp deleted file mode 100644 index afd069233..000000000 --- a/CesiumGltf/src/Helpers.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "CesiumGltf/Helpers.h" -#include "CesiumGltf/BufferView.h" - -namespace CesiumGltf { - -int8_t computeNumberOfComponents(CesiumGltf::Accessor::Type type) { - switch (type) { - case CesiumGltf::Accessor::Type::SCALAR: - return 1; - case CesiumGltf::Accessor::Type::VEC2: - return 2; - case CesiumGltf::Accessor::Type::VEC3: - return 3; - case CesiumGltf::Accessor::Type::VEC4: - return 4; - case CesiumGltf::Accessor::Type::MAT2: - return 4; - case CesiumGltf::Accessor::Type::MAT3: - return 9; - case CesiumGltf::Accessor::Type::MAT4: - return 16; - default: - return 0; - } -} - -int8_t computeByteSizeOfComponent(CesiumGltf::Accessor::ComponentType componentType) { - switch (componentType) { - case CesiumGltf::Accessor::ComponentType::BYTE: - case CesiumGltf::Accessor::ComponentType::UNSIGNED_BYTE: - return 1; - case CesiumGltf::Accessor::ComponentType::SHORT: - case CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT: - return 2; - case CesiumGltf::Accessor::ComponentType::UNSIGNED_INT: - case CesiumGltf::Accessor::ComponentType::FLOAT: - return 4; - default: - return 0; - } -} - -int64_t computeByteStride(const CesiumGltf::Accessor& accessor, const CesiumGltf::BufferView& bufferView) { - if (bufferView.byteStride) { - return bufferView.byteStride.value(); - } else { - return computeNumberOfComponents(accessor.type) * computeByteSizeOfComponent(accessor.componentType); - } -} - -} \ No newline at end of file diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 1ccda0397..a24f55de1 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -1,4 +1,3 @@ -#include "CesiumGltf/Helpers.h" #include "CesiumGltf/Reader.h" #include "JsonHandler.h" #include "ModelJsonHandler.h" @@ -283,8 +282,8 @@ namespace { if (options.decodeEmbeddedImages) { for (Image& image : model.images) { - const BufferView& bufferView = getSafe(model.bufferViews, image.bufferView); - const Buffer& buffer = getSafe(model.buffers, bufferView.buffer); + const BufferView& bufferView = Model::getSafe(model.bufferViews, image.bufferView); + const Buffer& buffer = Model::getSafe(model.buffers, bufferView.buffer); if (bufferView.byteOffset + bufferView.byteLength > static_cast(buffer.cesium.data.size())) { if (!readModel.warnings.empty()) readModel.warnings += "\n"; diff --git a/CesiumGltfReader/src/decodeDraco.cpp b/CesiumGltfReader/src/decodeDraco.cpp index 84a9ba804..8b2a79f1a 100644 --- a/CesiumGltfReader/src/decodeDraco.cpp +++ b/CesiumGltfReader/src/decodeDraco.cpp @@ -2,7 +2,6 @@ #include "CesiumGltf/Model.h" #include "CesiumGltf/KHR_draco_mesh_compression.h" #include "CesiumGltf/Reader.h" -#include "CesiumGltf/Helpers.h" #include #pragma warning(push) @@ -83,7 +82,7 @@ namespace { return; } - Accessor* pIndicesAccessor = getSafe(&model.accessors, primitive.indices); + Accessor* pIndicesAccessor = Model::getSafe(&model.accessors, primitive.indices); if (!pIndicesAccessor) { if (!readModel.warnings.empty()) readModel.warnings += "\n"; readModel.warnings += "Primitive indices accessor ID is invalid."; @@ -103,7 +102,7 @@ namespace { indicesBufferView.buffer = static_cast(model.buffers.size()); Buffer& indicesBuffer = model.buffers.emplace_back(); - int64_t indexBytes = computeByteSizeOfComponent(pIndicesAccessor->componentType); + int64_t indexBytes = pIndicesAccessor->computeByteSizeOfComponent(); int64_t indicesBytes = pIndicesAccessor->count * indexBytes; indicesBuffer.cesium.data.resize(indicesBytes); @@ -162,8 +161,8 @@ namespace { bufferView.buffer = static_cast(model.buffers.size()); Buffer& buffer = model.buffers.emplace_back(); - int8_t numberOfComponents = computeNumberOfComponents(pAccessor->type); - int64_t stride = numberOfComponents * computeByteSizeOfComponent(pAccessor->componentType); + int8_t numberOfComponents = pAccessor->computeNumberOfComponents(); + int64_t stride = numberOfComponents * pAccessor->computeByteSizeOfComponent(); int64_t sizeBytes = pAccessor->count * stride; buffer.cesium.data.resize(sizeBytes); @@ -234,7 +233,7 @@ namespace { } int32_t primitiveAttrIndex = primitiveAttrIt->second; - Accessor* pAccessor = getSafe(&model.accessors, primitiveAttrIndex); + Accessor* pAccessor = Model::getSafe(&model.accessors, primitiveAttrIndex); if (!pAccessor) { if (!readModel.warnings.empty()) { readModel.warnings += "\n"; From 614b59db21af63728c9f5322216b66719576671c Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 00:15:57 +1100 Subject: [PATCH 41/61] Remove GltfAccessor and GltfWriter. --- .../include/Cesium3DTiles/GltfAccessor.h | 199 ------------------ .../include/Cesium3DTiles/GltfWriter.h | 75 ------- Cesium3DTiles/src/GltfContent.cpp | 24 ++- .../src/upsampleGltfForRasterOverlays.cpp | 138 ++++++------ .../test/TestQuantizedMeshContent.cpp | 56 +++-- .../test/TestUpsampleGltfForRasterOverlay.cpp | 38 ++-- CesiumGltf/include/CesiumGltf/AccessorView.h | 180 ++++++++++++---- .../include/CesiumGltf/AccessorWriter.h | 39 +++- 8 files changed, 309 insertions(+), 440 deletions(-) delete mode 100644 Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h delete mode 100644 Cesium3DTiles/include/Cesium3DTiles/GltfWriter.h diff --git a/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h b/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h deleted file mode 100644 index fb3f56555..000000000 --- a/Cesium3DTiles/include/Cesium3DTiles/GltfAccessor.h +++ /dev/null @@ -1,199 +0,0 @@ -#pragma once - -#include "Gltf.h" -#include - -namespace Cesium3DTiles { - - /** - * @brief A view on the data of one accessor of a glTF asset. - * - * It provides the actual accessor data like an array of elements. - * The type of the accessor elements is determined by the template - * parameter. Instances are created from an input glTF model - * and an accessor index, and the {@link operator[]()} - * can be used to access the elements: - * - * ``` - * CesiumGltf::Model model; - * GltfAccessor positions(model, accessorIndex) - * glm::vec3 position = positions[i]; - * ``` - * - * @tparam T The type of the elements in the accessor. - */ - template - class GltfAccessor final { - private: - const CesiumGltf::Buffer* _pGltfBuffer; - const CesiumGltf::BufferView* _pGltfBufferView; - const CesiumGltf::Accessor* _pGltfAccessor; - const unsigned char* _pBufferViewData; - size_t _stride; - size_t _offset; - size_t _size; - - public: - typedef T value_type; - - /** - * @brief Creates a new instance. - * - * The resulting instance will provide the data of the specified - * accessor from the given model. - * - * @param model The glTF model. - * @param accessorID The ID (index) of the accessor. - * @throws An `std::runtime_error` may be thrown when there are - * inconsistencies in the given model. This may refer to the model - * itself, or to cases where the size of the template parameter `T` - * does not match the size of the elements of the specified accessor. - */ - GltfAccessor(const CesiumGltf::Model& model, size_t accessorID) - { - const CesiumGltf::Accessor& accessor = model.accessors[accessorID]; - const CesiumGltf::BufferView& bufferView = model.bufferViews[accessor.bufferView]; - const CesiumGltf::Buffer& buffer = model.buffers[bufferView.buffer]; - - const std::vector& data = buffer.cesium.data; - int64_t bufferBytes = data.size(); - if (bufferView.byteOffset + bufferView.byteLength > bufferBytes) - { - throw std::runtime_error("bufferView does not fit in buffer."); - } - - int64_t accessorByteStride = computeByteStride(accessor, bufferView); - if (accessorByteStride == -1) - { - throw std::runtime_error("cannot compute accessor byteStride."); - } - - int64_t accessorComponentElements = computeNumberOfComponents(accessor.type); - int64_t accessorComponentBytes = computeByteSizeOfComponent(accessor.componentType); - int64_t accessorBytesPerStride = accessorComponentElements * accessorComponentBytes; - - if (sizeof(T) != accessorBytesPerStride) - { - throw std::runtime_error("sizeof(T) does not much accessor bytes."); - } - - int64_t accessorBytes = accessorByteStride * accessor.count; - int64_t bytesRemainingInBufferView = bufferView.byteLength - (accessor.byteOffset + accessorByteStride * (accessor.count - 1) + accessorBytesPerStride); - if (accessorBytes > bufferView.byteLength || bytesRemainingInBufferView < 0) - { - throw std::runtime_error("accessor does not fit in bufferView."); - } - - const unsigned char* pBufferData = &data[0]; - const unsigned char* pBufferViewData = pBufferData + bufferView.byteOffset; - - this->_pGltfBuffer = &buffer; - this->_pGltfBufferView = &bufferView; - this->_pGltfAccessor = &accessor; - this->_stride = accessorByteStride; - this->_offset = accessor.byteOffset; - this->_size = accessor.count; - this->_pBufferViewData = pBufferViewData; - } - - /** - * @brief Provides the specified accessor element. - * - * @param i The index of the element. - * @returns The constant reference to the accessor element. - * @throws A `std::range_error` if the given index is negative - * or not smaller than the {@link size} of this accessor. - */ - const T& operator[](size_t i) const - { - if (i < 0 || i >= this->_size) - { - throw std::range_error("index out of range"); - } - - return *reinterpret_cast(this->_pBufferViewData + i * this->_stride + this->_offset); - } - - /** - * @brief Returns the size (number of elements) of this accessor. - * - * This is the number of elements of type `T` that this accessor contains. - * - * @returns The size. - */ - size_t size() const noexcept - { - return this->_size; - } - - /** - * @brief Returns the underyling buffer implementation. - */ - const CesiumGltf::Buffer& gltfBuffer() const - { - return *this->_pGltfBuffer; - } - - /** - * @brief Returns the underyling buffer view implementation. - */ - const CesiumGltf::BufferView& gltfBufferView() const noexcept - { - return *this->_pGltfBufferView; - } - - /** - * @brief Returns the underyling acessor implementation. - */ - const CesiumGltf::Accessor& gltfAccessor() const noexcept - { - return *this->_pGltfAccessor; - } - - static int64_t computeNumberOfComponents(CesiumGltf::Accessor::Type type) { - switch (type) { - case CesiumGltf::Accessor::Type::SCALAR: - return 1; - case CesiumGltf::Accessor::Type::VEC2: - return 2; - case CesiumGltf::Accessor::Type::VEC3: - return 3; - case CesiumGltf::Accessor::Type::VEC4: - return 4; - case CesiumGltf::Accessor::Type::MAT2: - return 4; - case CesiumGltf::Accessor::Type::MAT3: - return 9; - case CesiumGltf::Accessor::Type::MAT4: - return 16; - default: - return 0; - } - } - - static int64_t computeByteSizeOfComponent(CesiumGltf::Accessor::ComponentType componentType) { - switch (componentType) { - case CesiumGltf::Accessor::ComponentType::BYTE: - case CesiumGltf::Accessor::ComponentType::UNSIGNED_BYTE: - return 1; - case CesiumGltf::Accessor::ComponentType::SHORT: - case CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT: - return 2; - case CesiumGltf::Accessor::ComponentType::UNSIGNED_INT: - case CesiumGltf::Accessor::ComponentType::FLOAT: - return 4; - default: - return 0; - } - } - - static int64_t computeByteStride(const CesiumGltf::Accessor& accessor, const CesiumGltf::BufferView& bufferView) { - if (bufferView.byteStride) { - return bufferView.byteStride.value(); - } else { - return computeNumberOfComponents(accessor.type) * computeByteSizeOfComponent(accessor.componentType); - } - } - }; - -} \ No newline at end of file diff --git a/Cesium3DTiles/include/Cesium3DTiles/GltfWriter.h b/Cesium3DTiles/include/Cesium3DTiles/GltfWriter.h deleted file mode 100644 index 921057f41..000000000 --- a/Cesium3DTiles/include/Cesium3DTiles/GltfWriter.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -#include "Gltf.h" -#include "GltfAccessor.h" - -#include - -namespace Cesium3DTiles { - - /** - * @brief Provides write access to a {@link GltfAccessor}. - */ - template - class GltfWriter final { - private: - GltfAccessor _accessor; - - public: - - /** @copydoc GltfAccessor::GltfAccessor */ - GltfWriter(CesiumGltf::Model& model, size_t accessorID) : - _accessor(model, accessorID) - { - } - - /** @copydoc GltfAccessor::operator[]() */ - const T& operator[](size_t i) const { - return this->_accessor[i]; - } - - /** @copydoc GltfAccessor::operator[]() */ - T& operator[](size_t i) { - return const_cast(this->_accessor[i]); - } - - /** @copydoc GltfAccessor::size */ - size_t size() const noexcept { - return this->_accessor.size(); - } - - /** @copydoc GltfAccessor::gltfBuffer */ - const CesiumGltf::Buffer& gltfBuffer() const noexcept - { - return this->_accessor.gltfBuffer(); - } - - /** @copydoc GltfAccessor::gltfBuffer */ - CesiumGltf::Buffer& gltfBuffer() noexcept - { - return const_cast(this->_accessor.gltfBuffer()); - } - - /** @copydoc GltfAccessor::gltfBufferView */ - const CesiumGltf::BufferView& gltfBufferView() const noexcept - { - return this->_accessor.gltfBufferView(); - } - - /** @copydoc GltfAccessor::gltfBufferView */ - CesiumGltf::BufferView& gltfBufferView() noexcept { - return const_cast(this->_accessor.gltfBufferView()); - } - - /** @copydoc GltfAccessor::gltfAccessor */ - const CesiumGltf::Accessor& gltfAccessor() const noexcept { - return this->_accessor.gltfAccessor(); - } - - /** @copydoc GltfAccessor::gltfAccessor */ - CesiumGltf::Accessor& gltfAccessor() noexcept { - return const_cast(this->_accessor.gltfAccessor()); - } - }; - -} \ No newline at end of file diff --git a/Cesium3DTiles/src/GltfContent.cpp b/Cesium3DTiles/src/GltfContent.cpp index 4a8c69e2a..9e233a229 100644 --- a/Cesium3DTiles/src/GltfContent.cpp +++ b/Cesium3DTiles/src/GltfContent.cpp @@ -1,7 +1,7 @@ -#include "Cesium3DTiles/GltfAccessor.h" #include "Cesium3DTiles/GltfContent.h" -#include "Cesium3DTiles/GltfWriter.h" #include "Cesium3DTiles/spdlog-cesium.h" +#include "CesiumGltf/AccessorView.h" +#include "CesiumGltf/AccessorWriter.h" #include "CesiumGltf/Reader.h" #include "CesiumUtility/Math.h" #include @@ -61,9 +61,12 @@ namespace Cesium3DTiles { int uvAccessorId = static_cast(accessors.size()); accessors.emplace_back(); - GltfAccessor positionAccessor(gltf, static_cast(positionAccessorIndex)); + CesiumGltf::AccessorView positionView(gltf, positionAccessorIndex); + if (positionView.status() != CesiumGltf::AccessorViewStatus::Valid) { + return -1; + } - uvBuffer.cesium.data.resize(positionAccessor.size() * 2 * sizeof(float)); + uvBuffer.cesium.data.resize(positionView.size() * 2 * sizeof(float)); CesiumGltf::BufferView& uvBufferView = gltf.bufferViews[static_cast(uvBufferViewId)]; uvBufferView.buffer = uvBufferId; @@ -76,17 +79,18 @@ namespace Cesium3DTiles { uvAccessor.bufferView = uvBufferViewId; uvAccessor.byteOffset = 0; uvAccessor.componentType = CesiumGltf::Accessor::ComponentType::FLOAT; - uvAccessor.count = positionAccessor.size(); + uvAccessor.count = positionView.size(); uvAccessor.type = CesiumGltf::Accessor::Type::VEC2; - GltfWriter uvWriter(gltf, static_cast(uvAccessorId)); + CesiumGltf::AccessorWriter uvWriter(gltf, uvAccessorId); + assert(uvWriter.status() == CesiumGltf::AccessorViewStatus::Valid); double width = rectangle.computeWidth(); double height = rectangle.computeHeight(); - for (size_t i = 0; i < positionAccessor.size(); ++i) { + for (int64_t i = 0; i < positionView.size(); ++i) { // Get the ECEF position - glm::vec3 position = positionAccessor[i]; + glm::vec3 position = positionView[i]; glm::dvec3 positionEcef = transform * glm::dvec4(position, 1.0); // Convert it to cartographic @@ -199,6 +203,10 @@ namespace Cesium3DTiles { // Generate new texture coordinates int nextTextureCoordinateAccessorIndex = generateOverlayTextureCoordinates(gltf_, positionAccessorIndex, transform, projection, rectangle, west, south, east, north, minimumHeight, maximumHeight); + if (nextTextureCoordinateAccessorIndex < 0) { + return; + } + primitive.attributes[attributeName] = nextTextureCoordinateAccessorIndex; positionAccessorsToTextureCoordinateAccessor[static_cast(positionAccessorIndex)] = nextTextureCoordinateAccessorIndex; }); diff --git a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp index 52e55bd1f..f79a78b59 100644 --- a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp +++ b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp @@ -1,12 +1,14 @@ -#include "Cesium3DTiles/GltfAccessor.h" #include "CesiumGeometry/clipTriangleAtAxisAlignedThreshold.h" -#include "CesiumUtility/Math.h" -#include "CesiumGeospatial/Ellipsoid.h" #include "CesiumGeospatial/Cartographic.h" -#include "upsampleGltfForRasterOverlays.h" +#include "CesiumGeospatial/Ellipsoid.h" +#include "CesiumGltf/AccessorView.h" +#include "CesiumUtility/Math.h" #include "SkirtMeshMetadata.h" +#include "upsampleGltfForRasterOverlays.h" #include +using namespace CesiumGltf; + namespace Cesium3DTiles { struct EdgeVertex { uint32_t index; @@ -21,10 +23,10 @@ namespace Cesium3DTiles { }; static void upsamplePrimitiveForRasterOverlays( - const CesiumGltf::Model& parentModel, - CesiumGltf::Model& model, - CesiumGltf::Mesh& mesh, - CesiumGltf::MeshPrimitive& primitive, + const Model& parentModel, + Model& model, + Mesh& mesh, + MeshPrimitive& primitive, CesiumGeometry::QuadtreeChild childID ); @@ -53,7 +55,7 @@ namespace Cesium3DTiles { double thresholdV, bool keepAboveU, bool keepAboveV, - const GltfAccessor& uvs, + const AccessorView& uvs, const std::vector& clipVertexToIndices, const std::vector& complements, const std::vector& clipResult); @@ -77,8 +79,8 @@ namespace Cesium3DTiles { size_t vertexSizeFloats, uint32_t positionAttributeIndex); - CesiumGltf::Model upsampleGltfForRasterOverlays(const CesiumGltf::Model& parentModel, CesiumGeometry::QuadtreeChild childID) { - CesiumGltf::Model result; + Model upsampleGltfForRasterOverlays(const Model& parentModel, CesiumGeometry::QuadtreeChild childID) { + Model result; // Copy the entire parent model except for the buffers, bufferViews, and accessors, which we'll be rewriting. result.animations = parentModel.animations; @@ -100,8 +102,8 @@ namespace Cesium3DTiles { // result.extras_json_string = parentModel.extras_json_string; // result.extensions_json_string = parentModel.extensions_json_string; - for (CesiumGltf::Mesh& mesh : result.meshes) { - for (CesiumGltf::MeshPrimitive& primitive : mesh.primitives) { + for (Mesh& mesh : result.meshes) { + for (MeshPrimitive& primitive : mesh.primitives) { upsamplePrimitiveForRasterOverlays(parentModel, result, mesh, primitive, childID); } } @@ -216,9 +218,9 @@ namespace Cesium3DTiles { } template - static T getVertexValue(const GltfAccessor& accessor, const CesiumGeometry::TriangleClipVertex& vertex) { + static T getVertexValue(const AccessorView& accessor, const CesiumGeometry::TriangleClipVertex& vertex) { struct Operation { - const Cesium3DTiles::GltfAccessor& accessor; + const AccessorView& accessor; T operator()(int vertexIndex) { return accessor[static_cast(vertexIndex)]; @@ -235,12 +237,12 @@ namespace Cesium3DTiles { } template - static T getVertexValue(const GltfAccessor& accessor, + static T getVertexValue(const AccessorView& accessor, const std::vector &complements, const CesiumGeometry::TriangleClipVertex& vertex) { struct Operation { - const Cesium3DTiles::GltfAccessor& accessor; + const AccessorView& accessor; const std::vector& complements; T operator()(int vertexIndex) { @@ -277,10 +279,10 @@ namespace Cesium3DTiles { template static void upsamplePrimitiveForRasterOverlays( - const CesiumGltf::Model& parentModel, - CesiumGltf::Model& model, - CesiumGltf::Mesh& /*mesh*/, - CesiumGltf::MeshPrimitive& primitive, + const Model& parentModel, + Model& model, + Mesh& /*mesh*/, + MeshPrimitive& primitive, CesiumGeometry::QuadtreeChild childID ) { // Add up the per-vertex size of all attributes and create buffers, bufferViews, and accessors @@ -299,13 +301,13 @@ namespace Cesium3DTiles { size_t indexBufferViewIndex = model.bufferViews.size(); model.bufferViews.emplace_back(); - CesiumGltf::BufferView& vertexBufferView = model.bufferViews[vertexBufferViewIndex]; + BufferView& vertexBufferView = model.bufferViews[vertexBufferViewIndex]; vertexBufferView.buffer = static_cast(vertexBufferIndex); - vertexBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; + vertexBufferView.target = BufferView::Target::ARRAY_BUFFER; - CesiumGltf::BufferView& indexBufferView = model.bufferViews[indexBufferViewIndex]; + BufferView& indexBufferView = model.bufferViews[indexBufferViewIndex]; indexBufferView.buffer = static_cast(indexBufferIndex); - indexBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; + indexBufferView.target = BufferView::Target::ARRAY_BUFFER; uint32_t vertexSizeFloats = 0; int uvAccessorIndex = -1; @@ -333,33 +335,33 @@ namespace Cesium3DTiles { continue; } - const CesiumGltf::Accessor& accessor = parentModel.accessors[static_cast(attribute.second)]; + const Accessor& accessor = parentModel.accessors[static_cast(attribute.second)]; if (accessor.bufferView < 0 || accessor.bufferView >= static_cast(parentModel.bufferViews.size())) { toRemove.push_back(attribute.first); continue; } - const CesiumGltf::BufferView& bufferView = parentModel.bufferViews[static_cast(accessor.bufferView)]; + const BufferView& bufferView = parentModel.bufferViews[static_cast(accessor.bufferView)]; if (bufferView.buffer < 0 || bufferView.buffer >= static_cast(parentModel.buffers.size())) { toRemove.push_back(attribute.first); continue; } - const CesiumGltf::Buffer& buffer = parentModel.buffers[static_cast(bufferView.buffer)]; + const Buffer& buffer = parentModel.buffers[static_cast(bufferView.buffer)]; - int64_t accessorByteStride = Cesium3DTiles::GltfAccessor::computeByteStride(accessor, bufferView); - int64_t accessorComponentElements = Cesium3DTiles::GltfAccessor::computeNumberOfComponents(accessor.type); - if (accessor.componentType != CesiumGltf::Accessor::ComponentType::FLOAT) { + int64_t accessorByteStride = accessor.computeByteStride(parentModel); + int64_t accessorComponentElements = accessor.computeNumberOfComponents(); + if (accessor.componentType != Accessor::ComponentType::FLOAT) { // Can only interpolate floating point vertex attributes return; } attribute.second = static_cast(model.accessors.size()); model.accessors.emplace_back(); - CesiumGltf::Accessor& newAccessor = model.accessors.back(); + Accessor& newAccessor = model.accessors.back(); newAccessor.bufferView = static_cast(vertexBufferIndex); newAccessor.byteOffset = vertexSizeFloats * sizeof(float); - newAccessor.componentType = CesiumGltf::Accessor::ComponentType::FLOAT; + newAccessor.componentType = Accessor::ComponentType::FLOAT; newAccessor.type = accessor.type; vertexSizeFloats += static_cast(accessorComponentElements); @@ -393,12 +395,16 @@ namespace Cesium3DTiles { bool keepAboveU = childID == CesiumGeometry::QuadtreeChild::LowerRight || childID == CesiumGeometry::QuadtreeChild::UpperRight; bool keepAboveV = childID == CesiumGeometry::QuadtreeChild::UpperLeft || childID == CesiumGeometry::QuadtreeChild::UpperRight; - GltfAccessor uvAccessor(parentModel, static_cast(uvAccessorIndex)); - GltfAccessor indicesAccessor(parentModel, static_cast(primitive.indices)); + AccessorView uvView(parentModel, uvAccessorIndex); + AccessorView indicesView(parentModel, primitive.indices); + + if (uvView.status() != AccessorViewStatus::Valid || indicesView.status() != AccessorViewStatus::Valid) { + return; + } // check if the primitive has skirts size_t indicesBegin = 0; - size_t indicesCount = indicesAccessor.size(); + size_t indicesCount = indicesView.size(); std::optional parentSkirtMeshMetadata = SkirtMeshMetadata::parseFromGltfExtras(primitive.extras); bool hasSkirt = (parentSkirtMeshMetadata != std::nullopt) && (positionAttributeIndex != -1); if (hasSkirt) { @@ -411,7 +417,7 @@ namespace Cesium3DTiles { std::vector clippedB; // Maps old (parentModel) vertex indices to new (model) vertex indices. - std::vector vertexMap(uvAccessor.size(), std::numeric_limits::max()); + std::vector vertexMap(uvView.size(), std::numeric_limits::max()); // std::vector newVertexBuffer(vertexSizeFloats * sizeof(float)); // gsl::span newVertexFloats(reinterpret_cast(newVertexBuffer.data()), newVertexBuffer.size() / sizeof(float)); @@ -420,13 +426,13 @@ namespace Cesium3DTiles { EdgeIndices edgeIndices; for (size_t i = indicesBegin; i < indicesBegin + indicesCount; i += 3) { - TIndex i0 = indicesAccessor[i]; - TIndex i1 = indicesAccessor[i + 1]; - TIndex i2 = indicesAccessor[i + 2]; + TIndex i0 = indicesView[i]; + TIndex i1 = indicesView[i + 1]; + TIndex i2 = indicesView[i + 2]; - glm::vec2 uv0 = uvAccessor[i0]; - glm::vec2 uv1 = uvAccessor[i1]; - glm::vec2 uv2 = uvAccessor[i2]; + glm::vec2 uv0 = uvView[i0]; + glm::vec2 uv1 = uvView[i1]; + glm::vec2 uv2 = uvView[i2]; // Clip this triangle against the East-West boundary clippedA.clear(); @@ -446,16 +452,16 @@ namespace Cesium3DTiles { ~0, ~1, ~2, - getVertexValue(uvAccessor, clippedA[0]).y, - getVertexValue(uvAccessor, clippedA[1]).y, - getVertexValue(uvAccessor, clippedA[2]).y, + getVertexValue(uvView, clippedA[0]).y, + getVertexValue(uvView, clippedA[1]).y, + getVertexValue(uvView, clippedA[2]).y, clippedB ); // Add the clipped triangle or quad, if any addClippedPolygon(newVertexFloats, indices, attributes, vertexMap, clipVertexToIndices, clippedA, clippedB); if (hasSkirt) { - addEdge(edgeIndices, 0.5, 0.5, keepAboveU, keepAboveV, uvAccessor, clipVertexToIndices, clippedA, clippedB); + addEdge(edgeIndices, 0.5, 0.5, keepAboveU, keepAboveV, uvView, clipVertexToIndices, clippedA, clippedB); } // If the East-West clip yielded a quad (rather than a triangle), clip the second triangle of the quad, too. @@ -468,16 +474,16 @@ namespace Cesium3DTiles { ~0, ~2, ~3, - getVertexValue(uvAccessor, clippedA[0]).y, - getVertexValue(uvAccessor, clippedA[2]).y, - getVertexValue(uvAccessor, clippedA[3]).y, + getVertexValue(uvView, clippedA[0]).y, + getVertexValue(uvView, clippedA[2]).y, + getVertexValue(uvView, clippedA[3]).y, clippedB ); // Add the clipped triangle or quad, if any addClippedPolygon(newVertexFloats, indices, attributes, vertexMap, clipVertexToIndices, clippedA, clippedB); if (hasSkirt) { - addEdge(edgeIndices, 0.5, 0.5, keepAboveU, keepAboveV, uvAccessor, clipVertexToIndices, clippedA, clippedB); + addEdge(edgeIndices, 0.5, 0.5, keepAboveU, keepAboveV, uvView, clipVertexToIndices, clippedA, clippedB); } } } @@ -503,7 +509,7 @@ namespace Cesium3DTiles { // Update the accessor vertex counts and min/max values size_t numberOfVertices = newVertexFloats.size() / vertexSizeFloats; for (const FloatVertexAttribute& attribute : attributes) { - CesiumGltf::Accessor& accessor = model.accessors[static_cast(attribute.accessorIndex)]; + Accessor& accessor = model.accessors[static_cast(attribute.accessorIndex)]; accessor.count = numberOfVertices; accessor.min = std::move(attribute.minimums); accessor.max = std::move(attribute.maximums); @@ -512,22 +518,22 @@ namespace Cesium3DTiles { // Add an accessor for the indices size_t indexAccessorIndex = model.accessors.size(); model.accessors.emplace_back(); - CesiumGltf::Accessor& newIndicesAccessor = model.accessors.back(); + Accessor& newIndicesAccessor = model.accessors.back(); newIndicesAccessor.bufferView = static_cast(indexBufferViewIndex); newIndicesAccessor.byteOffset = 0; newIndicesAccessor.count = indices.size(); - newIndicesAccessor.componentType = CesiumGltf::Accessor::ComponentType::UNSIGNED_INT; - newIndicesAccessor.type = CesiumGltf::Accessor::Type::SCALAR; + newIndicesAccessor.componentType = Accessor::ComponentType::UNSIGNED_INT; + newIndicesAccessor.type = Accessor::Type::SCALAR; // Populate the buffers - CesiumGltf::Buffer& vertexBuffer = model.buffers[vertexBufferIndex]; + Buffer& vertexBuffer = model.buffers[vertexBufferIndex]; vertexBuffer.cesium.data.resize(newVertexFloats.size() * sizeof(float)); float* pAsFloats = reinterpret_cast(vertexBuffer.cesium.data.data()); std::copy(newVertexFloats.begin(), newVertexFloats.end(), pAsFloats); vertexBufferView.byteLength = vertexBuffer.cesium.data.size(); vertexBufferView.byteStride = vertexSizeFloats * sizeof(float); - CesiumGltf::Buffer& indexBuffer = model.buffers[indexBufferIndex]; + Buffer& indexBuffer = model.buffers[indexBufferIndex]; indexBuffer.cesium.data.resize(indices.size() * sizeof(uint32_t)); uint32_t* pAsUint32s = reinterpret_cast(indexBuffer.cesium.data.data()); std::copy(indices.begin(), indices.end(), pAsUint32s); @@ -612,7 +618,7 @@ namespace Cesium3DTiles { double thresholdV, bool keepAboveU, bool keepAboveV, - const GltfAccessor& uvs, + const AccessorView& uvs, const std::vector& clipVertexToIndices, const std::vector& complements, const std::vector& clipResult) @@ -839,14 +845,14 @@ namespace Cesium3DTiles { } static void upsamplePrimitiveForRasterOverlays( - const CesiumGltf::Model& parentModel, - CesiumGltf::Model& model, - CesiumGltf::Mesh& mesh, - CesiumGltf::MeshPrimitive& primitive, + const Model& parentModel, + Model& model, + Mesh& mesh, + MeshPrimitive& primitive, CesiumGeometry::QuadtreeChild childID ) { if ( - primitive.mode != CesiumGltf::MeshPrimitive::Mode::TRIANGLES || + primitive.mode != MeshPrimitive::Mode::TRIANGLES || primitive.indices < 0 || primitive.indices >= static_cast(parentModel.accessors.size()) ) { @@ -856,10 +862,10 @@ namespace Cesium3DTiles { return; } - const CesiumGltf::Accessor& indicesAccessorGltf = parentModel.accessors[static_cast(primitive.indices)]; - if (indicesAccessorGltf.componentType == CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT) { + const Accessor& indicesAccessorGltf = parentModel.accessors[static_cast(primitive.indices)]; + if (indicesAccessorGltf.componentType == Accessor::ComponentType::UNSIGNED_SHORT) { upsamplePrimitiveForRasterOverlays(parentModel, model, mesh, primitive, childID); - } else if (indicesAccessorGltf.componentType == CesiumGltf::Accessor::ComponentType::UNSIGNED_INT) { + } else if (indicesAccessorGltf.componentType == Accessor::ComponentType::UNSIGNED_INT) { upsamplePrimitiveForRasterOverlays(parentModel, model, mesh, primitive, childID); } } diff --git a/Cesium3DTiles/test/TestQuantizedMeshContent.cpp b/Cesium3DTiles/test/TestQuantizedMeshContent.cpp index b523dd559..075dbaf09 100644 --- a/Cesium3DTiles/test/TestQuantizedMeshContent.cpp +++ b/Cesium3DTiles/test/TestQuantizedMeshContent.cpp @@ -1,16 +1,17 @@ #include "catch2/catch.hpp" -#include "Cesium3DTiles/GltfAccessor.h" #include "Cesium3DTiles/registerAllTileContentTypes.h" #include "Cesium3DTiles/spdlog-cesium.h" #include "Cesium3DTiles/TileContentFactory.h" #include "CesiumGeometry/QuadtreeTilingScheme.h" #include "CesiumGeometry/Rectangle.h" +#include "CesiumGltf/AccessorView.h" #include "CesiumUtility/Math.h" -#include "glm/glm.hpp" +#include using namespace Cesium3DTiles; using namespace CesiumGeometry; using namespace CesiumGeospatial; +using namespace CesiumGltf; using namespace CesiumUtility; struct QuantizedMeshHeader { @@ -312,8 +313,8 @@ static QuantizedMesh createGridQuantizedMesh(const BoundingRegion ®ion, ui template void checkGridMesh(const QuantizedMesh& quantizedMesh, - const GltfAccessor& indices, - const GltfAccessor& positions, + const AccessorView& indices, + const AccessorView& positions, const QuadtreeTilingScheme &tilingScheme, const Ellipsoid &ellipsoid, const Rectangle &tileRectangle, @@ -451,9 +452,9 @@ void checkGridMesh(const QuantizedMesh& quantizedMesh, template static void checkGeneratedGridNormal(const QuantizedMesh& quantizedMesh, - const GltfAccessor &normals, - const GltfAccessor &positions, - const GltfAccessor &indices, + const AccessorView &normals, + const AccessorView &positions, + const AccessorView &indices, const glm::vec3 &geodeticNormal, uint32_t verticesWidth, uint32_t verticesHeight) @@ -611,12 +612,17 @@ TEST_CASE("Test converting quantized mesh to gltf with skirt") { const CesiumGltf::MeshPrimitive& primitive = mesh.primitives.front(); // make sure mesh contains grid mesh and skirts at the end - GltfAccessor indices(model, static_cast(primitive.indices)); - GltfAccessor positions(model, static_cast(primitive.attributes.at("POSITION"))); + AccessorView indices(model, primitive.indices); + CHECK(indices.status() == AccessorViewStatus::Valid); + AccessorView positions(model, primitive.attributes.at("POSITION")); + CHECK(positions.status() == AccessorViewStatus::Valid); + checkGridMesh(quantizedMesh, indices, positions, tilingScheme, ellipsoid, tileRectangle, verticesWidth, verticesHeight); // check normal - GltfAccessor normals(model, static_cast(primitive.attributes.at("NORMAL"))); + AccessorView normals(model, primitive.attributes.at("NORMAL")); + CHECK(normals.status() == AccessorViewStatus::Valid); + Cartographic center = boundingVolume.getRectangle().computeCenter(); glm::vec3 geodeticNormal = static_cast(ellipsoid.geodeticSurfaceNormal(center)); checkGeneratedGridNormal(quantizedMesh, normals, positions, indices, geodeticNormal, verticesWidth, verticesHeight); @@ -658,12 +664,17 @@ TEST_CASE("Test converting quantized mesh to gltf with skirt") { const CesiumGltf::MeshPrimitive& primitive = mesh.primitives.front(); // make sure mesh contains grid mesh and skirts at the end - GltfAccessor indices(model, static_cast(primitive.indices)); - GltfAccessor positions(model, static_cast(primitive.attributes.at("POSITION"))); + AccessorView indices(model, primitive.indices); + CHECK(indices.status() == AccessorViewStatus::Valid); + AccessorView positions(model, primitive.attributes.at("POSITION")); + CHECK(positions.status() == AccessorViewStatus::Valid); + checkGridMesh(quantizedMesh, indices, positions, tilingScheme, ellipsoid, tileRectangle, verticesWidth, verticesHeight); // check normal - GltfAccessor normals(model, static_cast(primitive.attributes.at("NORMAL"))); + AccessorView normals(model, primitive.attributes.at("NORMAL")); + CHECK(normals.status() == AccessorViewStatus::Valid); + Cartographic center = boundingVolume.getRectangle().computeCenter(); glm::vec3 geodeticNormal = static_cast(ellipsoid.geodeticSurfaceNormal(center)); checkGeneratedGridNormal(quantizedMesh, normals, positions, indices, geodeticNormal, verticesWidth, verticesHeight); @@ -705,12 +716,17 @@ TEST_CASE("Test converting quantized mesh to gltf with skirt") { const CesiumGltf::MeshPrimitive& primitive = mesh.primitives.front(); // make sure mesh contains grid mesh and skirts at the end - GltfAccessor indices(model, static_cast(primitive.indices)); - GltfAccessor positions(model, static_cast(primitive.attributes.at("POSITION"))); + AccessorView indices(model, primitive.indices); + CHECK(indices.status() == AccessorViewStatus::Valid); + AccessorView positions(model, primitive.attributes.at("POSITION")); + CHECK(positions.status() == AccessorViewStatus::Valid); + checkGridMesh(quantizedMesh, indices, positions, tilingScheme, ellipsoid, tileRectangle, verticesWidth, verticesHeight); // check normal - GltfAccessor normals(model, static_cast(primitive.attributes.at("NORMAL"))); + AccessorView normals(model, primitive.attributes.at("NORMAL")); + CHECK(normals.status() == AccessorViewStatus::Valid); + Cartographic center = boundingVolume.getRectangle().computeCenter(); glm::vec3 geodeticNormal = static_cast(ellipsoid.geodeticSurfaceNormal(center)); checkGeneratedGridNormal(quantizedMesh, normals, positions, indices, geodeticNormal, verticesWidth, verticesHeight); @@ -774,9 +790,11 @@ TEST_CASE("Test converting quantized mesh to gltf with skirt") { size_t northIndicesCount = quantizedMesh.vertexData.northIndices.size(); size_t totalSkirtVerticesCount = westIndicesCount + southIndicesCount + eastIndicesCount + northIndicesCount; - GltfAccessor normals(model, static_cast(primitive.attributes.at("NORMAL"))); - REQUIRE(normals.size() == (verticesWidth * verticesHeight + totalSkirtVerticesCount)); - for (size_t i = 0; i < normals.size(); ++i) { + AccessorView normals(model, primitive.attributes.at("NORMAL")); + CHECK(normals.status() == AccessorViewStatus::Valid); + + REQUIRE(static_cast(normals.size()) == (verticesWidth * verticesHeight + totalSkirtVerticesCount)); + for (int64_t i = 0; i < normals.size(); ++i) { REQUIRE(Math::equalsEpsilon(normals[i].x, normal.x, Math::EPSILON2)); REQUIRE(Math::equalsEpsilon(normals[i].y, normal.y, Math::EPSILON2)); REQUIRE(Math::equalsEpsilon(normals[i].z, normal.z, Math::EPSILON2)); diff --git a/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp b/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp index c686e8497..9f3793b62 100644 --- a/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp +++ b/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp @@ -1,12 +1,12 @@ #include "catch2/catch.hpp" #include "Cesium3DTiles/Gltf.h" -#include "Cesium3DTiles/GltfAccessor.h" -#include "CesiumUtility/Math.h" #include "CesiumGeospatial/Cartographic.h" #include "CesiumGeospatial/Ellipsoid.h" +#include "CesiumGltf/AccessorView.h" +#include "CesiumUtility/Math.h" #include "SkirtMeshMetadata.h" #include "upsampleGltfForRasterOverlays.h" -#include "glm/trigonometric.hpp" +#include #include using namespace Cesium3DTiles; @@ -147,8 +147,8 @@ TEST_CASE("Test upsample tile without skirts") { REQUIRE(upsampledPrimitive.indices >= 0); REQUIRE(upsampledPrimitive.attributes.find("POSITION") != upsampledPrimitive.attributes.end()); - GltfAccessor upsampledPosition(upsampledModel, static_cast(upsampledPrimitive.attributes.at("POSITION"))); - GltfAccessor upsampledIndices(upsampledModel, static_cast(upsampledPrimitive.indices)); + AccessorView upsampledPosition(upsampledModel, upsampledPrimitive.attributes.at("POSITION")); + AccessorView upsampledIndices(upsampledModel, upsampledPrimitive.indices); glm::vec3 p0 = upsampledPosition[0]; REQUIRE(glm::epsilonEqual(p0, positions[0], glm::vec3(static_cast(Math::EPSILON7))) == glm::bvec3(true)); @@ -183,8 +183,8 @@ TEST_CASE("Test upsample tile without skirts") { REQUIRE(upsampledPrimitive.indices >= 0); REQUIRE(upsampledPrimitive.attributes.find("POSITION") != upsampledPrimitive.attributes.end()); - GltfAccessor upsampledPosition(upsampledModel, static_cast(upsampledPrimitive.attributes.at("POSITION"))); - GltfAccessor upsampledIndices(upsampledModel, static_cast(upsampledPrimitive.indices)); + AccessorView upsampledPosition(upsampledModel, upsampledPrimitive.attributes.at("POSITION")); + AccessorView upsampledIndices(upsampledModel, upsampledPrimitive.indices); glm::vec3 p0 = upsampledPosition[0]; REQUIRE(glm::epsilonEqual(p0, positions[1], glm::vec3(static_cast(Math::EPSILON7))) == glm::bvec3(true)); @@ -219,8 +219,8 @@ TEST_CASE("Test upsample tile without skirts") { REQUIRE(upsampledPrimitive.indices >= 0); REQUIRE(upsampledPrimitive.attributes.find("POSITION") != upsampledPrimitive.attributes.end()); - GltfAccessor upsampledPosition(upsampledModel, static_cast(upsampledPrimitive.attributes.at("POSITION"))); - GltfAccessor upsampledIndices(upsampledModel, static_cast(upsampledPrimitive.indices)); + AccessorView upsampledPosition(upsampledModel, upsampledPrimitive.attributes.at("POSITION")); + AccessorView upsampledIndices(upsampledModel, upsampledPrimitive.indices); glm::vec3 p0 = upsampledPosition[0]; REQUIRE(glm::epsilonEqual(p0, positions[3], glm::vec3(static_cast(Math::EPSILON7))) == glm::bvec3(true)); @@ -255,8 +255,8 @@ TEST_CASE("Test upsample tile without skirts") { REQUIRE(upsampledPrimitive.indices >= 0); REQUIRE(upsampledPrimitive.attributes.find("POSITION") != upsampledPrimitive.attributes.end()); - GltfAccessor upsampledPosition(upsampledModel, static_cast(upsampledPrimitive.attributes.at("POSITION"))); - GltfAccessor upsampledIndices(upsampledModel, static_cast(upsampledPrimitive.indices)); + AccessorView upsampledPosition(upsampledModel, upsampledPrimitive.attributes.at("POSITION")); + AccessorView upsampledIndices(upsampledModel, upsampledPrimitive.indices); glm::vec3 p0 = upsampledPosition[0]; REQUIRE(glm::epsilonEqual(p0, positions[2], glm::vec3(static_cast(Math::EPSILON7))) == glm::bvec3(true)); @@ -305,8 +305,8 @@ TEST_CASE("Test upsample tile without skirts") { REQUIRE(upsampledPrimitive.indices >= 0); REQUIRE(upsampledPrimitive.attributes.find("POSITION") != upsampledPrimitive.attributes.end()); - GltfAccessor upsampledPosition(upsampledModel, static_cast(upsampledPrimitive.attributes.at("POSITION"))); - GltfAccessor upsampledIndices(upsampledModel, static_cast(upsampledPrimitive.indices)); + AccessorView upsampledPosition(upsampledModel, upsampledPrimitive.attributes.at("POSITION")); + AccessorView upsampledIndices(upsampledModel, upsampledPrimitive.indices); // check west edge checkSkirt(ellipsoid, upsampledPosition[0], upsampledPosition[7], center, skirtHeight); @@ -340,8 +340,8 @@ TEST_CASE("Test upsample tile without skirts") { REQUIRE(upsampledPrimitive.indices >= 0); REQUIRE(upsampledPrimitive.attributes.find("POSITION") != upsampledPrimitive.attributes.end()); - GltfAccessor upsampledPosition(upsampledModel, static_cast(upsampledPrimitive.attributes.at("POSITION"))); - GltfAccessor upsampledIndices(upsampledModel, static_cast(upsampledPrimitive.indices)); + AccessorView upsampledPosition(upsampledModel, upsampledPrimitive.attributes.at("POSITION")); + AccessorView upsampledIndices(upsampledModel, upsampledPrimitive.indices); // check west edge checkSkirt(ellipsoid, upsampledPosition[1], upsampledPosition[7], center, skirtHeight); @@ -379,8 +379,8 @@ TEST_CASE("Test upsample tile without skirts") { REQUIRE(upsampledPrimitive.indices >= 0); REQUIRE(upsampledPrimitive.attributes.find("POSITION") != upsampledPrimitive.attributes.end()); - GltfAccessor upsampledPosition(upsampledModel, static_cast(upsampledPrimitive.attributes.at("POSITION"))); - GltfAccessor upsampledIndices(upsampledModel, static_cast(upsampledPrimitive.indices)); + AccessorView upsampledPosition(upsampledModel, upsampledPrimitive.attributes.at("POSITION")); + AccessorView upsampledIndices(upsampledModel, upsampledPrimitive.indices); // check west edge checkSkirt(ellipsoid, upsampledPosition[5], upsampledPosition[7], center, skirtHeight * 0.5); @@ -414,8 +414,8 @@ TEST_CASE("Test upsample tile without skirts") { REQUIRE(upsampledPrimitive.indices >= 0); REQUIRE(upsampledPrimitive.attributes.find("POSITION") != upsampledPrimitive.attributes.end()); - GltfAccessor upsampledPosition(upsampledModel, static_cast(upsampledPrimitive.attributes.at("POSITION"))); - GltfAccessor upsampledIndices(upsampledModel, static_cast(upsampledPrimitive.indices)); + AccessorView upsampledPosition(upsampledModel, upsampledPrimitive.attributes.at("POSITION")); + AccessorView upsampledIndices(upsampledModel, upsampledPrimitive.indices); // check west edge checkSkirt(ellipsoid, upsampledPosition[2], upsampledPosition[7], center, skirtHeight * 0.5); diff --git a/CesiumGltf/include/CesiumGltf/AccessorView.h b/CesiumGltf/include/CesiumGltf/AccessorView.h index 73026bb93..5049c5563 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorView.h +++ b/CesiumGltf/include/CesiumGltf/AccessorView.h @@ -5,18 +5,54 @@ namespace CesiumGltf { + enum class AccessorViewStatus { + /** + * @brief This accessor is valid and ready to use. + */ + Valid, + + /** + * @brief The accessor index does not refer to a valid accessor. + */ + InvalidAccessorIndex, + + /** + * @brief The accessor's bufferView index does not refer to a valid bufferView. + */ + InvalidBufferViewIndex, + + /** + * @brief The accessor's bufferView's buffer index does not refer to a valid buffer. + */ + InvalidBufferIndex, + + /** + * @brief The accessor is too large to fit in its bufferView. + */ + BufferViewTooSmall, + + /** + * @brief The accessor's bufferView is too large to fit in its buffer. + */ + BufferTooSmall, + + /** + * @brief The `sizeof(T)` does not match the accessor's {@link Accessor::computeBytesPerVertex}. + */ + WrongSizeT, + }; + /** * @brief A view on the data of one accessor of a glTF asset. * * It provides the actual accessor data like an array of elements. * The type of the accessor elements is determined by the template - * parameter. Instances are created from an input glTF model - * and an accessor index, and the {@link operator[]()} - * can be used to access the elements: + * parameter. Instances are usually created by {@link Accessor::createView}, + * and the {@link operator[]()} can be used to access the elements: * * ``` * CesiumGltf::Model model; - * GltfAccessor positions(model, accessorIndex) + * AccessorView positions = model.accessors[0].createView class AccessorView final { private: - uint8_t* _pData; + const uint8_t* _pData; int64_t _stride; int64_t _offset; int64_t _size; + AccessorViewStatus _status; public: typedef T value_type; + AccessorView() : + _pData(nullptr), + _stride(0), + _offset(0), + _size(0), + _status(AccessorViewStatus::InvalidAccessorIndex) + { + } + /** - * @brief Creates a new instance. + * @brief Creates a new instance from low-level parameters. * - * The resulting instance will provide the data of the specified - * accessor from the given model. + * The provided parameters are not validated in any way, and so this overload can easily + * be used to access invalid memory. * - * @param model The glTF model. - * @param accessorID The ID (index) of the accessor. - * @throws An `std::runtime_error` may be thrown when there are - * inconsistencies in the given model. This may refer to the model - * itself, or to cases where the size of the template parameter `T` - * does not match the size of the elements of the specified accessor. + * @param pData The raw data buffer from which to read. + * @param stride The stride, in bytes, between successive elements. + * @param offset The offset from the start of the buffer to the first element. + * @param size The total number of elements. */ - AccessorView(const CesiumGltf::Model& model, int32_t accessorID) { - const CesiumGltf::Accessor& accessor = model.accessors[accessorID]; - const CesiumGltf::BufferView& bufferView = model.bufferViews[accessor.bufferView]; - const CesiumGltf::Buffer& buffer = model.buffers[bufferView.buffer]; - - const std::vector& data = buffer.cesium.data; - int64_t bufferBytes = data.size(); - if (bufferView.byteOffset + bufferView.byteLength > bufferBytes) { - throw std::runtime_error("bufferView does not fit in buffer."); - } - - int64_t accessorByteStride = computeByteStride(accessor, bufferView); - if (accessorByteStride == -1) { - throw std::runtime_error("cannot compute accessor byteStride."); - } - - int64_t accessorComponentElements = computeNumberOfComponents(accessor.type); - int64_t accessorComponentBytes = computeByteSizeOfComponent(accessor.componentType); - int64_t accessorBytesPerStride = accessorComponentElements * accessorComponentBytes; + AccessorView(const uint8_t* pData, int64_t stride, int64_t offset, int64_t size) : + _pData(pData), + _stride(stride), + _offset(offset), + _size(size), + _status(AccessorViewStatus::Valid) + { + } - if (sizeof(T) != accessorBytesPerStride) { - throw std::runtime_error("sizeof(T) does not much accessor bytes."); - } + AccessorView(const Model& model, const Accessor& accessor) : + AccessorView() + { + this->create(model, accessor); + } - int64_t accessorBytes = accessorByteStride * accessor.count; - int64_t bytesRemainingInBufferView = bufferView.byteLength - (accessor.byteOffset + accessorByteStride * (accessor.count - 1) + accessorBytesPerStride); - if (accessorBytes > bufferView.byteLength || bytesRemainingInBufferView < 0) { - throw std::runtime_error("accessor does not fit in bufferView."); + AccessorView(const Model& model, int32_t accessorIndex) : + AccessorView() + { + const Accessor* pAccessor = Model::getSafe(&model.accessors, accessorIndex); + if (!pAccessor) { + this->_status = AccessorViewStatus::InvalidAccessorIndex; + return; } - this->_stride = accessorByteStride; - this->_offset = accessor.byteOffset + bufferView.byteOffset; - this->_size = accessor.count; - this->_pData = &buffer.cesium.data.data(); + this->create(model, *pAccessor); } /** @@ -95,7 +130,7 @@ namespace CesiumGltf { throw std::range_error("index out of range"); } - return *reinterpret_cast(this->_pBufferViewData + i * this->_stride + this->_offset); + return *reinterpret_cast(this->_pData + i * this->_stride + this->_offset); } /** @@ -108,6 +143,61 @@ namespace CesiumGltf { int64_t size() const noexcept { return this->_size; } + + /** + * @brief Gets the status of this accessor view. + * + * Indicates whether the view accurately reflects the accessor's data, or whether + * an error occurred. + */ + AccessorViewStatus status() const noexcept { + return this->_status; + } + + private: + void create(const Model& model, const Accessor& accessor) { + const CesiumGltf::BufferView* pBufferView = Model::getSafe(&model.bufferViews, accessor.bufferView); + if (!pBufferView) { + this->_status = AccessorViewStatus::InvalidBufferViewIndex; + return; + } + + const CesiumGltf::Buffer* pBuffer = Model::getSafe(&model.buffers, pBufferView->buffer); + if (!pBuffer) { + this->_status = AccessorViewStatus::InvalidBufferIndex; + return; + } + + const std::vector& data = pBuffer->cesium.data; + int64_t bufferBytes = data.size(); + if (pBufferView->byteOffset + pBufferView->byteLength > bufferBytes) { + this->_status = AccessorViewStatus::BufferTooSmall; + return; + } + + int64_t accessorByteStride = accessor.computeByteStride(model); + int64_t accessorComponentElements = accessor.computeNumberOfComponents(); + int64_t accessorComponentBytes = accessor.computeByteSizeOfComponent(); + int64_t accessorBytesPerStride = accessorComponentElements * accessorComponentBytes; + + if (sizeof(T) != accessorBytesPerStride) { + this->_status = AccessorViewStatus::WrongSizeT; + return; + } + + int64_t accessorBytes = accessorByteStride * accessor.count; + int64_t bytesRemainingInBufferView = pBufferView->byteLength - (accessor.byteOffset + accessorByteStride * (accessor.count - 1) + accessorBytesPerStride); + if (accessorBytes > pBufferView->byteLength || bytesRemainingInBufferView < 0) { + this->_status = AccessorViewStatus::BufferViewTooSmall; + return; + } + + this->_pData = pBuffer->cesium.data.data(); + this->_stride = accessorByteStride; + this->_offset = accessor.byteOffset + pBufferView->byteOffset; + this->_size = accessor.count; + this->_status = AccessorViewStatus::Valid; + } }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorWriter.h b/CesiumGltf/include/CesiumGltf/AccessorWriter.h index 4cd1d7e4e..ea70089fa 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorWriter.h +++ b/CesiumGltf/include/CesiumGltf/AccessorWriter.h @@ -1,9 +1,6 @@ #pragma once -#include "Gltf.h" -#include "GltfAccessor.h" - -#include +#include "CesiumGltf/AccessorView.h" namespace CesiumGltf { @@ -16,27 +13,51 @@ namespace CesiumGltf { AccessorView _accessor; public: + AccessorWriter() : + _accessor() + { + } /** @copydoc AccessorView::AccessorView */ - AccessorWriter(CesiumGltf::Model& model, int32_t accessorID) : - _accessor(model, accessorID) + AccessorWriter(uint8_t* pData, int64_t stride, int64_t offset, int64_t size) : + _accessor(pData, stride, offset, size) + { + } + + AccessorWriter(Model& model, const Accessor& accessor) : + _accessor(model, accessor) + { + } + + AccessorWriter(Model& model, int32_t accessorIndex) : + _accessor(model, accessorIndex) { } /** @copydoc AccessorView::operator[]() */ - const T& operator[](size_t i) const { + const T& operator[](int64_t i) const { return this->_accessor[i]; } /** @copydoc AccessorView::operator[]() */ - T& operator[](size_t i) { + T& operator[](int64_t i) { return const_cast(this->_accessor[i]); } /** @copydoc AccessorView::size */ - size_t size() const noexcept { + int64_t size() const noexcept { return this->_accessor.size(); } + + /** + * @brief Gets the status of this accessor writer. + * + * Indicates whether the writer accurately reflects the accessor's data, or whether + * an error occurred. + */ + AccessorViewStatus status() const noexcept { + return this->_accessor.status(); + } }; } \ No newline at end of file From 6147e0bf1104b9fa49dddbc7e9a0c2ea4fe52d46 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 14:27:06 +1100 Subject: [PATCH 42/61] Clear arrays in StartArray. --- CesiumGltfReader/src/ArrayJsonHandler.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CesiumGltfReader/src/ArrayJsonHandler.h b/CesiumGltfReader/src/ArrayJsonHandler.h index 9580a4073..788df0b50 100644 --- a/CesiumGltfReader/src/ArrayJsonHandler.h +++ b/CesiumGltfReader/src/ArrayJsonHandler.h @@ -74,6 +74,7 @@ namespace CesiumGltf { } this->_arrayIsOpen = true; + this->_pArray->clear(); return this; } @@ -184,6 +185,7 @@ namespace CesiumGltf { } this->_arrayIsOpen = true; + this->_pArray->clear(); return this; } @@ -287,6 +289,7 @@ namespace CesiumGltf { } this->_arrayIsOpen = true; + this->_pArray->clear(); return this; } @@ -362,6 +365,7 @@ namespace CesiumGltf { } this->_arrayIsOpen = true; + this->_pArray->clear(); return this; } From dfa5f01526cb941e9c7c10961d14a0d250c27b96 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 14:32:30 +1100 Subject: [PATCH 43/61] Remove tinygltf. --- .gitmodules | 3 --- extern/tinygltf | 1 - 2 files changed, 4 deletions(-) delete mode 160000 extern/tinygltf diff --git a/.gitmodules b/.gitmodules index 2cc824113..f4b8b8a7a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "extern/tinygltf"] - path = extern/tinygltf - url = https://github.com/syoyo/tinygltf [submodule "extern/glm"] path = extern/glm url = https://github.com/g-truc/glm.git diff --git a/extern/tinygltf b/extern/tinygltf deleted file mode 160000 index 18f0e20a1..000000000 --- a/extern/tinygltf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 18f0e20a118409c0df0f33252549586cae7d2df0 From 5d069f204ddf594267dd2748740b0e56d468211e Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 15:03:19 +1100 Subject: [PATCH 44/61] Fix test failures. --- Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp b/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp index 9f3793b62..f08ffe760 100644 --- a/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp +++ b/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp @@ -67,7 +67,6 @@ TEST_CASE("Test upsample tile without skirts") { positionBufferView.buffer = static_cast(model.buffers.size() - 1); positionBufferView.byteOffset = 0; positionBufferView.byteLength = positionsBufferSize; - positionBufferView.byteStride = 0; model.accessors.emplace_back(); Accessor &positionAccessor = model.accessors.back(); @@ -85,7 +84,6 @@ TEST_CASE("Test upsample tile without skirts") { uvBufferView.buffer = static_cast(model.buffers.size() - 1); uvBufferView.byteOffset = positionsBufferSize; uvBufferView.byteLength = uvsBufferSize; - uvBufferView.byteStride = 0; model.accessors.emplace_back(); Accessor &uvAccessor = model.accessors.back(); @@ -103,7 +101,6 @@ TEST_CASE("Test upsample tile without skirts") { indicesBufferView.buffer = static_cast(model.buffers.size() - 1); indicesBufferView.byteOffset = positionsBufferSize + uvsBufferSize; indicesBufferView.byteLength = indicesBufferSize; - indicesBufferView.byteStride = 0; model.accessors.emplace_back(); Accessor &indicesAccessor = model.accessors.back(); From 168798fe4a46665678322b75194015463558a317 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 15:19:42 +1100 Subject: [PATCH 45/61] Don't use a C++ reserved word as a parameter name. --- CesiumGltf/include/CesiumGltf/JsonValue.h | 12 ++++++------ CesiumGltf/src/JsonValue.cpp | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CesiumGltf/include/CesiumGltf/JsonValue.h b/CesiumGltf/include/CesiumGltf/JsonValue.h index 73a98fd95..708622335 100644 --- a/CesiumGltf/include/CesiumGltf/JsonValue.h +++ b/CesiumGltf/include/CesiumGltf/JsonValue.h @@ -42,26 +42,26 @@ namespace CesiumGltf { /** * @brief Gets the number from the value, or a default if the value does not contain a number. * - * @param default The default value to return if the value is not a number. + * @param defaultValue The default value to return if the value is not a number. * @return The number. */ - double getNumber(double default) const; + double getNumber(double defaultValue) const; /** * @brief Gets the bool from the value, or a default if the value does not contain a bool. * - * @param default The default value to return if the value is not a bool. + * @param defaultValue The default value to return if the value is not a bool. * @return The bool. */ - bool getBool(bool default) const; + bool getBool(bool defaultValue) const; /** * @brief Gets the string from the value, or a default if the value does not contain a string. * - * @param default The default value to return if the value is not a string. + * @param defaultValue The default value to return if the value is not a string. * @return The string. */ - std::string getString(const std::string& default) const; + std::string getString(const std::string& defaultValue) const; /** * @brief Gets a typed value corresponding to the given key in the object represented by this instance. diff --git a/CesiumGltf/src/JsonValue.cpp b/CesiumGltf/src/JsonValue.cpp index 26872dede..64bd23379 100644 --- a/CesiumGltf/src/JsonValue.cpp +++ b/CesiumGltf/src/JsonValue.cpp @@ -2,30 +2,30 @@ using namespace CesiumGltf; -double JsonValue::getNumber(double default) const { +double JsonValue::getNumber(double defaultValue) const { const double* p = std::get_if(&this->value); if (p) { return *p; } else { - return default; + return defaultValue; } } -bool JsonValue::getBool(bool default) const { +bool JsonValue::getBool(bool defaultValue) const { const bool* p = std::get_if(&this->value); if (p) { return *p; } else { - return default; + return defaultValue; } } -std::string JsonValue::getString(const std::string& default) const { +std::string JsonValue::getString(const std::string& defaultValue) const { const std::string* p = std::get_if(&this->value); if (p) { return *p; } else { - return default; + return defaultValue; } } From 5b1550da3915c8ba7a694f2dac6b1dadd2dd63da Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 15:28:01 +1100 Subject: [PATCH 46/61] Remove another "default". --- CesiumGltf/include/CesiumGltf/Model.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index 8de11d58c..46644b547 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -15,9 +15,9 @@ namespace CesiumGltf { */ template static const T& getSafe(const std::vector& items, int32_t index) { - static T default; + static T defaultObject; if (index < 0 || static_cast(index) >= items.size()) { - return default; + return defaultObject; } else { return items[index]; } From 8fdc7518b99f0ec8fed6ffa2e15e09907075c535 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 17:25:00 +1100 Subject: [PATCH 47/61] Fix Clang problems. --- Cesium3DTiles/include/Cesium3DTiles/Tile.h | 2 +- Cesium3DTiles/include/Cesium3DTiles/Tileset.h | 6 ++-- Cesium3DTiles/src/GltfContent.cpp | 6 ++-- Cesium3DTiles/src/QuantizedMeshContent.cpp | 20 +++++------ Cesium3DTiles/src/RasterOverlayTile.cpp | 20 +++++------ Cesium3DTiles/src/Tile.cpp | 4 +-- Cesium3DTiles/src/Tileset.cpp | 6 ++-- .../src/upsampleGltfForRasterOverlays.cpp | 28 +++++++-------- .../test/TestQuantizedMeshContent.cpp | 32 ++++++++--------- .../test/TestUpsampleGltfForRasterOverlay.cpp | 17 ++++----- CesiumGltf/include/CesiumGltf/JsonValue.h | 17 +++++---- CesiumGltfReader/src/DictionaryJsonHandler.h | 35 +++++++++++++------ CesiumGltfReader/src/Reader.cpp | 2 +- CesiumGltfReader/src/decodeDraco.cpp | 27 ++++++++------ 14 files changed, 124 insertions(+), 98 deletions(-) diff --git a/Cesium3DTiles/include/Cesium3DTiles/Tile.h b/Cesium3DTiles/include/Cesium3DTiles/Tile.h index f0f38f720..d79cc469e 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/Tile.h +++ b/Cesium3DTiles/include/Cesium3DTiles/Tile.h @@ -467,7 +467,7 @@ namespace Cesium3DTiles { /** * @brief Determines the number of bytes in this tile's geometry and texture data. */ - size_t computeByteSize() const noexcept; + int64_t computeByteSize() const noexcept; private: diff --git a/Cesium3DTiles/include/Cesium3DTiles/Tileset.h b/Cesium3DTiles/include/Cesium3DTiles/Tileset.h index 6de7113fd..e23d3ff94 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/Tileset.h +++ b/Cesium3DTiles/include/Cesium3DTiles/Tileset.h @@ -99,7 +99,7 @@ namespace Cesium3DTiles { * loaded bytes is greater than this value, tiles will be unloaded until the total is under * this number or until only required tiles remain, whichever comes first. */ - size_t maximumCachedBytes = 512 * 1024 * 1024; + int64_t maximumCachedBytes = 512 * 1024 * 1024; /** * @brief A table that maps the camera height above the ellipsoid to a fog density. Tiles that are in full fog are culled. @@ -299,7 +299,7 @@ namespace Cesium3DTiles { /** * @brief Gets the total number of bytes of tile and raster overlay data that are currently loaded. */ - size_t getTotalDataBytes() const noexcept; + int64_t getTotalDataBytes() const noexcept; private: struct TraversalDetails { @@ -500,7 +500,7 @@ namespace Cesium3DTiles { RasterOverlayCollection _overlays; - size_t _tileDataBytes; + int64_t _tileDataBytes; static void addTileToLoadQueue(std::vector& loadQueue, const FrameState& frameState, Tile& tile, double distance); static void processQueue(std::vector& queue, std::atomic& loadsInProgress, uint32_t maximumLoadsInProgress); diff --git a/Cesium3DTiles/src/GltfContent.cpp b/Cesium3DTiles/src/GltfContent.cpp index 9e233a229..aae3dd968 100644 --- a/Cesium3DTiles/src/GltfContent.cpp +++ b/Cesium3DTiles/src/GltfContent.cpp @@ -66,20 +66,20 @@ namespace Cesium3DTiles { return -1; } - uvBuffer.cesium.data.resize(positionView.size() * 2 * sizeof(float)); + uvBuffer.cesium.data.resize(size_t(positionView.size()) * 2 * sizeof(float)); CesiumGltf::BufferView& uvBufferView = gltf.bufferViews[static_cast(uvBufferViewId)]; uvBufferView.buffer = uvBufferId; uvBufferView.byteOffset = 0; uvBufferView.byteStride = 2 * sizeof(float); - uvBufferView.byteLength = uvBuffer.cesium.data.size(); + uvBufferView.byteLength = int64_t(uvBuffer.cesium.data.size()); uvBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; CesiumGltf::Accessor& uvAccessor = gltf.accessors[static_cast(uvAccessorId)]; uvAccessor.bufferView = uvBufferViewId; uvAccessor.byteOffset = 0; uvAccessor.componentType = CesiumGltf::Accessor::ComponentType::FLOAT; - uvAccessor.count = positionView.size(); + uvAccessor.count = int64_t(positionView.size()); uvAccessor.type = CesiumGltf::Accessor::Type::VEC2; CesiumGltf::AccessorWriter uvWriter(gltf, uvAccessorId); diff --git a/Cesium3DTiles/src/QuantizedMeshContent.cpp b/Cesium3DTiles/src/QuantizedMeshContent.cpp index 3e0e740d7..6280492c6 100644 --- a/Cesium3DTiles/src/QuantizedMeshContent.cpp +++ b/Cesium3DTiles/src/QuantizedMeshContent.cpp @@ -850,10 +850,10 @@ namespace Cesium3DTiles { size_t positionBufferViewId = model.bufferViews.size(); model.bufferViews.emplace_back(); CesiumGltf::BufferView& positionBufferView = model.bufferViews[positionBufferViewId]; - positionBufferView.buffer = static_cast(positionBufferId); + positionBufferView.buffer = int32_t(positionBufferId); positionBufferView.byteOffset = 0; positionBufferView.byteStride = 3 * sizeof(float); - positionBufferView.byteLength = positionBuffer.cesium.data.size(); + positionBufferView.byteLength = int64_t(positionBuffer.cesium.data.size()); positionBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; size_t positionAccessorId = model.accessors.size(); @@ -867,7 +867,7 @@ namespace Cesium3DTiles { positionAccessor.min = { minX, minY, minZ }; positionAccessor.max = { maxX, maxY, maxZ }; - primitive.attributes.emplace("POSITION", static_cast(positionAccessorId)); + primitive.attributes.emplace("POSITION", int32_t(positionAccessorId)); // add normal buffer to gltf if there are any if (!outputNormalsBuffer.empty()) { @@ -879,16 +879,16 @@ namespace Cesium3DTiles { size_t normalBufferViewId = model.bufferViews.size(); model.bufferViews.emplace_back(); CesiumGltf::BufferView& normalBufferView = model.bufferViews[normalBufferViewId]; - normalBufferView.buffer = static_cast(normalBufferId); + normalBufferView.buffer = int32_t(normalBufferId); normalBufferView.byteOffset = 0; normalBufferView.byteStride = 3 * sizeof(float); - normalBufferView.byteLength = normalBuffer.cesium.data.size(); + normalBufferView.byteLength = int64_t(normalBuffer.cesium.data.size()); normalBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; size_t normalAccessorId = model.accessors.size(); model.accessors.emplace_back(); CesiumGltf::Accessor& normalAccessor = model.accessors[normalAccessorId]; - normalAccessor.bufferView = static_cast(normalBufferViewId); + normalAccessor.bufferView = int32_t(normalBufferViewId); normalAccessor.byteOffset = 0; normalAccessor.componentType = CesiumGltf::Accessor::ComponentType::FLOAT; normalAccessor.count = vertexCount + skirtVertexCount; @@ -906,22 +906,22 @@ namespace Cesium3DTiles { size_t indicesBufferViewId = model.bufferViews.size(); model.bufferViews.emplace_back(); CesiumGltf::BufferView& indicesBufferView = model.bufferViews[indicesBufferViewId]; - indicesBufferView.buffer = static_cast(indicesBufferId); + indicesBufferView.buffer = int32_t(indicesBufferId); indicesBufferView.byteOffset = 0; - indicesBufferView.byteLength = indicesBuffer.cesium.data.size(); + indicesBufferView.byteLength = int64_t(indicesBuffer.cesium.data.size()); indicesBufferView.byteStride = indexSizeBytes; indicesBufferView.target = CesiumGltf::BufferView::Target::ARRAY_BUFFER; size_t indicesAccessorId = model.accessors.size(); model.accessors.emplace_back(); CesiumGltf::Accessor& indicesAccessor = model.accessors[indicesAccessorId]; - indicesAccessor.bufferView = static_cast(indicesBufferViewId); + indicesAccessor.bufferView = int32_t(indicesBufferViewId); indicesAccessor.byteOffset = 0; indicesAccessor.type = CesiumGltf::Accessor::Type::SCALAR; indicesAccessor.count = indicesCount + skirtIndicesCount; indicesAccessor.componentType = indexSizeBytes == sizeof(uint32_t) ? CesiumGltf::Accessor::ComponentType::UNSIGNED_INT : CesiumGltf::Accessor::ComponentType::UNSIGNED_SHORT; - primitive.indices = static_cast(indicesBufferId); + primitive.indices = int32_t(indicesBufferId); // add skirts info to primitive extra in case we need to upsample from it SkirtMeshMetadata skirtMeshMetadata; diff --git a/Cesium3DTiles/src/RasterOverlayTile.cpp b/Cesium3DTiles/src/RasterOverlayTile.cpp index 569e3841c..cd03513f3 100644 --- a/Cesium3DTiles/src/RasterOverlayTile.cpp +++ b/Cesium3DTiles/src/RasterOverlayTile.cpp @@ -127,18 +127,18 @@ namespace Cesium3DTiles { std::swap(startV, endV); - uint32_t startPixelX = static_cast(std::floor(startU * width)); - uint32_t endPixelX = static_cast(std::ceil(endU * width)); - uint32_t startPixelY = static_cast(std::floor(startV * height)); - uint32_t endPixelY = static_cast(std::ceil(endV * height)); - - for (uint32_t j = startPixelY; j < endPixelY; ++j) { - uint32_t rowStart = j * static_cast(width) * static_cast(bytesPerPixel); - for (uint32_t i = startPixelX; i < endPixelX; ++i) { - uint32_t pixelStart = rowStart + i * bytesPerPixel; + int32_t startPixelX = static_cast(std::floor(startU * width)); + int32_t endPixelX = static_cast(std::ceil(endU * width)); + int32_t startPixelY = static_cast(std::floor(startV * height)); + int32_t endPixelY = static_cast(std::ceil(endV * height)); + + for (int32_t j = startPixelY; j < endPixelY; ++j) { + int32_t rowStart = j * width * bytesPerPixel; + for (int32_t i = startPixelX; i < endPixelX; ++i) { + int32_t pixelStart = rowStart + i * bytesPerPixel; // Set alpha to 0 - imageData[pixelStart + 3] = 0; + imageData[size_t(pixelStart + 3)] = 0; } } } diff --git a/Cesium3DTiles/src/Tile.cpp b/Cesium3DTiles/src/Tile.cpp index 5c5d48237..afc5da214 100644 --- a/Cesium3DTiles/src/Tile.cpp +++ b/Cesium3DTiles/src/Tile.cpp @@ -579,8 +579,8 @@ namespace Cesium3DTiles { } } - size_t Tile::computeByteSize() const noexcept { - size_t bytes = 0; + int64_t Tile::computeByteSize() const noexcept { + int64_t bytes = 0; const TileContentLoadResult* pContent = this->getContent(); if (pContent && pContent->model) { diff --git a/Cesium3DTiles/src/Tileset.cpp b/Cesium3DTiles/src/Tileset.cpp index ec884ce5f..450b8210c 100644 --- a/Cesium3DTiles/src/Tileset.cpp +++ b/Cesium3DTiles/src/Tileset.cpp @@ -349,8 +349,8 @@ namespace Cesium3DTiles { } } - size_t Tileset::getTotalDataBytes() const noexcept { - size_t bytes = this->_tileDataBytes; + int64_t Tileset::getTotalDataBytes() const noexcept { + int64_t bytes = this->_tileDataBytes; for (auto& pOverlay : this->_overlays) { const RasterOverlayTileProvider* pProvider = pOverlay->getTileProvider(); @@ -1185,7 +1185,7 @@ namespace Cesium3DTiles { } void Tileset::_unloadCachedTiles() { - const size_t maxBytes = this->getOptions().maximumCachedBytes; + const int64_t maxBytes = this->getOptions().maximumCachedBytes; Tile* pTile = this->_loadedTiles.head(); diff --git a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp index f79a78b59..bf13e1126 100644 --- a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp +++ b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp @@ -223,12 +223,12 @@ namespace Cesium3DTiles { const AccessorView& accessor; T operator()(int vertexIndex) { - return accessor[static_cast(vertexIndex)]; + return accessor[vertexIndex]; } T operator()(const CesiumGeometry::InterpolatedVertex& vertex) { - const T& v0 = accessor[static_cast(vertex.first)]; - const T& v1 = accessor[static_cast(vertex.second)]; + const T& v0 = accessor[vertex.first]; + const T& v1 = accessor[vertex.second]; return glm::mix(v0, v1, vertex.t); } }; @@ -250,7 +250,7 @@ namespace Cesium3DTiles { return getVertexValue(accessor, complements, complements[static_cast(~vertexIndex)]); } - return accessor[static_cast(vertexIndex)]; + return accessor[vertexIndex]; } T operator()(const CesiumGeometry::InterpolatedVertex& vertex) { @@ -259,7 +259,7 @@ namespace Cesium3DTiles { v0 = getVertexValue(accessor, complements, complements[static_cast(~vertex.first)]); } else { - v0 = accessor[static_cast(vertex.first)]; + v0 = accessor[vertex.first]; } T v1{}; @@ -267,7 +267,7 @@ namespace Cesium3DTiles { v1 = getVertexValue(accessor, complements, complements[static_cast(~vertex.second)]); } else { - v1 = accessor[static_cast(vertex.second)]; + v1 = accessor[vertex.second]; } return glm::mix(v0, v1, vertex.t); @@ -403,8 +403,8 @@ namespace Cesium3DTiles { } // check if the primitive has skirts - size_t indicesBegin = 0; - size_t indicesCount = indicesView.size(); + int64_t indicesBegin = 0; + int64_t indicesCount = indicesView.size(); std::optional parentSkirtMeshMetadata = SkirtMeshMetadata::parseFromGltfExtras(primitive.extras); bool hasSkirt = (parentSkirtMeshMetadata != std::nullopt) && (positionAttributeIndex != -1); if (hasSkirt) { @@ -417,7 +417,7 @@ namespace Cesium3DTiles { std::vector clippedB; // Maps old (parentModel) vertex indices to new (model) vertex indices. - std::vector vertexMap(uvView.size(), std::numeric_limits::max()); + std::vector vertexMap(size_t(uvView.size()), std::numeric_limits::max()); // std::vector newVertexBuffer(vertexSizeFloats * sizeof(float)); // gsl::span newVertexFloats(reinterpret_cast(newVertexBuffer.data()), newVertexBuffer.size() / sizeof(float)); @@ -425,7 +425,7 @@ namespace Cesium3DTiles { std::vector indices; EdgeIndices edgeIndices; - for (size_t i = indicesBegin; i < indicesBegin + indicesCount; i += 3) { + for (int64_t i = indicesBegin; i < indicesBegin + indicesCount; i += 3) { TIndex i0 = indicesView[i]; TIndex i1 = indicesView[i + 1]; TIndex i2 = indicesView[i + 2]; @@ -507,7 +507,7 @@ namespace Cesium3DTiles { } // Update the accessor vertex counts and min/max values - size_t numberOfVertices = newVertexFloats.size() / vertexSizeFloats; + int64_t numberOfVertices = int64_t(newVertexFloats.size()) / vertexSizeFloats; for (const FloatVertexAttribute& attribute : attributes) { Accessor& accessor = model.accessors[static_cast(attribute.accessorIndex)]; accessor.count = numberOfVertices; @@ -521,7 +521,7 @@ namespace Cesium3DTiles { Accessor& newIndicesAccessor = model.accessors.back(); newIndicesAccessor.bufferView = static_cast(indexBufferViewIndex); newIndicesAccessor.byteOffset = 0; - newIndicesAccessor.count = indices.size(); + newIndicesAccessor.count = int64_t(indices.size()); newIndicesAccessor.componentType = Accessor::ComponentType::UNSIGNED_INT; newIndicesAccessor.type = Accessor::Type::SCALAR; @@ -530,14 +530,14 @@ namespace Cesium3DTiles { vertexBuffer.cesium.data.resize(newVertexFloats.size() * sizeof(float)); float* pAsFloats = reinterpret_cast(vertexBuffer.cesium.data.data()); std::copy(newVertexFloats.begin(), newVertexFloats.end(), pAsFloats); - vertexBufferView.byteLength = vertexBuffer.cesium.data.size(); + vertexBufferView.byteLength = int64_t(vertexBuffer.cesium.data.size()); vertexBufferView.byteStride = vertexSizeFloats * sizeof(float); Buffer& indexBuffer = model.buffers[indexBufferIndex]; indexBuffer.cesium.data.resize(indices.size() * sizeof(uint32_t)); uint32_t* pAsUint32s = reinterpret_cast(indexBuffer.cesium.data.data()); std::copy(indices.begin(), indices.end(), pAsUint32s); - indexBufferView.byteLength = indexBuffer.cesium.data.size(); + indexBufferView.byteLength = int64_t(indexBuffer.cesium.data.size()); // add skirts to extras to be upsampled later if needed if (hasSkirt) { diff --git a/Cesium3DTiles/test/TestQuantizedMeshContent.cpp b/Cesium3DTiles/test/TestQuantizedMeshContent.cpp index 075dbaf09..c624c81eb 100644 --- a/Cesium3DTiles/test/TestQuantizedMeshContent.cpp +++ b/Cesium3DTiles/test/TestQuantizedMeshContent.cpp @@ -390,8 +390,8 @@ void checkGridMesh(const QuantizedMesh& quantizedMesh, double longitudeOffset = (west - east) * 0.0001; double latitudeOffset = (north - south) * 0.0001; - REQUIRE(totalSkirtIndices == indices.size() - gridIndicesCount); - REQUIRE(totalSkirtVertices == positions.size() - gridVerticesCount); + REQUIRE(totalSkirtIndices == size_t(indices.size()) - gridIndicesCount); + REQUIRE(totalSkirtVertices == size_t(positions.size()) - gridVerticesCount); size_t currentVertexCount = gridVerticesCount; for (size_t i = 0; i < westIndicesCount; ++i) { @@ -400,7 +400,7 @@ void checkGridMesh(const QuantizedMesh& quantizedMesh, double latitude = Math::lerp(south, north, uvs[westIndex].y); glm::dvec3 expectPosition = ellipsoid.cartographicToCartesian(Cartographic(longitude, latitude, -skirtHeight)); - glm::dvec3 position = static_cast(positions[currentVertexCount + i]); + glm::dvec3 position = static_cast(positions[int64_t(currentVertexCount + i)]); position += glm::dvec3(quantizedMesh.header.boundingSphereCenterX, quantizedMesh.header.boundingSphereCenterY, quantizedMesh.header.boundingSphereCenterZ); REQUIRE(Math::equalsEpsilon(position.x, expectPosition.x, Math::EPSILON3)); REQUIRE(Math::equalsEpsilon(position.y, expectPosition.y, Math::EPSILON3)); @@ -414,7 +414,7 @@ void checkGridMesh(const QuantizedMesh& quantizedMesh, double latitude = south - latitudeOffset; glm::dvec3 expectPosition = ellipsoid.cartographicToCartesian(Cartographic(longitude, latitude, -skirtHeight)); - glm::dvec3 position = static_cast(positions[currentVertexCount + i]); + glm::dvec3 position = static_cast(positions[int64_t(currentVertexCount + i)]); position += glm::dvec3(quantizedMesh.header.boundingSphereCenterX, quantizedMesh.header.boundingSphereCenterY, quantizedMesh.header.boundingSphereCenterZ); REQUIRE(Math::equalsEpsilon(position.x, expectPosition.x, Math::EPSILON3)); REQUIRE(Math::equalsEpsilon(position.y, expectPosition.y, Math::EPSILON3)); @@ -428,7 +428,7 @@ void checkGridMesh(const QuantizedMesh& quantizedMesh, double latitude = Math::lerp(south, north, uvs[eastIndex].y); glm::dvec3 expectPosition = ellipsoid.cartographicToCartesian(Cartographic(longitude, latitude, -skirtHeight)); - glm::dvec3 position = static_cast(positions[currentVertexCount + i]); + glm::dvec3 position = static_cast(positions[int64_t(currentVertexCount + i)]); position += glm::dvec3(quantizedMesh.header.boundingSphereCenterX, quantizedMesh.header.boundingSphereCenterY, quantizedMesh.header.boundingSphereCenterZ); REQUIRE(Math::equalsEpsilon(position.x, expectPosition.x, Math::EPSILON3)); REQUIRE(Math::equalsEpsilon(position.y, expectPosition.y, Math::EPSILON2)); @@ -442,7 +442,7 @@ void checkGridMesh(const QuantizedMesh& quantizedMesh, double latitude = north + latitudeOffset; glm::dvec3 expectPosition = ellipsoid.cartographicToCartesian(Cartographic(longitude, latitude, -skirtHeight)); - glm::dvec3 position = static_cast(positions[currentVertexCount + i]); + glm::dvec3 position = static_cast(positions[int64_t(currentVertexCount + i)]); position += glm::dvec3(quantizedMesh.header.boundingSphereCenterX, quantizedMesh.header.boundingSphereCenterY, quantizedMesh.header.boundingSphereCenterZ); REQUIRE(Math::equalsEpsilon(position.x, expectPosition.x, Math::EPSILON3)); REQUIRE(Math::equalsEpsilon(position.y, expectPosition.y, Math::EPSILON3)); @@ -478,7 +478,7 @@ static void checkGeneratedGridNormal(const QuantizedMesh& quantizedMesh, for (size_t i = 0; i < expectedNormals.size(); ++i) { glm::vec3 &expectedNormal = expectedNormals[i]; - glm::vec3 normal = normals[i]; + glm::vec3 normal = normals[int64_t(i)]; if (!Math::equalsEpsilon(glm::dot(expectedNormals[i], expectedNormals[i]), 0.0, Math::EPSILON7)) { expectedNormal = glm::normalize(expectedNormals[i]); @@ -506,14 +506,14 @@ static void checkGeneratedGridNormal(const QuantizedMesh& quantizedMesh, size_t gridVerticesCount = verticesWidth * verticesHeight; size_t totalSkirtVertices = westIndicesCount + southIndicesCount + eastIndicesCount + northIndicesCount; - REQUIRE(totalSkirtVertices == normals.size() - gridVerticesCount); + REQUIRE(totalSkirtVertices == size_t(normals.size()) - gridVerticesCount); size_t currentVertexCount = gridVerticesCount; uint32_t x = 0; uint32_t y = 0; for (size_t i = 0; i < westIndicesCount; ++i) { - glm::vec3 normal = normals[currentVertexCount + i]; - glm::vec3 expectedNormal = expectedNormals[static_cast(index2DTo1D(x, y, verticesWidth))]; + glm::vec3 normal = normals[int64_t(currentVertexCount + i)]; + glm::vec3 expectedNormal = expectedNormals[index2DTo1D(x, y, verticesWidth)]; REQUIRE(Math::equalsEpsilon(normal.x, expectedNormal.x, Math::EPSILON7)); REQUIRE(Math::equalsEpsilon(normal.y, expectedNormal.y, Math::EPSILON7)); REQUIRE(Math::equalsEpsilon(normal.z, expectedNormal.z, Math::EPSILON7)); @@ -525,8 +525,8 @@ static void checkGeneratedGridNormal(const QuantizedMesh& quantizedMesh, x = verticesWidth - 1; y = 0; for (size_t i = 0; i < southIndicesCount; ++i) { - glm::vec3 normal = normals[currentVertexCount + i]; - glm::vec3 expectedNormal = expectedNormals[static_cast(index2DTo1D(x, y, verticesWidth))]; + glm::vec3 normal = normals[int64_t(currentVertexCount + i)]; + glm::vec3 expectedNormal = expectedNormals[index2DTo1D(x, y, verticesWidth)]; REQUIRE(Math::equalsEpsilon(normal.x, expectedNormal.x, Math::EPSILON7)); REQUIRE(Math::equalsEpsilon(normal.y, expectedNormal.y, Math::EPSILON7)); REQUIRE(Math::equalsEpsilon(normal.z, expectedNormal.z, Math::EPSILON7)); @@ -538,8 +538,8 @@ static void checkGeneratedGridNormal(const QuantizedMesh& quantizedMesh, x = verticesWidth - 1; y = verticesHeight - 1; for (size_t i = 0; i < eastIndicesCount; ++i) { - glm::vec3 normal = normals[currentVertexCount + i]; - glm::vec3 expectedNormal = expectedNormals[static_cast(index2DTo1D(x, y, verticesWidth))]; + glm::vec3 normal = normals[int64_t(currentVertexCount + i)]; + glm::vec3 expectedNormal = expectedNormals[index2DTo1D(x, y, verticesWidth)]; REQUIRE(Math::equalsEpsilon(normal.x, expectedNormal.x, Math::EPSILON7)); REQUIRE(Math::equalsEpsilon(normal.y, expectedNormal.y, Math::EPSILON7)); REQUIRE(Math::equalsEpsilon(normal.z, expectedNormal.z, Math::EPSILON7)); @@ -551,8 +551,8 @@ static void checkGeneratedGridNormal(const QuantizedMesh& quantizedMesh, x = 0; y = verticesHeight - 1; for (size_t i = 0; i < northIndicesCount; ++i) { - glm::vec3 normal = normals[currentVertexCount + i]; - glm::vec3 expectedNormal = expectedNormals[static_cast(index2DTo1D(x, y, verticesWidth))]; + glm::vec3 normal = normals[int64_t(currentVertexCount + i)]; + glm::vec3 expectedNormal = expectedNormals[index2DTo1D(x, y, verticesWidth)]; REQUIRE(Math::equalsEpsilon(normal.x, expectedNormal.x, Math::EPSILON7)); REQUIRE(Math::equalsEpsilon(normal.y, expectedNormal.y, Math::EPSILON7)); REQUIRE(Math::equalsEpsilon(normal.z, expectedNormal.z, Math::EPSILON7)); diff --git a/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp b/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp index f08ffe760..3741aed14 100644 --- a/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp +++ b/Cesium3DTiles/test/TestUpsampleGltfForRasterOverlay.cpp @@ -7,6 +7,7 @@ #include "SkirtMeshMetadata.h" #include "upsampleGltfForRasterOverlays.h" #include +#include #include using namespace Cesium3DTiles; @@ -70,30 +71,30 @@ TEST_CASE("Test upsample tile without skirts") { model.accessors.emplace_back(); Accessor &positionAccessor = model.accessors.back(); - positionAccessor.bufferView = static_cast(model.bufferViews.size() - 1); + positionAccessor.bufferView = static_cast(model.bufferViews.size() - 1); positionAccessor.byteOffset = 0; - positionAccessor.count = positions.size(); + positionAccessor.count = static_cast(positions.size()); positionAccessor.componentType = Accessor::ComponentType::FLOAT; positionAccessor.type = Accessor::Type::VEC3; - int positionAccessorIdx = static_cast(model.accessors.size() - 1); + int32_t positionAccessorIdx = static_cast(model.accessors.size() - 1); // create uv model.bufferViews.emplace_back(); BufferView &uvBufferView = model.bufferViews.emplace_back(); - uvBufferView.buffer = static_cast(model.buffers.size() - 1); + uvBufferView.buffer = static_cast(model.buffers.size() - 1); uvBufferView.byteOffset = positionsBufferSize; uvBufferView.byteLength = uvsBufferSize; model.accessors.emplace_back(); Accessor &uvAccessor = model.accessors.back(); - uvAccessor.bufferView = static_cast(model.bufferViews.size() - 1); + uvAccessor.bufferView = static_cast(model.bufferViews.size() - 1); uvAccessor.byteOffset = 0; - uvAccessor.count = uvs.size(); + uvAccessor.count = static_cast(uvs.size()); uvAccessor.componentType = Accessor::ComponentType::FLOAT; uvAccessor.type = Accessor::Type::VEC2; - int uvAccessorIdx = static_cast(model.accessors.size() - 1); + int32_t uvAccessorIdx = static_cast(model.accessors.size() - 1); // create indices model.bufferViews.emplace_back(); @@ -106,7 +107,7 @@ TEST_CASE("Test upsample tile without skirts") { Accessor &indicesAccessor = model.accessors.back(); indicesAccessor.bufferView = static_cast(model.bufferViews.size() - 1); indicesAccessor.byteOffset = 0; - indicesAccessor.count = indices.size(); + indicesAccessor.count = static_cast(indices.size()); indicesAccessor.componentType = Accessor::ComponentType::UNSIGNED_SHORT; indicesAccessor.type = Accessor::Type::SCALAR; diff --git a/CesiumGltf/include/CesiumGltf/JsonValue.h b/CesiumGltf/include/CesiumGltf/JsonValue.h index 708622335..97fc48a9e 100644 --- a/CesiumGltf/include/CesiumGltf/JsonValue.h +++ b/CesiumGltf/include/CesiumGltf/JsonValue.h @@ -1,21 +1,24 @@ #pragma once +#include +#include +#include +#include #include #include -#include namespace CesiumGltf { class JsonValue final { public: - using Null = nullptr_t; + using Null = std::nullptr_t; using Number = double; using Bool = bool; using String = std::string; - using Object = std::unordered_map; + using Object = std::map; using Array = std::vector; JsonValue() : value() {} - JsonValue(nullptr_t) : value(nullptr) {} + JsonValue(std::nullptr_t) : value(nullptr) {} JsonValue(double v) : value(v) {} JsonValue(int8_t v) : JsonValue(static_cast(v)) {} JsonValue(uint8_t v) : JsonValue(static_cast(v)) {} @@ -29,15 +32,15 @@ namespace CesiumGltf { JsonValue(const std::string& v) : value(v) {} JsonValue(std::string&& v) : value(std::move(v)) {} JsonValue(const char* v) : value(std::string(v)) {} - JsonValue(const std::unordered_map& v) : value(v) {} - JsonValue(std::unordered_map&& v) : value(std::move(v)) {} + JsonValue(const std::map& v) : value(v) {} + JsonValue(std::map&& v) : value(std::move(v)) {} JsonValue(const std::vector& v) : value(v) {} JsonValue(std::vector&& v) : value(std::move(v)) {} JsonValue(std::initializer_list v) : value(std::vector(v)) {} JsonValue(std::initializer_list> v) : - value(std::unordered_map(v)) {} + value(std::map(v)) {} /** * @brief Gets the number from the value, or a default if the value does not contain a number. diff --git a/CesiumGltfReader/src/DictionaryJsonHandler.h b/CesiumGltfReader/src/DictionaryJsonHandler.h index b55e868b5..ef83fbe54 100644 --- a/CesiumGltfReader/src/DictionaryJsonHandler.h +++ b/CesiumGltfReader/src/DictionaryJsonHandler.h @@ -3,6 +3,7 @@ #include "ObjectJsonHandler.h" #include "IntegerJsonHandler.h" #include +#include namespace CesiumGltf { template @@ -10,25 +11,39 @@ namespace CesiumGltf { public: void reset(IJsonHandler* pParent, std::unordered_map* pDictionary) { ObjectJsonHandler::reset(pParent); - this->_pDictionary = pDictionary; + this->_pDictionary1 = pDictionary; } - std::unordered_map* getObject() { return this->_pDictionary; } + void reset(IJsonHandler* pParent, std::map* pDictionary) { + ObjectJsonHandler::reset(pParent); + this->_pDictionary2 = pDictionary; + } virtual IJsonHandler* Key(const char* str, size_t /*length*/, bool /*copy*/) override { - assert(this->_pDictionary); + assert(this->_pDictionary1 || this->_pDictionary2); + + if (this->_pDictionary1) { + auto it = this->_pDictionary1->emplace(str, T()).first; - auto it = this->_pDictionary->emplace(str, T()).first; + return this->property( + it->first.c_str(), + this->_item, + it->second + ); + } else { + auto it = this->_pDictionary2->emplace(str, T()).first; - return this->property( - it->first.c_str(), - this->_item, - it->second - ); + return this->property( + it->first.c_str(), + this->_item, + it->second + ); + } } private: - std::unordered_map* _pDictionary; + std::unordered_map* _pDictionary1 = nullptr; + std::map* _pDictionary2 = nullptr; THandler _item; }; } diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index a24f55de1..62575c39e 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -292,7 +292,7 @@ namespace { } gsl::span bufferSpan(buffer.cesium.data); - gsl::span bufferViewSpan = bufferSpan.subspan(bufferView.byteOffset, bufferView.byteLength); + gsl::span bufferViewSpan = bufferSpan.subspan(static_cast(bufferView.byteOffset), static_cast(bufferView.byteLength)); ImageReaderResult imageResult = readImage(bufferViewSpan); if (imageResult.image) { image.cesium = std::move(imageResult.image.value()); diff --git a/CesiumGltfReader/src/decodeDraco.cpp b/CesiumGltfReader/src/decodeDraco.cpp index 8b2a79f1a..0f5f9e858 100644 --- a/CesiumGltfReader/src/decodeDraco.cpp +++ b/CesiumGltfReader/src/decodeDraco.cpp @@ -4,12 +4,17 @@ #include "CesiumGltf/Reader.h" #include +#ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4127) +#endif + #include #include -#pragma warning(pop) +#ifdef _MSC_VER +#pragma warning(pop) +#endif namespace { using namespace CesiumGltf; @@ -21,21 +26,23 @@ namespace { ) { Model& model = readModel.model.value(); - if (draco.bufferView < 0 || draco.bufferView >= model.bufferViews.size()) { + BufferView* pBufferView = Model::getSafe(&model.bufferViews, draco.bufferView); + if (!pBufferView) { if (!readModel.warnings.empty()) readModel.warnings += "\n"; readModel.warnings += "Draco bufferView index is invalid."; return nullptr; } - BufferView& bufferView = model.bufferViews[draco.bufferView]; + BufferView& bufferView = *pBufferView; - if (bufferView.buffer < 0 || bufferView.buffer >= model.buffers.size()) { + Buffer* pBuffer = Model::getSafe(&model.buffers, bufferView.buffer); + if (!pBuffer) { if (!readModel.warnings.empty()) readModel.warnings += "\n"; readModel.warnings += "Draco bufferView has an invalid buffer index."; return nullptr; } - Buffer& buffer = model.buffers[bufferView.buffer]; + Buffer& buffer = *pBuffer; if (bufferView.byteOffset < 0 || bufferView.byteLength < 0 || bufferView.byteOffset + bufferView.byteLength > static_cast(buffer.cesium.data.size())) { if (!readModel.warnings.empty()) readModel.warnings += "\n"; @@ -43,7 +50,7 @@ namespace { return nullptr; } - gsl::span data(buffer.cesium.data.data() + bufferView.byteOffset, bufferView.byteLength); + gsl::span data(buffer.cesium.data.data() + bufferView.byteOffset, static_cast(bufferView.byteLength)); draco::DecoderBuffer decodeBuffer; decodeBuffer.Init(reinterpret_cast(data.data()), data.size()); @@ -105,7 +112,7 @@ namespace { int64_t indexBytes = pIndicesAccessor->computeByteSizeOfComponent(); int64_t indicesBytes = pIndicesAccessor->count * indexBytes; - indicesBuffer.cesium.data.resize(indicesBytes); + indicesBuffer.cesium.data.resize(static_cast(indicesBytes)); indicesBuffer.byteLength = indicesBytes; indicesBufferView.byteLength = indicesBytes; indicesBufferView.byteStride = indexBytes; @@ -165,7 +172,7 @@ namespace { int64_t stride = numberOfComponents * pAccessor->computeByteSizeOfComponent(); int64_t sizeBytes = pAccessor->count * stride; - buffer.cesium.data.resize(sizeBytes); + buffer.cesium.data.resize(static_cast(sizeBytes)); buffer.byteLength = sizeBytes; bufferView.byteLength = sizeBytes; bufferView.byteStride = stride; @@ -220,7 +227,7 @@ namespace { copyDecodedIndices(readModel, primitive, pMesh.get()); - for (const std::pair& attribute : draco.attributes) { + for (const std::pair& attribute : draco.attributes) { auto primitiveAttrIt = primitive.attributes.find(attribute.first); if (primitiveAttrIt == primitive.attributes.end()) { // The primitive does not use this attribute. The KHR_draco_mesh_compression spec @@ -243,7 +250,7 @@ namespace { } int32_t dracoAttrIndex = attribute.second; - const draco::PointAttribute* pAttribute = pMesh->GetAttributeByUniqueId(dracoAttrIndex); + const draco::PointAttribute* pAttribute = pMesh->GetAttributeByUniqueId(static_cast(dracoAttrIndex)); if (pAttribute == nullptr) { if (!readModel.warnings.empty()) { readModel.warnings += "\n"; From 3fe36a7c7b58d0e7f7ec157bc8e2e854f7281cc3 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 17:30:01 +1100 Subject: [PATCH 48/61] Fix GCC build problems. --- .../include/Cesium3DTiles/RasterOverlayTileProvider.h | 4 ++-- Cesium3DTiles/src/RasterOverlayTileProvider.cpp | 4 ++-- Cesium3DTiles/src/Tile.cpp | 10 +++++----- CesiumGltfReader/src/ObjectJsonHandler.h | 10 +++++++--- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTileProvider.h b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTileProvider.h index b3da38c54..66d603ed5 100644 --- a/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTileProvider.h +++ b/Cesium3DTiles/include/Cesium3DTiles/RasterOverlayTileProvider.h @@ -197,7 +197,7 @@ namespace Cesium3DTiles { /** * @brief Gets the number of bytes of tile data that are currently loaded. */ - size_t getTileDataBytes() const noexcept { return this->_tileDataBytes; } + int64_t getTileDataBytes() const noexcept { return this->_tileDataBytes; } /** * @brief Returns the number of tiles that are currently loading. @@ -249,7 +249,7 @@ namespace Cesium3DTiles { uint32_t _imageHeight; std::unordered_map> _tiles; std::unique_ptr _pPlaceholder; - size_t _tileDataBytes; + int64_t _tileDataBytes; uint32_t _tilesCurrentlyLoading; }; } diff --git a/Cesium3DTiles/src/RasterOverlayTileProvider.cpp b/Cesium3DTiles/src/RasterOverlayTileProvider.cpp index e42f83822..35fce1d2b 100644 --- a/Cesium3DTiles/src/RasterOverlayTileProvider.cpp +++ b/Cesium3DTiles/src/RasterOverlayTileProvider.cpp @@ -356,7 +356,7 @@ namespace Cesium3DTiles { } void RasterOverlayTileProvider::notifyTileLoaded(RasterOverlayTile* pTile) noexcept { - this->_tileDataBytes += pTile->getImage().pixelData.size(); + this->_tileDataBytes += int64_t(pTile->getImage().pixelData.size()); --this->_tilesCurrentlyLoading; } @@ -367,7 +367,7 @@ namespace Cesium3DTiles { assert(it != this->_tiles.end()); assert(it->second.get() == pTile); - this->_tileDataBytes -= pTile->getImage().pixelData.size(); + this->_tileDataBytes -= int64_t(pTile->getImage().pixelData.size()); RasterOverlay& overlay = pTile->getOverlay(); diff --git a/Cesium3DTiles/src/Tile.cpp b/Cesium3DTiles/src/Tile.cpp index afc5da214..b17346fc7 100644 --- a/Cesium3DTiles/src/Tile.cpp +++ b/Cesium3DTiles/src/Tile.cpp @@ -588,20 +588,20 @@ namespace Cesium3DTiles { // Add up the glTF buffers for (const CesiumGltf::Buffer& buffer : model.buffers) { - bytes += buffer.cesium.data.size(); + bytes += int64_t(buffer.cesium.data.size()); } // For images loaded from buffers, subtract the buffer size and add // the decoded image size instead. const std::vector& bufferViews = model.bufferViews; for (const CesiumGltf::Image& image : model.images) { - int bufferView = image.bufferView; - if (bufferView < 0 || bufferView >= static_cast(bufferViews.size())) { + int32_t bufferView = image.bufferView; + if (bufferView < 0 || bufferView >= static_cast(bufferViews.size())) { continue; } - bytes -= bufferViews[static_cast(bufferView)].byteLength; - bytes += image.cesium.pixelData.size(); + bytes -= bufferViews[size_t(bufferView)].byteLength; + bytes += int64_t(image.cesium.pixelData.size()); } } diff --git a/CesiumGltfReader/src/ObjectJsonHandler.h b/CesiumGltfReader/src/ObjectJsonHandler.h index 026aba6ed..23f846a2b 100644 --- a/CesiumGltfReader/src/ObjectJsonHandler.h +++ b/CesiumGltfReader/src/ObjectJsonHandler.h @@ -17,7 +17,7 @@ namespace CesiumGltf { IJsonHandler* property(const char* currentKey, TAccessor& accessor, TProperty& value) { this->_currentKey = currentKey; - if constexpr (isOptional) { + if constexpr (isOptional::value) { value.emplace(); accessor.reset(this, &value.value()); } else { @@ -31,10 +31,14 @@ namespace CesiumGltf { private: template - static constexpr bool isOptional = false; + struct isOptional { + static constexpr bool value = false; + }; template - static constexpr bool isOptional> = true; + struct isOptional> { + static constexpr bool value = true; + }; int32_t _depth = 0; const char* _currentKey; From b8bfe333882a4eed02b73bc92d786c7ded0ea300 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 17:58:02 +1100 Subject: [PATCH 49/61] More signed/unsigned warnings. --- .../src/upsampleGltfForRasterOverlays.cpp | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp index bf13e1126..b3b584a68 100644 --- a/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp +++ b/Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp @@ -66,8 +66,8 @@ namespace Cesium3DTiles { const std::vector& edgeIndices, const glm::dvec3& center, double skirtHeight, - size_t vertexSizeFloats, - uint32_t positionAttributeIndex); + int64_t vertexSizeFloats, + int32_t positionAttributeIndex); static void addSkirts(std::vector& output, std::vector& indices, @@ -76,8 +76,8 @@ namespace Cesium3DTiles { SkirtMeshMetadata ¤tSkirt, const SkirtMeshMetadata &parentSkirt, EdgeIndices &edgeIndices, - size_t vertexSizeFloats, - uint32_t positionAttributeIndex); + int64_t vertexSizeFloats, + int32_t positionAttributeIndex); Model upsampleGltfForRasterOverlays(const Model& parentModel, CesiumGeometry::QuadtreeChild childID) { Model result; @@ -309,9 +309,9 @@ namespace Cesium3DTiles { indexBufferView.buffer = static_cast(indexBufferIndex); indexBufferView.target = BufferView::Target::ARRAY_BUFFER; - uint32_t vertexSizeFloats = 0; - int uvAccessorIndex = -1; - int positionAttributeIndex = -1; + int64_t vertexSizeFloats = 0; + int32_t uvAccessorIndex = -1; + int32_t positionAttributeIndex = -1; std::vector toRemove; @@ -360,11 +360,11 @@ namespace Cesium3DTiles { model.accessors.emplace_back(); Accessor& newAccessor = model.accessors.back(); newAccessor.bufferView = static_cast(vertexBufferIndex); - newAccessor.byteOffset = vertexSizeFloats * sizeof(float); + newAccessor.byteOffset = vertexSizeFloats * int64_t(sizeof(float)); newAccessor.componentType = Accessor::ComponentType::FLOAT; newAccessor.type = accessor.type; - vertexSizeFloats += static_cast(accessorComponentElements); + vertexSizeFloats += accessorComponentElements; attributes.push_back(FloatVertexAttribute { buffer.cesium.data, @@ -378,7 +378,7 @@ namespace Cesium3DTiles { // get position to be used to create for skirts later if (attribute.first == "POSITION") { - positionAttributeIndex = static_cast(attributes.size() - 1); + positionAttributeIndex = int32_t(attributes.size() - 1); } } @@ -503,7 +503,7 @@ namespace Cesium3DTiles { *parentSkirtMeshMetadata, edgeIndices, vertexSizeFloats, - static_cast(positionAttributeIndex)); + positionAttributeIndex); } // Update the accessor vertex counts and min/max values @@ -531,7 +531,7 @@ namespace Cesium3DTiles { float* pAsFloats = reinterpret_cast(vertexBuffer.cesium.data.data()); std::copy(newVertexFloats.begin(), newVertexFloats.end(), pAsFloats); vertexBufferView.byteLength = int64_t(vertexBuffer.cesium.data.size()); - vertexBufferView.byteStride = vertexSizeFloats * sizeof(float); + vertexBufferView.byteStride = vertexSizeFloats * int64_t(sizeof(float)); Buffer& indexBuffer = model.buffers[indexBufferIndex]; indexBuffer.cesium.data.resize(indices.size() * sizeof(uint32_t)); @@ -668,20 +668,20 @@ namespace Cesium3DTiles { const std::vector& edgeIndices, const glm::dvec3& center, double skirtHeight, - size_t vertexSizeFloats, - uint32_t positionAttributeIndex) + int64_t vertexSizeFloats, + int32_t positionAttributeIndex) { const CesiumGeospatial::Ellipsoid& ellipsoid = CesiumGeospatial::Ellipsoid::WGS84; - uint32_t newEdgeIndex = static_cast(output.size() / vertexSizeFloats); - for (uint32_t i = 0; i < edgeIndices.size(); ++i) { + uint32_t newEdgeIndex = uint32_t(output.size() / size_t(vertexSizeFloats)); + for (size_t i = 0; i < edgeIndices.size(); ++i) { uint32_t edgeIdx = edgeIndices[i]; uint32_t offset = 0; - for (uint32_t j = 0; j < attributes.size(); ++j) { + for (size_t j = 0; j < attributes.size(); ++j) { FloatVertexAttribute& attribute = attributes[j]; - uint32_t valueIndex = offset + static_cast(vertexSizeFloats) * edgeIdx; + uint32_t valueIndex = offset + uint32_t(vertexSizeFloats) * edgeIdx; - if (j == positionAttributeIndex) { + if (int32_t(j) == positionAttributeIndex) { glm::dvec3 position{ output[valueIndex], output[valueIndex + 1], output[valueIndex + 2] }; position += center; @@ -727,8 +727,8 @@ namespace Cesium3DTiles { SkirtMeshMetadata ¤tSkirt, const SkirtMeshMetadata &parentSkirt, EdgeIndices &edgeIndices, - size_t vertexSizeFloats, - uint32_t positionAttributeIndex) + int64_t vertexSizeFloats, + int32_t positionAttributeIndex) { glm::dvec3 center = currentSkirt.meshCenter; double shortestSkirtHeight = glm::min(parentSkirt.skirtWestHeight, parentSkirt.skirtEastHeight); From 56feb198dfb30f56e22d0a55490da7acee4b8dd2 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 19:32:14 +1100 Subject: [PATCH 50/61] List of errors and warnings instead of a single string for each. --- Cesium3DTiles/src/GltfContent.cpp | 5 +- Cesium3DTiles/src/RasterOverlayTile.cpp | 9 +-- CesiumGltfReader/include/CesiumGltf/Reader.h | 10 +-- CesiumGltfReader/src/Reader.cpp | 65 +++++++++---------- CesiumGltfReader/src/decodeDraco.cpp | 40 ++++-------- .../include/CesiumUtility/joinToString.h | 45 +++++++++++++ 6 files changed, 99 insertions(+), 75 deletions(-) create mode 100644 CesiumUtility/include/CesiumUtility/joinToString.h diff --git a/Cesium3DTiles/src/GltfContent.cpp b/Cesium3DTiles/src/GltfContent.cpp index aae3dd968..8eed5c24b 100644 --- a/Cesium3DTiles/src/GltfContent.cpp +++ b/Cesium3DTiles/src/GltfContent.cpp @@ -4,6 +4,7 @@ #include "CesiumGltf/AccessorWriter.h" #include "CesiumGltf/Reader.h" #include "CesiumUtility/Math.h" +#include "CesiumUtility/joinToString.h" #include namespace Cesium3DTiles { @@ -24,10 +25,10 @@ namespace Cesium3DTiles { CesiumGltf::ModelReaderResult loadedModel = CesiumGltf::readModel(data); if (!loadedModel.errors.empty()) { - SPDLOG_LOGGER_ERROR(pLogger, "Failed to load binary glTF from {}: {}", url, loadedModel.errors); + SPDLOG_LOGGER_ERROR(pLogger, "Failed to load binary glTF from {}:\n- {}", url, CesiumUtility::joinToString(loadedModel.errors, "\n- ")); } if (!loadedModel.warnings.empty()) { - SPDLOG_LOGGER_WARN(pLogger, "Warning when loading binary glTF from {}: {}", url, loadedModel.warnings); + SPDLOG_LOGGER_WARN(pLogger, "Warning when loading binary glTF from {}:\n- {}", url, CesiumUtility::joinToString(loadedModel.warnings, "\n- ")); } pResult->model = std::move(loadedModel.model); diff --git a/Cesium3DTiles/src/RasterOverlayTile.cpp b/Cesium3DTiles/src/RasterOverlayTile.cpp index cd03513f3..91705ad74 100644 --- a/Cesium3DTiles/src/RasterOverlayTile.cpp +++ b/Cesium3DTiles/src/RasterOverlayTile.cpp @@ -6,6 +6,7 @@ #include "CesiumAsync/IAssetResponse.h" #include "CesiumAsync/ITaskProcessor.h" #include "CesiumGltf/Reader.h" +#include "CesiumUtility/joinToString.h" using namespace CesiumAsync; @@ -50,8 +51,8 @@ namespace Cesium3DTiles { LoadState state; CesiumGltf::ImageCesium image; - std::string warnings; - std::string errors; + std::vector warnings; + std::vector errors; void* pRendererResources; }; @@ -82,7 +83,7 @@ namespace Cesium3DTiles { CesiumGltf::ImageReaderResult loadedImage = CesiumGltf::readImage(data); if (!loadedImage.image.has_value()) { - SPDLOG_LOGGER_ERROR(pLogger, "Failed to load image: {}", loadedImage.errors); + SPDLOG_LOGGER_ERROR(pLogger, "Failed to load image:\n- {}", CesiumUtility::joinToString(loadedImage.errors, "\n- ")); LoadResult result; result.pRendererResources = nullptr; @@ -91,7 +92,7 @@ namespace Cesium3DTiles { } if (!loadedImage.warnings.empty()) { - SPDLOG_LOGGER_WARN(pLogger, "Warnings while loading image: {}", loadedImage.warnings); + SPDLOG_LOGGER_WARN(pLogger, "Warnings while loading image:\n- {}", CesiumUtility::joinToString(loadedImage.warnings, "\n- ")); } CesiumGltf::ImageCesium& image = loadedImage.image.value(); diff --git a/CesiumGltfReader/include/CesiumGltf/Reader.h b/CesiumGltfReader/include/CesiumGltf/Reader.h index 0cffab4a7..2d41e5e83 100644 --- a/CesiumGltfReader/include/CesiumGltf/Reader.h +++ b/CesiumGltfReader/include/CesiumGltf/Reader.h @@ -3,12 +3,14 @@ #include "CesiumGltf/Model.h" #include #include +#include +#include namespace CesiumGltf { struct ModelReaderResult { std::optional model; - std::string errors; - std::string warnings; + std::vector errors; + std::vector warnings; }; struct ReadModelOptions { @@ -21,8 +23,8 @@ namespace CesiumGltf { struct ImageReaderResult { std::optional image; - std::string errors; - std::string warnings; + std::vector errors; + std::vector warnings; }; ImageReaderResult readImage(const gsl::span& data); diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 62575c39e..6c1a09327 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -50,18 +50,16 @@ namespace { } virtual void reportWarning(const std::string& warning, std::vector&& context) override { - if (!this->_result.warnings.empty()) { - this->_result.warnings.push_back('\n'); - } - - this->_result.warnings += warning; - this->_result.warnings += "\n While parsing: "; + std::string fullWarning = warning; + fullWarning += "\n While parsing: "; for (auto it = context.rbegin(); it != context.rend(); ++it) { - this->_result.warnings += *it; + fullWarning += *it; } - this->_result.warnings += "\n From byte offset: "; - this->_result.warnings += std::to_string(this->_inputStream.Tell()); + fullWarning += "\n From byte offset: "; + fullWarning += std::to_string(this->_inputStream.Tell()); + + this->_result.warnings.emplace_back(std::move(fullWarning)); } private: @@ -156,11 +154,7 @@ namespace { s += std::to_string(reader.GetErrorOffset()); s += ": "; s += getMessageFromRapidJsonError(reader.GetParseErrorCode()); - - if (!result.errors.empty()) { - result.errors.push_back('\n'); - } - result.errors += s; + result.errors.emplace_back(std::move(s)); } return result; @@ -170,8 +164,8 @@ namespace { if (data.size() < sizeof(GlbHeader) + sizeof(ChunkHeader)) { return { std::nullopt, - "Too short to be a valid GLB.", - "" + {"Too short to be a valid GLB."}, + {} }; } @@ -179,24 +173,24 @@ namespace { if (pHeader->magic != 0x46546C67) { return { std::nullopt, - "GLB does not start with the expected magic value 'glTF'.", - "" + { "GLB does not start with the expected magic value 'glTF'." }, + {} }; } if (pHeader->version != 2) { return { std::nullopt, - "Only binary glTF version 2 is supported.", - "" + { "Only binary glTF version 2 is supported." }, + {} }; } if (pHeader->length > data.size()) { return { std::nullopt, - "GLB extends past the end of the buffer.", - "" + { "GLB extends past the end of the buffer." }, + {} }; } @@ -206,8 +200,8 @@ namespace { if (pJsonChunkHeader->chunkType != 0x4E4F534A) { return { std::nullopt, - "GLB JSON chunk does not have the expected chunkType.", - "" + { "GLB JSON chunk does not have the expected chunkType." }, + {} }; } @@ -217,8 +211,8 @@ namespace { if (jsonEnd > glbData.size()) { return { std::nullopt, - "GLB JSON chunk extends past the end of the buffer.", - "" + { "GLB JSON chunk extends past the end of the buffer." }, + {} }; } @@ -230,8 +224,8 @@ namespace { if (pBinaryChunkHeader->chunkType != 0x004E4942) { return { std::nullopt, - "GLB binary chunk does not have the expected chunkType.", - "" + { "GLB binary chunk does not have the expected chunkType." }, + {} }; } @@ -241,8 +235,8 @@ namespace { if (binaryEnd > glbData.size()) { return { std::nullopt, - "GLB binary chunk extends past the end of the buffer.", - "" + { "GLB binary chunk extends past the end of the buffer." }, + {} }; } @@ -255,19 +249,19 @@ namespace { Model& model = result.model.value(); if (model.buffers.size() == 0) { - result.errors = "GLB has a binary chunk but the JSON does not define any buffers."; + result.errors.emplace_back("GLB has a binary chunk but the JSON does not define any buffers."); return result; } Buffer& buffer = model.buffers[0]; if (buffer.uri) { - result.errors = "GLB has a binary chunk but the first buffer in the JSON chunk also has a 'uri'."; + result.errors.emplace_back("GLB has a binary chunk but the first buffer in the JSON chunk also has a 'uri'."); return result; } int64_t binaryChunkSize = static_cast(binaryChunk.size()); if (buffer.byteLength > binaryChunkSize || buffer.byteLength + 3 < binaryChunkSize) { - result.errors = "GLB binary chunk size does not match the size of the first buffer in the JSON chunk."; + result.errors.emplace_back("GLB binary chunk size does not match the size of the first buffer in the JSON chunk."); return result; } @@ -286,8 +280,7 @@ namespace { const Buffer& buffer = Model::getSafe(model.buffers, bufferView.buffer); if (bufferView.byteOffset + bufferView.byteLength > static_cast(buffer.cesium.data.size())) { - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "Image bufferView's byteLength is more than the available bytes."; + readModel.warnings.emplace_back("Image bufferView's byteLength is more than the available bytes."); continue; } @@ -332,7 +325,7 @@ ImageReaderResult CesiumGltf::readImage(const gsl::span& data) { stbi_image_free(pImage); } else { result.image.reset(); - result.errors = stbi_failure_reason(); + result.errors.emplace_back(stbi_failure_reason()); } return result; diff --git a/CesiumGltfReader/src/decodeDraco.cpp b/CesiumGltfReader/src/decodeDraco.cpp index 0f5f9e858..b5dda07e7 100644 --- a/CesiumGltfReader/src/decodeDraco.cpp +++ b/CesiumGltfReader/src/decodeDraco.cpp @@ -28,8 +28,7 @@ namespace { BufferView* pBufferView = Model::getSafe(&model.bufferViews, draco.bufferView); if (!pBufferView) { - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "Draco bufferView index is invalid."; + readModel.warnings.emplace_back("Draco bufferView index is invalid."); return nullptr; } @@ -37,16 +36,14 @@ namespace { Buffer* pBuffer = Model::getSafe(&model.buffers, bufferView.buffer); if (!pBuffer) { - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "Draco bufferView has an invalid buffer index."; + readModel.warnings.emplace_back("Draco bufferView has an invalid buffer index."); return nullptr; } Buffer& buffer = *pBuffer; if (bufferView.byteOffset < 0 || bufferView.byteLength < 0 || bufferView.byteOffset + bufferView.byteLength > static_cast(buffer.cesium.data.size())) { - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "Draco bufferView extends beyond its buffer."; + readModel.warnings.emplace_back("Draco bufferView extends beyond its buffer."); return nullptr; } @@ -59,9 +56,7 @@ namespace { draco::Mesh mesh; draco::StatusOr> result = decoder.DecodeMeshFromBuffer(&decodeBuffer); if (!result.ok()) { - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "Draco decoding failed: "; - readModel.warnings += result.status().error_msg_string(); + readModel.warnings.emplace_back(std::string("Draco decoding failed: ") + result.status().error_msg_string()); return nullptr; } @@ -91,14 +86,12 @@ namespace { Accessor* pIndicesAccessor = Model::getSafe(&model.accessors, primitive.indices); if (!pIndicesAccessor) { - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "Primitive indices accessor ID is invalid."; + readModel.warnings.emplace_back("Primitive indices accessor ID is invalid."); return; } if (pIndicesAccessor->count > pMesh->num_faces() * 3) { - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "There are fewer decoded Draco indices than are expected by the accessor."; + readModel.warnings.emplace_back("There are fewer decoded Draco indices than are expected by the accessor."); pIndicesAccessor->count = pMesh->num_faces() * 3; } @@ -156,8 +149,7 @@ namespace { Model& model = readModel.model.value(); if (pAccessor->count > pMesh->num_points()) { - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "There are fewer decoded Draco indices than are expected by the accessor."; + readModel.warnings.emplace_back("There are fewer decoded Draco indices than are expected by the accessor."); pAccessor->count = pMesh->num_points(); } @@ -207,8 +199,7 @@ namespace { doCopy(reinterpret_cast(buffer.cesium.data.data())); break; default: - if (!readModel.warnings.empty()) readModel.warnings += "\n"; - readModel.warnings += "Accessor uses an unknown componentType: " + std::to_string(int32_t(pAccessor->componentType)); + readModel.warnings.emplace_back("Accessor uses an unknown componentType: " + std::to_string(int32_t(pAccessor->componentType))); break; } } @@ -232,30 +223,21 @@ namespace { if (primitiveAttrIt == primitive.attributes.end()) { // The primitive does not use this attribute. The KHR_draco_mesh_compression spec // says this shouldn't happen, so warn. - if (!readModel.warnings.empty()) { - readModel.warnings += "\n"; - } - readModel.warnings += "Draco extension has the " + attribute.first + " attribute, but the primitive does not have that attribute."; + readModel.warnings.emplace_back("Draco extension has the " + attribute.first + " attribute, but the primitive does not have that attribute."); continue; } int32_t primitiveAttrIndex = primitiveAttrIt->second; Accessor* pAccessor = Model::getSafe(&model.accessors, primitiveAttrIndex); if (!pAccessor) { - if (!readModel.warnings.empty()) { - readModel.warnings += "\n"; - } - readModel.warnings += "Primitive attribute's accessor index is invalid."; + readModel.warnings.emplace_back("Primitive attribute's accessor index is invalid."); continue; } int32_t dracoAttrIndex = attribute.second; const draco::PointAttribute* pAttribute = pMesh->GetAttributeByUniqueId(static_cast(dracoAttrIndex)); if (pAttribute == nullptr) { - if (!readModel.warnings.empty()) { - readModel.warnings += "\n"; - } - readModel.warnings += "Draco attribute with unique ID " + std::to_string(dracoAttrIndex) + " does not exist."; + readModel.warnings.emplace_back("Draco attribute with unique ID " + std::to_string(dracoAttrIndex) + " does not exist."); continue; } diff --git a/CesiumUtility/include/CesiumUtility/joinToString.h b/CesiumUtility/include/CesiumUtility/joinToString.h new file mode 100644 index 000000000..36e1fc968 --- /dev/null +++ b/CesiumUtility/include/CesiumUtility/joinToString.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +namespace CesiumUtility { + /** + * @brief Joins multiple elements together into a string, separated by a given separator. + * + * @tparam TIterator The type of the collection iterator. + * @param begin An iterator referring to the first element to join. + * @param end An iterator referring to one past the last element to join. + * @param separator The string to use to separate successive elements. + * @return The joined string. + */ + template + std::string joinToString(TIterator begin, TIterator end, const std::string& separator) { + return std::accumulate(begin, end, std::string(), [&separator](const std::string& acc, const std::string& element) { + if (!acc.empty()) { + return acc + separator + element; + } else { + return element; + } + }); + } + + /** + * @brief Joins multiple elements together into a string, separated by a given separator. + * + * @tparam TIterator The type of the collection iterator. + * @param collection The collection of elements to be joined. + * @param separator The string to use to separate successive elements. + * @return The joined string. + */ + template + std::string joinToString(TCollection collection, const std::string& separator) { + return std::accumulate(collection.cbegin(), collection.cend(), std::string(), [&separator](const std::string& acc, const std::string& element) { + if (!acc.empty()) { + return acc + separator + element; + } else { + return element; + } + }); + } +} \ No newline at end of file From 8d0b1f921016a766bbf6ffedf6f20a4c5db20c2a Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 20 Jan 2021 19:55:34 +1100 Subject: [PATCH 51/61] Move and rename test. --- .../test/TestReader.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) rename CesiumGltf/test/TestGltfModel.cpp => CesiumGltfReader/test/TestReader.cpp (87%) diff --git a/CesiumGltf/test/TestGltfModel.cpp b/CesiumGltfReader/test/TestReader.cpp similarity index 87% rename from CesiumGltf/test/TestGltfModel.cpp rename to CesiumGltfReader/test/TestReader.cpp index 20953869d..1627a336b 100644 --- a/CesiumGltf/test/TestGltfModel.cpp +++ b/CesiumGltfReader/test/TestReader.cpp @@ -6,7 +6,7 @@ using namespace CesiumGltf; -TEST_CASE("GltfModel") { +TEST_CASE("CesiumGltf::Reader") { using namespace std::string_literals; std::string s = @@ -58,14 +58,4 @@ TEST_CASE("GltfModel") { REQUIRE(model.meshes[0].primitives[0].targets.size() == 1); CHECK(model.meshes[0].primitives[0].targets[0]["POSITION"] == 10); CHECK(model.meshes[0].primitives[0].targets[0]["NORMAL"] == 11); - // std::vector v; - // GltfModel model = GltfModel::fromMemory(v); - // GltfCollection meshes = model.meshes(); - // for (const GltfMesh& mesh : meshes) { - // mesh; - // } - - // for (const std::string& s : model.extensionsUsed()) { - // s; - // } } \ No newline at end of file From 28b64347b7764b5580d3a3dfb459c36a7c5dadc7 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 25 Jan 2021 12:17:13 +1100 Subject: [PATCH 52/61] Incorporate changes from review and from the cmpt branch. --- CesiumGltf/include/CesiumGltf/Accessor.h | 3 +- .../include/CesiumGltf/AccessorSparse.h | 3 +- .../CesiumGltf/AccessorSparseIndices.h | 3 +- .../include/CesiumGltf/AccessorSparseValues.h | 3 +- CesiumGltf/include/CesiumGltf/AccessorSpec.h | 10 +- CesiumGltf/include/CesiumGltf/AccessorView.h | 46 +++- CesiumGltf/include/CesiumGltf/Animation.h | 3 +- .../include/CesiumGltf/AnimationChannel.h | 3 +- .../CesiumGltf/AnimationChannelTarget.h | 3 +- .../include/CesiumGltf/AnimationSampler.h | 3 +- CesiumGltf/include/CesiumGltf/Asset.h | 3 +- CesiumGltf/include/CesiumGltf/Buffer.h | 3 +- CesiumGltf/include/CesiumGltf/BufferCesium.h | 6 +- CesiumGltf/include/CesiumGltf/BufferSpec.h | 10 +- CesiumGltf/include/CesiumGltf/BufferView.h | 3 +- CesiumGltf/include/CesiumGltf/Camera.h | 3 +- .../include/CesiumGltf/CameraOrthographic.h | 3 +- .../include/CesiumGltf/CameraPerspective.h | 3 +- .../include/CesiumGltf/ExtensibleObject.h | 3 +- CesiumGltf/include/CesiumGltf/Image.h | 3 +- CesiumGltf/include/CesiumGltf/ImageCesium.h | 18 +- CesiumGltf/include/CesiumGltf/ImageSpec.h | 10 +- CesiumGltf/include/CesiumGltf/JsonValue.h | 3 +- .../CesiumGltf/KHR_draco_mesh_compression.h | 3 +- CesiumGltf/include/CesiumGltf/Library.h | 16 ++ CesiumGltf/include/CesiumGltf/Material.h | 3 +- .../CesiumGltf/MaterialNormalTextureInfo.h | 3 +- .../CesiumGltf/MaterialOcclusionTextureInfo.h | 3 +- .../CesiumGltf/MaterialPBRMetallicRoughness.h | 3 +- CesiumGltf/include/CesiumGltf/Mesh.h | 3 +- CesiumGltf/include/CesiumGltf/MeshPrimitive.h | 3 +- CesiumGltf/include/CesiumGltf/Model.h | 16 +- CesiumGltf/include/CesiumGltf/ModelSpec.h | 10 +- CesiumGltf/include/CesiumGltf/NamedObject.h | 3 +- CesiumGltf/include/CesiumGltf/Node.h | 3 +- CesiumGltf/include/CesiumGltf/Sampler.h | 3 +- CesiumGltf/include/CesiumGltf/Scene.h | 3 +- CesiumGltf/include/CesiumGltf/Skin.h | 3 +- CesiumGltf/include/CesiumGltf/Texture.h | 3 +- CesiumGltf/include/CesiumGltf/TextureInfo.h | 3 +- CesiumGltf/src/Model.cpp | 197 ++++++++++++++++++ CesiumGltf/test/TestAccessorView.cpp | 39 ++++ CesiumGltfReader/include/CesiumGltf/Reader.h | 11 +- .../include/CesiumGltf/ReaderLibrary.h | 11 + .../src/JsonObjectJsonHandler.cpp | 8 +- CesiumGltfReader/src/JsonObjectJsonHandler.h | 7 - 46 files changed, 437 insertions(+), 71 deletions(-) create mode 100644 CesiumGltf/include/CesiumGltf/Library.h create mode 100644 CesiumGltf/test/TestAccessorView.cpp create mode 100644 CesiumGltfReader/include/CesiumGltf/ReaderLibrary.h diff --git a/CesiumGltf/include/CesiumGltf/Accessor.h b/CesiumGltf/include/CesiumGltf/Accessor.h index 5c0290434..11014fdfb 100644 --- a/CesiumGltf/include/CesiumGltf/Accessor.h +++ b/CesiumGltf/include/CesiumGltf/Accessor.h @@ -1,13 +1,14 @@ #pragma once #include "CesiumGltf/AccessorSpec.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { struct Model; /** @copydoc AccessorSpec */ - struct Accessor : public AccessorSpec { + struct CESIUMGLTF_API Accessor final : public AccessorSpec { /** * @brief Computes the number of components for a given accessor type. * diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparse.h b/CesiumGltf/include/CesiumGltf/AccessorSparse.h index f8a494c00..8c1019c1d 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparse.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparse.h @@ -5,13 +5,14 @@ #include "CesiumGltf/AccessorSparseIndices.h" #include "CesiumGltf/AccessorSparseValues.h" #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { /** * @brief Sparse storage of attributes that deviate from their initialization value. */ - struct AccessorSparse : public ExtensibleObject { + struct CESIUMGLTF_API AccessorSparse final : public ExtensibleObject { /** * @brief Number of entries stored in the sparse array. diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h index 39b923453..f484a2e6f 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseIndices.h @@ -3,13 +3,14 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { /** * @brief Indices of those attributes that deviate from their initialization value. */ - struct AccessorSparseIndices : public ExtensibleObject { + struct CESIUMGLTF_API AccessorSparseIndices final : public ExtensibleObject { enum class ComponentType { UNSIGNED_BYTE = 5121, diff --git a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h index 07a7427b4..6c496b544 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSparseValues.h @@ -3,13 +3,14 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { /** * @brief Array of size `accessor.sparse.count` times number of components storing the displaced accessor attributes pointed by `accessor.sparse.indices`. */ - struct AccessorSparseValues : public ExtensibleObject { + struct CESIUMGLTF_API AccessorSparseValues final : public ExtensibleObject { /** * @brief The index of the bufferView with sparse values. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target. diff --git a/CesiumGltf/include/CesiumGltf/AccessorSpec.h b/CesiumGltf/include/CesiumGltf/AccessorSpec.h index 658039b67..7eb9c2fe2 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorSpec.h +++ b/CesiumGltf/include/CesiumGltf/AccessorSpec.h @@ -3,6 +3,7 @@ #pragma once #include "CesiumGltf/AccessorSparse.h" +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include #include @@ -12,7 +13,7 @@ namespace CesiumGltf { /** * @brief A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides a typed view into a bufferView or a subset of a bufferView similar to how WebGL's `vertexAttribPointer()` defines an attribute in a buffer. */ - struct AccessorSpec : public NamedObject { + struct CESIUMGLTF_API AccessorSpec : public NamedObject { enum class ComponentType { BYTE = 5120, @@ -106,5 +107,12 @@ namespace CesiumGltf { */ std::optional sparse; + private: + /** + * @brief This class is not mean to be instantiated directly. Use {@link Accessor} instead. + */ + AccessorSpec() = default; + friend struct Accessor; + }; } diff --git a/CesiumGltf/include/CesiumGltf/AccessorView.h b/CesiumGltf/include/CesiumGltf/AccessorView.h index 5049c5563..1efbd6c59 100644 --- a/CesiumGltf/include/CesiumGltf/AccessorView.h +++ b/CesiumGltf/include/CesiumGltf/AccessorView.h @@ -4,7 +4,13 @@ #include namespace CesiumGltf { - + /** + * @brief Indicates the status of an {@link AccessorView}. + * + * The {@link AccessorView} constructor always completes successfully. However, it may not + * always reflect the actual content of the {@link Accessor}, but instead indicate that + * its {@link AccessorView::size} is 0. This enumeration provides the reason. + */ enum class AccessorViewStatus { /** * @brief This accessor is valid and ready to use. @@ -47,14 +53,10 @@ namespace CesiumGltf { * * It provides the actual accessor data like an array of elements. * The type of the accessor elements is determined by the template - * parameter. Instances are usually created by {@link Accessor::createView}, + * parameter. Instances are usually from an {@link Accessor}, * and the {@link operator[]()} can be used to access the elements: * - * ``` - * CesiumGltf::Model model; - * AccessorView positions = model.accessors[0].createViewcreate(model, accessor); } - AccessorView(const Model& model, int32_t accessorIndex) : + + /** + * @brief Creates a new instance from a given model and accessor index. + * + * If the accessor cannot be viewed, the construct will still complete successfully + * without throwing an exception. However, {@link size} will return 0 and + * {@link status} will indicate what went wrong. + * + * @param model The model to access. + * @param accessorIndex The index of the accessor to view in the model's {@link Model::accessors} list. + */ + AccessorView(const Model& model, int32_t accessorIndex) noexcept : AccessorView() { const Accessor* pAccessor = Model::getSafe(&model.accessors, accessorIndex); diff --git a/CesiumGltf/include/CesiumGltf/Animation.h b/CesiumGltf/include/CesiumGltf/Animation.h index 268d34ab3..be2d6e4fd 100644 --- a/CesiumGltf/include/CesiumGltf/Animation.h +++ b/CesiumGltf/include/CesiumGltf/Animation.h @@ -4,6 +4,7 @@ #include "CesiumGltf/AnimationChannel.h" #include "CesiumGltf/AnimationSampler.h" +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include @@ -11,7 +12,7 @@ namespace CesiumGltf { /** * @brief A keyframe animation. */ - struct Animation : public NamedObject { + struct CESIUMGLTF_API Animation final : public NamedObject { /** * @brief An array of channels, each of which targets an animation's sampler at a node's property. Different channels of the same animation can't have equal targets. diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannel.h b/CesiumGltf/include/CesiumGltf/AnimationChannel.h index 0c3484c20..96fc660d4 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationChannel.h +++ b/CesiumGltf/include/CesiumGltf/AnimationChannel.h @@ -4,13 +4,14 @@ #include "CesiumGltf/AnimationChannelTarget.h" #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { /** * @brief Targets an animation's sampler at a node's property. */ - struct AnimationChannel : public ExtensibleObject { + struct CESIUMGLTF_API AnimationChannel final : public ExtensibleObject { /** * @brief The index of a sampler in this animation used to compute the value for the target. diff --git a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h index 916eea6b0..6c95148eb 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h +++ b/CesiumGltf/include/CesiumGltf/AnimationChannelTarget.h @@ -3,13 +3,14 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { /** * @brief The index of the node and TRS property that an animation channel targets. */ - struct AnimationChannelTarget : public ExtensibleObject { + struct CESIUMGLTF_API AnimationChannelTarget final : public ExtensibleObject { enum class Path { translation, diff --git a/CesiumGltf/include/CesiumGltf/AnimationSampler.h b/CesiumGltf/include/CesiumGltf/AnimationSampler.h index 458ef00fb..f8d2a8fa1 100644 --- a/CesiumGltf/include/CesiumGltf/AnimationSampler.h +++ b/CesiumGltf/include/CesiumGltf/AnimationSampler.h @@ -3,13 +3,14 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { /** * @brief Combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target). */ - struct AnimationSampler : public ExtensibleObject { + struct CESIUMGLTF_API AnimationSampler final : public ExtensibleObject { enum class Interpolation { LINEAR, diff --git a/CesiumGltf/include/CesiumGltf/Asset.h b/CesiumGltf/include/CesiumGltf/Asset.h index e107a32ed..69cf43fea 100644 --- a/CesiumGltf/include/CesiumGltf/Asset.h +++ b/CesiumGltf/include/CesiumGltf/Asset.h @@ -3,6 +3,7 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include #include @@ -10,7 +11,7 @@ namespace CesiumGltf { /** * @brief Metadata about the glTF asset. */ - struct Asset : public ExtensibleObject { + struct CESIUMGLTF_API Asset final : public ExtensibleObject { /** * @brief A copyright message suitable for display to credit the content creator. diff --git a/CesiumGltf/include/CesiumGltf/Buffer.h b/CesiumGltf/include/CesiumGltf/Buffer.h index 6d1e90c3d..47a6bf2b9 100644 --- a/CesiumGltf/include/CesiumGltf/Buffer.h +++ b/CesiumGltf/include/CesiumGltf/Buffer.h @@ -2,10 +2,11 @@ #include "CesiumGltf/BufferCesium.h" #include "CesiumGltf/BufferSpec.h" +#include "CesiumGltf/Library.h" namespace CesiumGltf { /** @copydoc BufferSpec */ - struct Buffer : public BufferSpec { + struct CESIUMGLTF_API Buffer final : public BufferSpec { /** * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. */ diff --git a/CesiumGltf/include/CesiumGltf/BufferCesium.h b/CesiumGltf/include/CesiumGltf/BufferCesium.h index dce15adeb..4e4ed068a 100644 --- a/CesiumGltf/include/CesiumGltf/BufferCesium.h +++ b/CesiumGltf/include/CesiumGltf/BufferCesium.h @@ -1,9 +1,13 @@ #pragma once +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { - struct BufferCesium final { + /** + * @brief Holds {@link Buffer} properties that are specific to the glTF loader rather than part of the glTF spec. + */ + struct CESIUMGLTF_API BufferCesium final { /** * @brief The buffer's data. */ diff --git a/CesiumGltf/include/CesiumGltf/BufferSpec.h b/CesiumGltf/include/CesiumGltf/BufferSpec.h index d8a5771c1..b3c355e2f 100644 --- a/CesiumGltf/include/CesiumGltf/BufferSpec.h +++ b/CesiumGltf/include/CesiumGltf/BufferSpec.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include #include @@ -11,7 +12,7 @@ namespace CesiumGltf { /** * @brief A buffer points to binary geometry, animation, or skins. */ - struct BufferSpec : public NamedObject { + struct CESIUMGLTF_API BufferSpec : public NamedObject { /** * @brief The uri of the buffer. @@ -25,5 +26,12 @@ namespace CesiumGltf { */ int64_t byteLength = int64_t(); + private: + /** + * @brief This class is not mean to be instantiated directly. Use {@link Buffer} instead. + */ + BufferSpec() = default; + friend struct Buffer; + }; } diff --git a/CesiumGltf/include/CesiumGltf/BufferView.h b/CesiumGltf/include/CesiumGltf/BufferView.h index bc4d23195..9f6816ab4 100644 --- a/CesiumGltf/include/CesiumGltf/BufferView.h +++ b/CesiumGltf/include/CesiumGltf/BufferView.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include #include @@ -10,7 +11,7 @@ namespace CesiumGltf { /** * @brief A view into a buffer generally representing a subset of the buffer. */ - struct BufferView : public NamedObject { + struct CESIUMGLTF_API BufferView final : public NamedObject { enum class Target { ARRAY_BUFFER = 34962, diff --git a/CesiumGltf/include/CesiumGltf/Camera.h b/CesiumGltf/include/CesiumGltf/Camera.h index ce0d56300..e3aa50881 100644 --- a/CesiumGltf/include/CesiumGltf/Camera.h +++ b/CesiumGltf/include/CesiumGltf/Camera.h @@ -4,6 +4,7 @@ #include "CesiumGltf/CameraOrthographic.h" #include "CesiumGltf/CameraPerspective.h" +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include @@ -11,7 +12,7 @@ namespace CesiumGltf { /** * @brief A camera's projection. A node can reference a camera to apply a transform to place the camera in the scene. */ - struct Camera : public NamedObject { + struct CESIUMGLTF_API Camera final : public NamedObject { enum class Type { perspective, diff --git a/CesiumGltf/include/CesiumGltf/CameraOrthographic.h b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h index 46b66a7be..c354bf7f9 100644 --- a/CesiumGltf/include/CesiumGltf/CameraOrthographic.h +++ b/CesiumGltf/include/CesiumGltf/CameraOrthographic.h @@ -3,12 +3,13 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" namespace CesiumGltf { /** * @brief An orthographic camera containing properties to create an orthographic projection matrix. */ - struct CameraOrthographic : public ExtensibleObject { + struct CESIUMGLTF_API CameraOrthographic final : public ExtensibleObject { /** * @brief The floating-point horizontal magnification of the view. Must not be zero. diff --git a/CesiumGltf/include/CesiumGltf/CameraPerspective.h b/CesiumGltf/include/CesiumGltf/CameraPerspective.h index 78be30ca0..af427d1c2 100644 --- a/CesiumGltf/include/CesiumGltf/CameraPerspective.h +++ b/CesiumGltf/include/CesiumGltf/CameraPerspective.h @@ -3,13 +3,14 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { /** * @brief A perspective camera containing properties to create a perspective projection matrix. */ - struct CameraPerspective : public ExtensibleObject { + struct CESIUMGLTF_API CameraPerspective final : public ExtensibleObject { /** * @brief The floating-point aspect ratio of the field of view. diff --git a/CesiumGltf/include/CesiumGltf/ExtensibleObject.h b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h index 79a58b064..c855c6921 100644 --- a/CesiumGltf/include/CesiumGltf/ExtensibleObject.h +++ b/CesiumGltf/include/CesiumGltf/ExtensibleObject.h @@ -1,6 +1,7 @@ #pragma once #include "CesiumGltf/JsonValue.h" +#include "CesiumGltf/Library.h" #include #include @@ -8,7 +9,7 @@ namespace CesiumGltf { /** * @brief The base class for objects in a glTF that have extensions and extras. */ - struct ExtensibleObject { + struct CESIUMGLTF_API ExtensibleObject { // TODO: extras /** diff --git a/CesiumGltf/include/CesiumGltf/Image.h b/CesiumGltf/include/CesiumGltf/Image.h index 9bfd81c23..d34d4aa3d 100644 --- a/CesiumGltf/include/CesiumGltf/Image.h +++ b/CesiumGltf/include/CesiumGltf/Image.h @@ -2,10 +2,11 @@ #include "CesiumGltf/ImageCesium.h" #include "CesiumGltf/ImageSpec.h" +#include "CesiumGltf/Library.h" namespace CesiumGltf { /** @copydoc ImageSpec */ - struct Image : public ImageSpec { + struct CESIUMGLTF_API Image final : public ImageSpec { /** * @brief Holds properties that are specific to the glTF loader rather than part of the glTF spec. */ diff --git a/CesiumGltf/include/CesiumGltf/ImageCesium.h b/CesiumGltf/include/CesiumGltf/ImageCesium.h index f955dbc33..0e446b039 100644 --- a/CesiumGltf/include/CesiumGltf/ImageCesium.h +++ b/CesiumGltf/include/CesiumGltf/ImageCesium.h @@ -1,10 +1,14 @@ #pragma once +#include "CesiumGltf/Library.h" #include #include namespace CesiumGltf { - struct ImageCesium final { + /** + * @brief Holds {@link Image} properties that are specific to the glTF loader rather than part of the glTF spec. + */ + struct CESIUMGLTF_API ImageCesium final { /** * @brief The width of the image in pixels. */ @@ -36,12 +40,12 @@ namespace CesiumGltf { * * The channels and their meaning are as follows: * - * | Number of Channels | Channel Meaning | - * |--------------------|-------------------------| - * | 1 | grey | - * | 2 | grey, alpha | - * | 3 | red, green, blue | - * | 4 | red, green, blue, alpha | + * | Number of Channels | Channel Order and Meaning | + * |--------------------|---------------------------| + * | 1 | grey | + * | 2 | grey, alpha | + * | 3 | red, green, blue | + * | 4 | red, green, blue, alpha | */ std::vector pixelData; }; diff --git a/CesiumGltf/include/CesiumGltf/ImageSpec.h b/CesiumGltf/include/CesiumGltf/ImageSpec.h index d76f42dd0..02769ee68 100644 --- a/CesiumGltf/include/CesiumGltf/ImageSpec.h +++ b/CesiumGltf/include/CesiumGltf/ImageSpec.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include #include @@ -11,7 +12,7 @@ namespace CesiumGltf { /** * @brief Image data used to create a texture. Image can be referenced by URI or `bufferView` index. `mimeType` is required in the latter case. */ - struct ImageSpec : public NamedObject { + struct CESIUMGLTF_API ImageSpec : public NamedObject { enum class MimeType { image_jpeg, @@ -35,5 +36,12 @@ namespace CesiumGltf { */ int32_t bufferView = -1; + private: + /** + * @brief This class is not mean to be instantiated directly. Use {@link Image} instead. + */ + ImageSpec() = default; + friend struct Image; + }; } diff --git a/CesiumGltf/include/CesiumGltf/JsonValue.h b/CesiumGltf/include/CesiumGltf/JsonValue.h index 97fc48a9e..3fa2c3eb3 100644 --- a/CesiumGltf/include/CesiumGltf/JsonValue.h +++ b/CesiumGltf/include/CesiumGltf/JsonValue.h @@ -1,5 +1,6 @@ #pragma once +#include "CesiumGltf/Library.h" #include #include #include @@ -8,7 +9,7 @@ #include namespace CesiumGltf { - class JsonValue final { + class CESIUMGLTF_API JsonValue final { public: using Null = std::nullptr_t; using Number = double; diff --git a/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h b/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h index eed688e17..6ed3a992d 100644 --- a/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h +++ b/CesiumGltf/include/CesiumGltf/KHR_draco_mesh_compression.h @@ -3,6 +3,7 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include #include @@ -10,7 +11,7 @@ namespace CesiumGltf { /** * @brief undefined */ - struct KHR_draco_mesh_compression : public ExtensibleObject { + struct CESIUMGLTF_API KHR_draco_mesh_compression final : public ExtensibleObject { /** * @brief The index of the bufferView. diff --git a/CesiumGltf/include/CesiumGltf/Library.h b/CesiumGltf/include/CesiumGltf/Library.h new file mode 100644 index 000000000..4c2bcd144 --- /dev/null +++ b/CesiumGltf/include/CesiumGltf/Library.h @@ -0,0 +1,16 @@ +#pragma once + +/** + * @brief Classes for working with [glTF](https://www.khronos.org/gltf/) models. + */ +namespace CesiumGltf {} + +#if defined(_WIN32) && defined(CESIUM_SHARED) + #ifdef CESIUMGLTF_BUILDING + #define CESIUMGLTF_API __declspec(dllexport) + #else + #define CESIUMGLTF_API __declspec(dllimport) + #endif +#else + #define CESIUMGLTF_API +#endif diff --git a/CesiumGltf/include/CesiumGltf/Material.h b/CesiumGltf/include/CesiumGltf/Material.h index 9d63ad621..5596b7388 100644 --- a/CesiumGltf/include/CesiumGltf/Material.h +++ b/CesiumGltf/include/CesiumGltf/Material.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/MaterialNormalTextureInfo.h" #include "CesiumGltf/MaterialOcclusionTextureInfo.h" #include "CesiumGltf/MaterialPBRMetallicRoughness.h" @@ -14,7 +15,7 @@ namespace CesiumGltf { /** * @brief The material appearance of a primitive. */ - struct Material : public NamedObject { + struct CESIUMGLTF_API Material final : public NamedObject { enum class AlphaMode { OPAQUE, diff --git a/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h index 8bf8dec38..8f2fa5d4d 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/MaterialNormalTextureInfo.h @@ -2,13 +2,14 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/TextureInfo.h" namespace CesiumGltf { /** * @brief undefined */ - struct MaterialNormalTextureInfo : public TextureInfo { + struct CESIUMGLTF_API MaterialNormalTextureInfo final : public TextureInfo { /** * @brief The scalar multiplier applied to each normal vector of the normal texture. diff --git a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h index 5875eada6..917c370cd 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/MaterialOcclusionTextureInfo.h @@ -2,13 +2,14 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/TextureInfo.h" namespace CesiumGltf { /** * @brief undefined */ - struct MaterialOcclusionTextureInfo : public TextureInfo { + struct CESIUMGLTF_API MaterialOcclusionTextureInfo final : public TextureInfo { /** * @brief A scalar multiplier controlling the amount of occlusion applied. diff --git a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h index 7b43d3f85..3cc2e13df 100644 --- a/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h +++ b/CesiumGltf/include/CesiumGltf/MaterialPBRMetallicRoughness.h @@ -3,6 +3,7 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include "CesiumGltf/TextureInfo.h" #include #include @@ -11,7 +12,7 @@ namespace CesiumGltf { /** * @brief A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology. */ - struct MaterialPBRMetallicRoughness : public ExtensibleObject { + struct CESIUMGLTF_API MaterialPBRMetallicRoughness final : public ExtensibleObject { /** * @brief The material's base color factor. diff --git a/CesiumGltf/include/CesiumGltf/Mesh.h b/CesiumGltf/include/CesiumGltf/Mesh.h index 607831909..e679b6706 100644 --- a/CesiumGltf/include/CesiumGltf/Mesh.h +++ b/CesiumGltf/include/CesiumGltf/Mesh.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/MeshPrimitive.h" #include "CesiumGltf/NamedObject.h" #include @@ -10,7 +11,7 @@ namespace CesiumGltf { /** * @brief A set of primitives to be rendered. A node can contain one mesh. A node's transform places the mesh in the scene. */ - struct Mesh : public NamedObject { + struct CESIUMGLTF_API Mesh final : public NamedObject { /** * @brief An array of primitives, each defining geometry to be rendered with a material. diff --git a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h index 13ff0d94d..2172fab35 100644 --- a/CesiumGltf/include/CesiumGltf/MeshPrimitive.h +++ b/CesiumGltf/include/CesiumGltf/MeshPrimitive.h @@ -3,6 +3,7 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include #include #include @@ -11,7 +12,7 @@ namespace CesiumGltf { /** * @brief Geometry to be rendered with the given material. */ - struct MeshPrimitive : public ExtensibleObject { + struct CESIUMGLTF_API MeshPrimitive final : public ExtensibleObject { enum class Mode { POINTS = 0, diff --git a/CesiumGltf/include/CesiumGltf/Model.h b/CesiumGltf/include/CesiumGltf/Model.h index 46644b547..cdf2582d5 100644 --- a/CesiumGltf/include/CesiumGltf/Model.h +++ b/CesiumGltf/include/CesiumGltf/Model.h @@ -1,10 +1,24 @@ #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/ModelSpec.h" namespace CesiumGltf { /** @copydoc ModelSpec */ - struct Model : public ModelSpec { + struct CESIUMGLTF_API Model : public ModelSpec { + /** + * @brief Merges another model into this one. + * + * After this method returns, this `Model` contains all of the + * elements that were originally in it _plus_ all of the elements + * that were in `rhs`. Element indices are updated accordingly. + * However, element indices in {@ExtensibleObject::extras}, if any, + * are _not_ updated. + * + * @param rhs The model to merge into this one. + */ + void merge(Model&& rhs); + /** * @brief Safely gets the element with a given index, returning a default instance if the index is outside the range. * diff --git a/CesiumGltf/include/CesiumGltf/ModelSpec.h b/CesiumGltf/include/CesiumGltf/ModelSpec.h index c169cf018..3e1c272cf 100644 --- a/CesiumGltf/include/CesiumGltf/ModelSpec.h +++ b/CesiumGltf/include/CesiumGltf/ModelSpec.h @@ -10,6 +10,7 @@ #include "CesiumGltf/Camera.h" #include "CesiumGltf/ExtensibleObject.h" #include "CesiumGltf/Image.h" +#include "CesiumGltf/Library.h" #include "CesiumGltf/Material.h" #include "CesiumGltf/Mesh.h" #include "CesiumGltf/Node.h" @@ -25,7 +26,7 @@ namespace CesiumGltf { /** * @brief The root object for a glTF asset. */ - struct ModelSpec : public ExtensibleObject { + struct CESIUMGLTF_API ModelSpec : public ExtensibleObject { /** * @brief Names of glTF extensions used somewhere in this asset. @@ -130,5 +131,12 @@ namespace CesiumGltf { */ std::vector textures; + private: + /** + * @brief This class is not mean to be instantiated directly. Use {@link Model} instead. + */ + ModelSpec() = default; + friend struct Model; + }; } diff --git a/CesiumGltf/include/CesiumGltf/NamedObject.h b/CesiumGltf/include/CesiumGltf/NamedObject.h index 1ddf52308..cbfbeff69 100644 --- a/CesiumGltf/include/CesiumGltf/NamedObject.h +++ b/CesiumGltf/include/CesiumGltf/NamedObject.h @@ -1,6 +1,7 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { @@ -9,7 +10,7 @@ namespace CesiumGltf { * * A named object is also an {@link ExtensibleObject}. */ - struct NamedObject : public ExtensibleObject { + struct CESIUMGLTF_API NamedObject : public ExtensibleObject { /** * @brief The user-defined name of this object. * diff --git a/CesiumGltf/include/CesiumGltf/Node.h b/CesiumGltf/include/CesiumGltf/Node.h index ff9540cbb..230f92111 100644 --- a/CesiumGltf/include/CesiumGltf/Node.h +++ b/CesiumGltf/include/CesiumGltf/Node.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include #include @@ -10,7 +11,7 @@ namespace CesiumGltf { /** * @brief A node in the node hierarchy. When the node contains `skin`, all `mesh.primitives` must contain `JOINTS_0` and `WEIGHTS_0` attributes. A node can have either a `matrix` or any combination of `translation`/`rotation`/`scale` (TRS) properties. TRS properties are converted to matrices and postmultiplied in the `T * R * S` order to compose the transformation matrix; first the scale is applied to the vertices, then the rotation, and then the translation. If none are provided, the transform is the identity. When a node is targeted for animation (referenced by an animation.channel.target), only TRS properties may be present; `matrix` will not be present. */ - struct Node : public NamedObject { + struct CESIUMGLTF_API Node final : public NamedObject { /** * @brief The index of the camera referenced by this node. diff --git a/CesiumGltf/include/CesiumGltf/Sampler.h b/CesiumGltf/include/CesiumGltf/Sampler.h index 1fd97d8be..956e13a7b 100644 --- a/CesiumGltf/include/CesiumGltf/Sampler.h +++ b/CesiumGltf/include/CesiumGltf/Sampler.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include @@ -9,7 +10,7 @@ namespace CesiumGltf { /** * @brief Texture sampler properties for filtering and wrapping modes. */ - struct Sampler : public NamedObject { + struct CESIUMGLTF_API Sampler final : public NamedObject { enum class MagFilter { NEAREST = 9728, diff --git a/CesiumGltf/include/CesiumGltf/Scene.h b/CesiumGltf/include/CesiumGltf/Scene.h index 53771fb45..7ffaa539f 100644 --- a/CesiumGltf/include/CesiumGltf/Scene.h +++ b/CesiumGltf/include/CesiumGltf/Scene.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include #include @@ -10,7 +11,7 @@ namespace CesiumGltf { /** * @brief The root nodes of a scene. */ - struct Scene : public NamedObject { + struct CESIUMGLTF_API Scene final : public NamedObject { /** * @brief The indices of each root node. diff --git a/CesiumGltf/include/CesiumGltf/Skin.h b/CesiumGltf/include/CesiumGltf/Skin.h index f69c1b460..7ed2c2740 100644 --- a/CesiumGltf/include/CesiumGltf/Skin.h +++ b/CesiumGltf/include/CesiumGltf/Skin.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include #include @@ -10,7 +11,7 @@ namespace CesiumGltf { /** * @brief Joints and matrices defining a skin. */ - struct Skin : public NamedObject { + struct CESIUMGLTF_API Skin final : public NamedObject { /** * @brief The index of the accessor containing the floating-point 4x4 inverse-bind matrices. The default is that each matrix is a 4x4 identity matrix, which implies that inverse-bind matrices were pre-applied. diff --git a/CesiumGltf/include/CesiumGltf/Texture.h b/CesiumGltf/include/CesiumGltf/Texture.h index 9767d3f37..7f1f07177 100644 --- a/CesiumGltf/include/CesiumGltf/Texture.h +++ b/CesiumGltf/include/CesiumGltf/Texture.h @@ -2,6 +2,7 @@ // DO NOT EDIT THIS FILE! #pragma once +#include "CesiumGltf/Library.h" #include "CesiumGltf/NamedObject.h" #include @@ -9,7 +10,7 @@ namespace CesiumGltf { /** * @brief A texture and its sampler. */ - struct Texture : public NamedObject { + struct CESIUMGLTF_API Texture final : public NamedObject { /** * @brief The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used. diff --git a/CesiumGltf/include/CesiumGltf/TextureInfo.h b/CesiumGltf/include/CesiumGltf/TextureInfo.h index deda7ae09..eecc20850 100644 --- a/CesiumGltf/include/CesiumGltf/TextureInfo.h +++ b/CesiumGltf/include/CesiumGltf/TextureInfo.h @@ -3,13 +3,14 @@ #pragma once #include "CesiumGltf/ExtensibleObject.h" +#include "CesiumGltf/Library.h" #include namespace CesiumGltf { /** * @brief Reference to a texture. */ - struct TextureInfo : public ExtensibleObject { + struct CESIUMGLTF_API TextureInfo : public ExtensibleObject { /** * @brief The index of the texture. diff --git a/CesiumGltf/src/Model.cpp b/CesiumGltf/src/Model.cpp index 5865dd096..36aef4da5 100644 --- a/CesiumGltf/src/Model.cpp +++ b/CesiumGltf/src/Model.cpp @@ -1 +1,198 @@ #include "CesiumGltf/Model.h" +#include "CesiumGltf/KHR_draco_mesh_compression.h" +#include + +using namespace CesiumGltf; + +namespace { + template + size_t copyElements(std::vector& to, std::vector& from) { + size_t out = to.size(); + to.resize(out + from.size()); + for (size_t i = 0; i < from.size(); ++i) { + to[out + i] = std::move(from[i]); + } + + return out; + } + + void updateIndex(int32_t& index, size_t offset) { + if (index == -1) { + return; + } + index += int32_t(offset); + } +} + +void Model::merge(Model&& rhs) { + // TODO: we could generate this pretty easily if the glTF JSON schema made + // it clear which index properties refer to which types of objects. + + // Copy all the source data into this instance. + copyElements(this->extensionsUsed, rhs.extensionsUsed); + std::sort(this->extensionsUsed.begin(), this->extensionsUsed.end()); + this->extensionsUsed.erase(std::unique(this->extensionsUsed.begin(), this->extensionsUsed.end()), this->extensionsUsed.end()); + + copyElements(this->extensionsRequired, rhs.extensionsRequired); + std::sort(this->extensionsRequired.begin(), this->extensionsRequired.end()); + this->extensionsRequired.erase(std::unique(this->extensionsRequired.begin(), this->extensionsRequired.end()), this->extensionsRequired.end()); + + size_t firstAccessor = copyElements(this->accessors, rhs.accessors); + size_t firstAnimation = copyElements(this->animations, rhs.animations); + size_t firstBuffer = copyElements(this->buffers, rhs.buffers); + size_t firstBufferView = copyElements(this->bufferViews, rhs.bufferViews); + size_t firstCamera = copyElements(this->cameras, rhs.cameras); + size_t firstImage = copyElements(this->images, rhs.images); + size_t firstMaterial = copyElements(this->materials, rhs.materials); + size_t firstMesh = copyElements(this->meshes, rhs.meshes); + size_t firstNode = copyElements(this->nodes, rhs.nodes); + size_t firstSampler = copyElements(this->samplers, rhs.samplers); + size_t firstScene = copyElements(this->scenes, rhs.scenes); + size_t firstSkin = copyElements(this->skins, rhs.skins); + size_t firstTexture = copyElements(this->textures, rhs.textures); + + // Update the copied indices + for (size_t i = firstAccessor; i < this->accessors.size(); ++i) { + Accessor& accessor = this->accessors[i]; + updateIndex(accessor.bufferView, firstBufferView); + + if (accessor.sparse) { + updateIndex(accessor.sparse.value().indices.bufferView, firstBufferView); + updateIndex(accessor.sparse.value().values.bufferView, firstBufferView); + } + } + + for (size_t i = firstAnimation; i < this->animations.size(); ++i) { + Animation& animation = this->animations[i]; + + for (AnimationChannel& channel : animation.channels) { + updateIndex(channel.sampler, firstSampler); + updateIndex(channel.target.node, firstNode); + } + + for (AnimationSampler& sampler : animation.samplers) { + updateIndex(sampler.input, firstAccessor); + updateIndex(sampler.output, firstAccessor); + } + } + + for (size_t i = firstBufferView; i < this->bufferViews.size(); ++i) { + BufferView& bufferView = this->bufferViews[i]; + updateIndex(bufferView.buffer, firstBuffer); + } + + for (size_t i = firstImage; i < this->images.size(); ++i) { + Image& image = this->images[i]; + updateIndex(image.bufferView, firstBufferView); + } + + for (size_t i = firstMesh; i < this->meshes.size(); ++i) { + Mesh& mesh = this->meshes[i]; + + for (MeshPrimitive& primitive : mesh.primitives) { + updateIndex(primitive.indices, firstAccessor); + updateIndex(primitive.material, firstMaterial); + + for (auto& attribute : primitive.attributes) { + updateIndex(attribute.second, firstAccessor); + } + + for (auto& target : primitive.targets) { + for (auto& displacement : target) { + updateIndex(displacement.second, firstAccessor); + } + } + + KHR_draco_mesh_compression* pDraco = primitive.getExtension(); + if (pDraco) { + updateIndex(pDraco->bufferView, firstBufferView); + } + } + } + + for (size_t i = firstNode; i < this->nodes.size(); ++i) { + Node& node = this->nodes[i]; + + updateIndex(node.camera, firstCamera); + updateIndex(node.skin, firstSkin); + updateIndex(node.mesh, firstMesh); + + for (auto& nodeIndex : node.children) { + updateIndex(nodeIndex, firstNode); + } + } + + for (size_t i = firstScene; i < this->scenes.size(); ++i) { + Scene& currentScene = this->scenes[i]; + for (int32_t& node : currentScene.nodes) { + updateIndex(node, firstNode); + } + } + + for (size_t i = firstSkin; i < this->skins.size(); ++i) { + Skin& skin = this->skins[i]; + + updateIndex(skin.inverseBindMatrices, firstAccessor); + updateIndex(skin.skeleton, firstNode); + + for (int32_t& nodeIndex : skin.joints) { + updateIndex(nodeIndex, firstNode); + } + } + + for (size_t i = firstTexture; i < this->textures.size(); ++i) { + Texture& texture = this->textures[i]; + + updateIndex(texture.sampler, firstSampler); + updateIndex(texture.source, firstImage); + } + + for (size_t i = firstMaterial; i < this->materials.size(); ++i) { + Material& material = this->materials[i]; + + if (material.normalTexture) { + updateIndex(material.normalTexture.value().index, firstTexture); + } + if (material.occlusionTexture) { + updateIndex(material.occlusionTexture.value().index, firstTexture); + } + if (material.pbrMetallicRoughness) { + MaterialPBRMetallicRoughness& pbr = material.pbrMetallicRoughness.value(); + if (pbr.baseColorTexture) { + updateIndex(pbr.baseColorTexture.value().index, firstTexture); + } + if (pbr.metallicRoughnessTexture) { + updateIndex(pbr.metallicRoughnessTexture.value().index, firstTexture); + } + } + if (material.emissiveTexture) { + updateIndex(material.emissiveTexture.value().index, firstTexture); + } + } + + Scene* pThisDefaultScene = Model::getSafe(&this->scenes, this->scene); + Scene* pRhsDefaultScene = Model::getSafe(&this->scenes, int32_t(rhs.scene + firstScene)); + + if (!pThisDefaultScene) { + this->scene = rhs.scene; + updateIndex(this->scene, firstScene); + } else if (pRhsDefaultScene) { + // Create a new default scene that has all the root nodes in + // the default scene of either model. + Scene& newScene = this->scenes.emplace_back(); + + // Refresh the scene pointers potentially invalidated by the above. + pThisDefaultScene = Model::getSafe(&this->scenes, this->scene); + pRhsDefaultScene = Model::getSafe(&this->scenes, int32_t(rhs.scene + firstScene)); + + newScene.nodes = pThisDefaultScene->nodes; + size_t originalNodeCount = newScene.nodes.size(); + newScene.nodes.resize(originalNodeCount + pRhsDefaultScene->nodes.size()); + std::copy(pRhsDefaultScene->nodes.begin(), pRhsDefaultScene->nodes.end(), newScene.nodes.begin() + originalNodeCount); + + // No need to update indices because they've already been updated when + // we copied them from rhs to this. + + this->scene = int32_t(this->scenes.size() - 1); + } +} diff --git a/CesiumGltf/test/TestAccessorView.cpp b/CesiumGltf/test/TestAccessorView.cpp new file mode 100644 index 000000000..b84a24cd3 --- /dev/null +++ b/CesiumGltf/test/TestAccessorView.cpp @@ -0,0 +1,39 @@ +#include "catch2/catch.hpp" +#include "CesiumGltf/Model.h" +#include "CesiumGltf/AccessorView.h" +#include + +TEST_CASE("AccessorView construct and read example") { + auto anyOldFunctionToGetAModel = []() { + CesiumGltf::Model model; + + CesiumGltf::Accessor& accessor = model.accessors.emplace_back(); + accessor.bufferView = 0; + accessor.componentType = CesiumGltf::Accessor::ComponentType::FLOAT; + accessor.type = CesiumGltf::Accessor::Type::VEC3; + accessor.count = 1; + + CesiumGltf::BufferView& bufferView = model.bufferViews.emplace_back(); + bufferView.buffer = 0; + bufferView.byteLength = accessor.count * sizeof(float) * 3; + + CesiumGltf::Buffer& buffer = model.buffers.emplace_back(); + buffer.byteLength = bufferView.byteLength; + buffer.cesium.data.resize(buffer.byteLength); + + float* p = reinterpret_cast(buffer.cesium.data.data()); + p[0] = 1.0f; + p[1] = 2.0f; + p[2] = 3.0f; + + return model; + }; + + //! [createFromAccessorAndRead] + CesiumGltf::Model model = anyOldFunctionToGetAModel(); + CesiumGltf::AccessorView positions(model, 0); + glm::vec3 firstPosition = positions[0]; + //! [createFromAccessorAndRead] + + CHECK(firstPosition == glm::vec3(1.0f, 2.0f, 3.0f)); +} diff --git a/CesiumGltfReader/include/CesiumGltf/Reader.h b/CesiumGltfReader/include/CesiumGltf/Reader.h index 2d41e5e83..c97ec2fe2 100644 --- a/CesiumGltfReader/include/CesiumGltf/Reader.h +++ b/CesiumGltfReader/include/CesiumGltf/Reader.h @@ -1,5 +1,6 @@ #pragma once +#include "CesiumGltf/ReaderLibrary.h" #include "CesiumGltf/Model.h" #include #include @@ -7,25 +8,25 @@ #include namespace CesiumGltf { - struct ModelReaderResult { + struct CESIUMGLTFREADER_API ModelReaderResult { std::optional model; std::vector errors; std::vector warnings; }; - struct ReadModelOptions { + struct CESIUMGLTFREADER_API ReadModelOptions { bool decodeDataUris = true; bool decodeEmbeddedImages = true; bool decodeDraco = true; }; - ModelReaderResult readModel(const gsl::span& data, const ReadModelOptions& options = ReadModelOptions()); + CESIUMGLTFREADER_API ModelReaderResult readModel(const gsl::span& data, const ReadModelOptions& options = ReadModelOptions()); - struct ImageReaderResult { + struct CESIUMGLTFREADER_API ImageReaderResult { std::optional image; std::vector errors; std::vector warnings; }; - ImageReaderResult readImage(const gsl::span& data); + CESIUMGLTFREADER_API ImageReaderResult readImage(const gsl::span& data); } diff --git a/CesiumGltfReader/include/CesiumGltf/ReaderLibrary.h b/CesiumGltfReader/include/CesiumGltf/ReaderLibrary.h new file mode 100644 index 000000000..4bd5ae889 --- /dev/null +++ b/CesiumGltfReader/include/CesiumGltf/ReaderLibrary.h @@ -0,0 +1,11 @@ +#pragma once + +#if defined(_WIN32) && defined(CESIUM_SHARED) + #ifdef CESIUMGLTFREADER_BUILDING + #define CESIUMGLTFREADER_API __declspec(dllexport) + #else + #define CESIUMGLTFREADER_API __declspec(dllimport) + #endif +#else + #define CESIUMGLTFREADER_API +#endif diff --git a/CesiumGltfReader/src/JsonObjectJsonHandler.cpp b/CesiumGltfReader/src/JsonObjectJsonHandler.cpp index 43f5f5949..860ce5466 100644 --- a/CesiumGltfReader/src/JsonObjectJsonHandler.cpp +++ b/CesiumGltfReader/src/JsonObjectJsonHandler.cpp @@ -83,12 +83,8 @@ IJsonHandler* JsonObjectJsonHandler::Key(const char* str, size_t /* length */, b auto it = pObject->emplace(str, JsonValue()).first; this->_stack.push_back(&it->second); - - return property( - it->first.c_str(), - *this, - it->second - ); + this->_currentKey = str; + return this; } IJsonHandler* JsonObjectJsonHandler::EndObject(size_t /* memberCount */) { diff --git a/CesiumGltfReader/src/JsonObjectJsonHandler.h b/CesiumGltfReader/src/JsonObjectJsonHandler.h index 9007136c2..38719824e 100644 --- a/CesiumGltfReader/src/JsonObjectJsonHandler.h +++ b/CesiumGltfReader/src/JsonObjectJsonHandler.h @@ -25,13 +25,6 @@ namespace CesiumGltf { virtual IJsonHandler* EndArray(size_t elementCount) override; private: - template - IJsonHandler* property(const char* currentKey, TAccessor& accessor, TProperty& value) { - this->_currentKey = currentKey; - accessor.reset(this, &value); - return &accessor; - } - IJsonHandler* doneElement(); std::vector _stack; From f11089f5c957a91caf8a75c0107edf732694b068 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 25 Jan 2021 14:43:46 +1100 Subject: [PATCH 53/61] Fix warnings. --- CesiumGltf/src/Model.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CesiumGltf/src/Model.cpp b/CesiumGltf/src/Model.cpp index 36aef4da5..98080230d 100644 --- a/CesiumGltf/src/Model.cpp +++ b/CesiumGltf/src/Model.cpp @@ -171,7 +171,7 @@ void Model::merge(Model&& rhs) { } Scene* pThisDefaultScene = Model::getSafe(&this->scenes, this->scene); - Scene* pRhsDefaultScene = Model::getSafe(&this->scenes, int32_t(rhs.scene + firstScene)); + Scene* pRhsDefaultScene = Model::getSafe(&this->scenes, rhs.scene + int32_t(firstScene)); if (!pThisDefaultScene) { this->scene = rhs.scene; @@ -183,12 +183,12 @@ void Model::merge(Model&& rhs) { // Refresh the scene pointers potentially invalidated by the above. pThisDefaultScene = Model::getSafe(&this->scenes, this->scene); - pRhsDefaultScene = Model::getSafe(&this->scenes, int32_t(rhs.scene + firstScene)); + pRhsDefaultScene = Model::getSafe(&this->scenes, rhs.scene + int32_t(firstScene)); newScene.nodes = pThisDefaultScene->nodes; size_t originalNodeCount = newScene.nodes.size(); newScene.nodes.resize(originalNodeCount + pRhsDefaultScene->nodes.size()); - std::copy(pRhsDefaultScene->nodes.begin(), pRhsDefaultScene->nodes.end(), newScene.nodes.begin() + originalNodeCount); + std::copy(pRhsDefaultScene->nodes.begin(), pRhsDefaultScene->nodes.end(), newScene.nodes.begin() + int64_t(originalNodeCount)); // No need to update indices because they've already been updated when // we copied them from rhs to this. From dccfcf0a23cc8915e4cee4fbe463b393131e5a62 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 25 Jan 2021 14:53:28 +1100 Subject: [PATCH 54/61] More picky clang signedness warnings. --- CesiumGltf/test/TestAccessorView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CesiumGltf/test/TestAccessorView.cpp b/CesiumGltf/test/TestAccessorView.cpp index b84a24cd3..454cb567d 100644 --- a/CesiumGltf/test/TestAccessorView.cpp +++ b/CesiumGltf/test/TestAccessorView.cpp @@ -15,11 +15,11 @@ TEST_CASE("AccessorView construct and read example") { CesiumGltf::BufferView& bufferView = model.bufferViews.emplace_back(); bufferView.buffer = 0; - bufferView.byteLength = accessor.count * sizeof(float) * 3; + bufferView.byteLength = accessor.count * int64_t(sizeof(float)) * 3; CesiumGltf::Buffer& buffer = model.buffers.emplace_back(); buffer.byteLength = bufferView.byteLength; - buffer.cesium.data.resize(buffer.byteLength); + buffer.cesium.data.resize(size_t(buffer.byteLength)); float* p = reinterpret_cast(buffer.cesium.data.data()); p[0] = 1.0f; From 7ef8d428d3a6c4432cb1fd404bf5856072c5d608 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 25 Jan 2021 15:24:11 +1100 Subject: [PATCH 55/61] WIP decoding of data URIs. --- CesiumGltfReader/include/CesiumGltf/Reader.h | 58 ++++++++++++++++++++ CesiumGltfReader/src/Reader.cpp | 7 ++- CesiumGltfReader/src/decodeDataUris.cpp | 9 +++ CesiumGltfReader/src/decodeDataUris.h | 7 +++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 CesiumGltfReader/src/decodeDataUris.cpp create mode 100644 CesiumGltfReader/src/decodeDataUris.h diff --git a/CesiumGltfReader/include/CesiumGltf/Reader.h b/CesiumGltfReader/include/CesiumGltf/Reader.h index c97ec2fe2..c2b73cd34 100644 --- a/CesiumGltfReader/include/CesiumGltf/Reader.h +++ b/CesiumGltfReader/include/CesiumGltf/Reader.h @@ -8,25 +8,83 @@ #include namespace CesiumGltf { + /** + * @brief The result of reading a glTF model with {@link readModel}. + */ struct CESIUMGLTFREADER_API ModelReaderResult { + /** + * @brief The read model, or std::nullopt if the model could not be read. + */ std::optional model; + + /** + * @brief Errors, if any, that occurred during the load process. + */ std::vector errors; + + /** + * @brief Warnings, if any, that occurred during the load process. + */ std::vector warnings; }; + /** + * @brief Options for how to read a glTF. + */ struct CESIUMGLTFREADER_API ReadModelOptions { + /** + * @brief Whether data URIs should be automatically decoded as part of the load process. + */ bool decodeDataUris = true; + + /** + * @brief Whether data URIs should be cleared after they are successfully decoded. + * + * This reduces the memory usage of the model. + */ + bool clearDecodedDataUris = true; + + /** + * @brief Whether embedded images in {@link Model:buffers} should be automatically decoded as part of the load process. + * + * The {@link ImageSpec::mimeType} property is ignored, and instead the [stb_image](https://github.com/nothings/stb) library + * is used to decode images in `JPG`, `PNG`, `TGA`, `BMP`, `PSD`, `GIF`, `HDR`, or `PIC` format. + */ bool decodeEmbeddedImages = true; + + /** + * @brief Whether geometry compressed using the `KHR_draco_mesh_compression` extension should be automatically decoded + * as part of the load process. + */ bool decodeDraco = true; }; + /** + * @brief Reads a glTF or binary glTF (GLB) from a buffer. + * + * @param data The buffer from which to read the glTF. + * @param options Options for how to read the glTF. + * @return The result of reading the glTF. + */ CESIUMGLTFREADER_API ModelReaderResult readModel(const gsl::span& data, const ReadModelOptions& options = ReadModelOptions()); + /** + * @brief The result of reading an image with {@link readImage}. + */ struct CESIUMGLTFREADER_API ImageReaderResult { std::optional image; std::vector errors; std::vector warnings; }; + /** + * @brief Reads an image from a buffer. + * + * The [stb_image](https://github.com/nothings/stb) library is used to decode images in `JPG`, `PNG`, `TGA`, + * `BMP`, `PSD`, `GIF`, `HDR`, or `PIC` format. + * + * @param data The buffer from which to read the image. + * @return The result of reading the image. + */ CESIUMGLTFREADER_API ImageReaderResult readImage(const gsl::span& data); } diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index 6c1a09327..bccfdc8be 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -1,7 +1,8 @@ #include "CesiumGltf/Reader.h" +#include "decodeDataUris.h" +#include "decodeDraco.h" #include "JsonHandler.h" #include "ModelJsonHandler.h" -#include "decodeDraco.h" #include #include @@ -274,6 +275,10 @@ namespace { void postprocess(ModelReaderResult& readModel, const ReadModelOptions& options) { Model& model = readModel.model.value(); + if (options.decodeDataUris) { + decodeDataUris(readModel); + } + if (options.decodeEmbeddedImages) { for (Image& image : model.images) { const BufferView& bufferView = Model::getSafe(model.bufferViews, image.bufferView); diff --git a/CesiumGltfReader/src/decodeDataUris.cpp b/CesiumGltfReader/src/decodeDataUris.cpp new file mode 100644 index 000000000..ba8c75bd1 --- /dev/null +++ b/CesiumGltfReader/src/decodeDataUris.cpp @@ -0,0 +1,9 @@ +#include "CesiumGltf/Model.h" +#include "decodeDataUris.h" + +namespace CesiumGltf { + +void CesiumGltf::decodeDataUris(ModelReaderResult& /* readModel */) { +} + +} diff --git a/CesiumGltfReader/src/decodeDataUris.h b/CesiumGltfReader/src/decodeDataUris.h new file mode 100644 index 000000000..3adbe527d --- /dev/null +++ b/CesiumGltfReader/src/decodeDataUris.h @@ -0,0 +1,7 @@ +#pragma once + +namespace CesiumGltf { + struct ModelReaderResult; + + void decodeDataUris(ModelReaderResult& readModel); +} From eee83c9e7775b9f755b93e91e2d6af3ab55e0708 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 25 Jan 2021 15:37:04 +1100 Subject: [PATCH 56/61] Remove extraneous namespace qualification. --- CesiumGltfReader/src/decodeDataUris.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CesiumGltfReader/src/decodeDataUris.cpp b/CesiumGltfReader/src/decodeDataUris.cpp index ba8c75bd1..56eaf9c8e 100644 --- a/CesiumGltfReader/src/decodeDataUris.cpp +++ b/CesiumGltfReader/src/decodeDataUris.cpp @@ -3,7 +3,7 @@ namespace CesiumGltf { -void CesiumGltf::decodeDataUris(ModelReaderResult& /* readModel */) { +void decodeDataUris(ModelReaderResult& /* readModel */) { } } From 243f48680b4045300e74e5cd1b3c5b8ff53b4b65 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 27 Jan 2021 23:52:43 +1100 Subject: [PATCH 57/61] Add base64 decoding. Mostly untested at the moment. --- CesiumGltfReader/CMakeLists.txt | 2 +- CesiumGltfReader/include/CesiumGltf/Reader.h | 8 +- CesiumGltfReader/src/Reader.cpp | 6 +- CesiumGltfReader/src/decodeDataUris.cpp | 9 - CesiumGltfReader/src/decodeDataUris.h | 7 - CesiumGltfReader/src/decodeDataUrls.cpp | 117 +++++ CesiumGltfReader/src/decodeDataUrls.h | 7 + extern/CMakeLists.txt | 2 + extern/modp_b64/CMakeLists.txt | 7 + extern/modp_b64/LICENSE | 33 ++ extern/modp_b64/README.cesium | 6 + extern/modp_b64/README.chromium | 17 + extern/modp_b64/modp_b64.cc | 253 ++++++++++ extern/modp_b64/modp_b64.h | 171 +++++++ extern/modp_b64/modp_b64_data.h | 481 +++++++++++++++++++ 15 files changed, 1102 insertions(+), 24 deletions(-) delete mode 100644 CesiumGltfReader/src/decodeDataUris.cpp delete mode 100644 CesiumGltfReader/src/decodeDataUris.h create mode 100644 CesiumGltfReader/src/decodeDataUrls.cpp create mode 100644 CesiumGltfReader/src/decodeDataUrls.h create mode 100644 extern/modp_b64/CMakeLists.txt create mode 100644 extern/modp_b64/LICENSE create mode 100644 extern/modp_b64/README.cesium create mode 100644 extern/modp_b64/README.chromium create mode 100644 extern/modp_b64/modp_b64.cc create mode 100644 extern/modp_b64/modp_b64.h create mode 100644 extern/modp_b64/modp_b64_data.h diff --git a/CesiumGltfReader/CMakeLists.txt b/CesiumGltfReader/CMakeLists.txt index fc4985c49..7321df6b1 100644 --- a/CesiumGltfReader/CMakeLists.txt +++ b/CesiumGltfReader/CMakeLists.txt @@ -29,4 +29,4 @@ target_include_directories( generated ) -target_link_libraries(CesiumGltfReader PUBLIC CesiumGltf GSL draco) +target_link_libraries(CesiumGltfReader PUBLIC CesiumGltf GSL PRIVATE draco modp_b64) diff --git a/CesiumGltfReader/include/CesiumGltf/Reader.h b/CesiumGltfReader/include/CesiumGltf/Reader.h index c2b73cd34..3a73df50c 100644 --- a/CesiumGltfReader/include/CesiumGltf/Reader.h +++ b/CesiumGltfReader/include/CesiumGltf/Reader.h @@ -33,16 +33,16 @@ namespace CesiumGltf { */ struct CESIUMGLTFREADER_API ReadModelOptions { /** - * @brief Whether data URIs should be automatically decoded as part of the load process. + * @brief Whether data URLs in buffers and images should be automatically decoded as part of the load process. */ - bool decodeDataUris = true; + bool decodeDataUrls = true; /** - * @brief Whether data URIs should be cleared after they are successfully decoded. + * @brief Whether data URLs should be cleared after they are successfully decoded. * * This reduces the memory usage of the model. */ - bool clearDecodedDataUris = true; + bool clearDecodedDataUrls = true; /** * @brief Whether embedded images in {@link Model:buffers} should be automatically decoded as part of the load process. diff --git a/CesiumGltfReader/src/Reader.cpp b/CesiumGltfReader/src/Reader.cpp index bccfdc8be..1e2c4e017 100644 --- a/CesiumGltfReader/src/Reader.cpp +++ b/CesiumGltfReader/src/Reader.cpp @@ -1,5 +1,5 @@ #include "CesiumGltf/Reader.h" -#include "decodeDataUris.h" +#include "decodeDataUrls.h" #include "decodeDraco.h" #include "JsonHandler.h" #include "ModelJsonHandler.h" @@ -275,8 +275,8 @@ namespace { void postprocess(ModelReaderResult& readModel, const ReadModelOptions& options) { Model& model = readModel.model.value(); - if (options.decodeDataUris) { - decodeDataUris(readModel); + if (options.decodeDataUrls) { + decodeDataUrls(readModel, options.clearDecodedDataUrls); } if (options.decodeEmbeddedImages) { diff --git a/CesiumGltfReader/src/decodeDataUris.cpp b/CesiumGltfReader/src/decodeDataUris.cpp deleted file mode 100644 index 56eaf9c8e..000000000 --- a/CesiumGltfReader/src/decodeDataUris.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "CesiumGltf/Model.h" -#include "decodeDataUris.h" - -namespace CesiumGltf { - -void decodeDataUris(ModelReaderResult& /* readModel */) { -} - -} diff --git a/CesiumGltfReader/src/decodeDataUris.h b/CesiumGltfReader/src/decodeDataUris.h deleted file mode 100644 index 3adbe527d..000000000 --- a/CesiumGltfReader/src/decodeDataUris.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace CesiumGltf { - struct ModelReaderResult; - - void decodeDataUris(ModelReaderResult& readModel); -} diff --git a/CesiumGltfReader/src/decodeDataUrls.cpp b/CesiumGltfReader/src/decodeDataUrls.cpp new file mode 100644 index 000000000..9ae82caa8 --- /dev/null +++ b/CesiumGltfReader/src/decodeDataUrls.cpp @@ -0,0 +1,117 @@ +#include "CesiumGltf/Model.h" +#include "CesiumGltf/Reader.h" +#include "decodeDataUrls.h" +#include "modp_b64.h" + +namespace { + + std::vector decodeBase64(gsl::span data) { + std::vector result(modp_b64_decode_len(data.size())); + + size_t resultLength = modp_b64_decode(reinterpret_cast(result.data()), reinterpret_cast(data.data()), data.size()); + if (resultLength == size_t(-1)) { + result.clear(); + result.shrink_to_fit(); + } + + return result; + } + + struct DecodeResult { + std::string mimeType; + std::vector data; + }; + + std::optional tryDecode(const std::string& uri) { + constexpr std::string_view dataPrefix = "data:"; + constexpr size_t dataPrefixLength = dataPrefix.size(); + + constexpr std::string_view base64Indicator = ";base64"; + constexpr size_t base64IndicatorLength = base64Indicator.size(); + + if (uri.substr(0, dataPrefixLength) != dataPrefix) { + return std::nullopt; + } + + size_t dataDelimeter = uri.find(',', dataPrefixLength); + if (dataDelimeter == std::string::npos) { + return std::nullopt; + } + + bool isBase64Encoded = false; + + DecodeResult result; + + result.mimeType = uri.substr(dataPrefixLength, dataDelimeter - dataPrefixLength); + if ( + result.mimeType.size() >= base64IndicatorLength && + result.mimeType.substr(result.mimeType.size() - base64IndicatorLength, base64IndicatorLength) == base64Indicator + ) { + isBase64Encoded = true; + result.mimeType = result.mimeType.substr(0, result.mimeType.size() - base64IndicatorLength); + } + + gsl::span data(reinterpret_cast(uri.data()) + dataDelimeter + 1, uri.size() - dataDelimeter - 1); + + if (isBase64Encoded) { + result.data = decodeBase64(data); + if (result.data.empty() && !data.empty()) { + // base64 decode failed. + return std::nullopt; + } + } else { + result.data = std::vector(data.begin(), data.end()); + } + + return result; + } +} + +namespace CesiumGltf { + +void decodeDataUrls(ModelReaderResult& readModel, bool clearDecodedDataUrls) { + if (!readModel.model) { + return; + } + + Model& model = readModel.model.value(); + + for (Buffer& buffer : model.buffers) { + if (!buffer.uri) { + continue; + } + + std::optional decoded = tryDecode(buffer.uri.value()); + if (!decoded) { + continue; + } + + buffer.cesium.data = std::move(decoded.value().data); + + if (clearDecodedDataUrls) { + buffer.uri.reset(); + } + } + + for (Image& image : model.images) { + if (!image.uri) { + continue; + } + + std::optional decoded = tryDecode(image.uri.value()); + if (!decoded) { + continue; + } + + ImageReaderResult imageResult = readImage(decoded.value().data); + if (imageResult.image) { + image.cesium = std::move(imageResult.image.value()); + } + + if (clearDecodedDataUrls) { + image.uri.reset(); + } + } +} + +} diff --git a/CesiumGltfReader/src/decodeDataUrls.h b/CesiumGltfReader/src/decodeDataUrls.h new file mode 100644 index 000000000..0dc62b6f4 --- /dev/null +++ b/CesiumGltfReader/src/decodeDataUrls.h @@ -0,0 +1,7 @@ +#pragma once + +namespace CesiumGltf { + struct ModelReaderResult; + + void decodeDataUrls(ModelReaderResult& readModel, bool clearDecodedDataUrls); +} diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index c6af6a0e8..0f3234a76 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -18,3 +18,5 @@ add_subdirectory(tinyxml2) add_subdirectory(asyncplusplus) add_subdirectory(spdlog) + +add_subdirectory(modp_b64) \ No newline at end of file diff --git a/extern/modp_b64/CMakeLists.txt b/extern/modp_b64/CMakeLists.txt new file mode 100644 index 000000000..db8192ab4 --- /dev/null +++ b/extern/modp_b64/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(modp_b64 STATIC modp_b64.cc modp_b64.h modp_b64_data.h) + +target_include_directories( + modp_b64 + SYSTEM PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/extern/modp_b64/LICENSE b/extern/modp_b64/LICENSE new file mode 100644 index 000000000..55af76f3e --- /dev/null +++ b/extern/modp_b64/LICENSE @@ -0,0 +1,33 @@ + * MODP_B64 - High performance base64 encoder/decoder + * Version 1.3 -- 17-Mar-2006 + * http://modp.com/release/base64 + * + * Copyright (c) 2005, 2006 Nick Galbreath -- nickg [at] modp [dot] com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of the modp.com nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/extern/modp_b64/README.cesium b/extern/modp_b64/README.cesium new file mode 100644 index 000000000..86b62e2c0 --- /dev/null +++ b/extern/modp_b64/README.cesium @@ -0,0 +1,6 @@ +This is a fork of Chromium's modp_b64 at commit 15996b5d2322b634f4197447b10289bddc2b0b32: +https://github.com/chromium/chromium/tree/15996b5d2322b634f4197447b10289bddc2b0b32/third_party/modp_b64 + +It is unmodified from the original at the initial commit to Cesium. We have only added this README and a CMakeLists.txt. + +Chromium's implementation is, in turn, a fork of https://github.com/client9/stringencoders. diff --git a/extern/modp_b64/README.chromium b/extern/modp_b64/README.chromium new file mode 100644 index 000000000..364a05073 --- /dev/null +++ b/extern/modp_b64/README.chromium @@ -0,0 +1,17 @@ +Name: modp base64 decoder +Short Name: stringencoders +URL: https://github.com/client9/stringencoders +Version: unknown +License: BSD +Security Critical: yes + +Description: +The modp_b64.c file was modified to remove the inclusion of modp's config.h +and to fix compilation errors that occur under VC8. The file was renamed +modp_b64.cc to force it to be compiled as C++ so that the inclusion of +basictypes.h could be possible. + +The modp_b64.cc and modp_b64.h files were modified to make them safe on +64-bit systems. +The modp_b64.cc was modified to avoid misaligned read/write on +little-endian hardware. diff --git a/extern/modp_b64/modp_b64.cc b/extern/modp_b64/modp_b64.cc new file mode 100644 index 000000000..fdb8a40ec --- /dev/null +++ b/extern/modp_b64/modp_b64.cc @@ -0,0 +1,253 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ +/* vi: set expandtab shiftwidth=4 tabstop=4: */ +/** + * \file + *
+ * MODP_B64 - High performance base64 encoder/decoder
+ * Version 1.3 -- 17-Mar-2006
+ * http://modp.com/release/base64
+ *
+ * Copyright © 2005, 2006  Nick Galbreath -- nickg [at] modp [dot] com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ *   Neither the name of the modp.com nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This is the standard "new" BSD license:
+ * http://www.opensource.org/licenses/bsd-license.php
+ * 
+ */ + +/* public header */ +#include "modp_b64.h" + +/* + * If you are ripping this out of the library, comment out the next + * line and uncomment the next lines as approrpiate + */ +//#include "config.h" + +/* if on motoral, sun, ibm; uncomment this */ +/* #define WORDS_BIGENDIAN 1 */ +/* else for Intel, Amd; uncomment this */ +/* #undef WORDS_BIGENDIAN */ + +#include "modp_b64_data.h" + +#define BADCHAR 0x01FFFFFF + +/** + * you can control if we use padding by commenting out this + * next line. However, I highly recommend you use padding and not + * using it should only be for compatability with a 3rd party. + * Also, 'no padding' is not tested! + */ +#define DOPAD 1 + +/* + * if we aren't doing padding + * set the pad character to NULL + */ +#ifndef DOPAD +#undef CHARPAD +#define CHARPAD '\0' +#endif + +size_t modp_b64_encode(char* dest, const char* str, size_t len) +{ + size_t i = 0; + uint8_t* p = (uint8_t*) dest; + + /* unsigned here is important! */ + uint8_t t1, t2, t3; + + if (len > 2) { + for (; i < len - 2; i += 3) { + t1 = str[i]; t2 = str[i+1]; t3 = str[i+2]; + *p++ = e0[t1]; + *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; + *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)]; + *p++ = e2[t3]; + } + } + + switch (len - i) { + case 0: + break; + case 1: + t1 = str[i]; + *p++ = e0[t1]; + *p++ = e1[(t1 & 0x03) << 4]; + *p++ = CHARPAD; + *p++ = CHARPAD; + break; + default: /* case 2 */ + t1 = str[i]; t2 = str[i+1]; + *p++ = e0[t1]; + *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; + *p++ = e2[(t2 & 0x0F) << 2]; + *p++ = CHARPAD; + } + + *p = '\0'; + return p - (uint8_t*)dest; +} + +#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */ +int modp_b64_decode(char* dest, const char* src, int len) +{ + if (len == 0) return 0; + +#ifdef DOPAD + /* if padding is used, then the message must be at least + 4 chars and be a multiple of 4. + there can be at most 2 pad chars at the end */ + if (len < 4 || (len % 4 != 0)) return MODP_B64_ERROR; + if (src[len-1] == CHARPAD) { + len--; + if (src[len -1] == CHARPAD) { + len--; + } + } +#endif /* DOPAD */ + + size_t i; + int leftover = len % 4; + size_t chunks = (leftover == 0) ? len / 4 - 1 : len /4; + + uint8_t* p = (uint8_t*) dest; + uint32_t x = 0; + uint32_t* destInt = (uint32_t*) p; + uint32_t* srcInt = (uint32_t*) src; + uint32_t y = *srcInt++; + for (i = 0; i < chunks; ++i) { + x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | + d2[y >> 8 & 0xff] | d3[y & 0xff]; + + if (x >= BADCHAR) return MODP_B64_ERROR; + *destInt = x << 8; + p += 3; + destInt = (uint32_t*)p; + y = *srcInt++; + } + + switch (leftover) { + case 0: + x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | + d2[y >> 8 & 0xff] | d3[y & 0xff]; + if (x >= BADCHAR) return MODP_B64_ERROR; + *p++ = ((uint8_t*)&x)[1]; + *p++ = ((uint8_t*)&x)[2]; + *p = ((uint8_t*)&x)[3]; + return (chunks+1)*3; + case 1: + x = d3[y >> 24]; + *p = (uint8_t)x; + break; + case 2: + x = d3[y >> 24] *64 + d3[(y >> 16) & 0xff]; + *p = (uint8_t)(x >> 4); + break; + default: /* case 3 */ + x = (d3[y >> 24] *64 + d3[(y >> 16) & 0xff])*64 + + d3[(y >> 8) & 0xff]; + *p++ = (uint8_t) (x >> 10); + *p = (uint8_t) (x >> 2); + break; + } + + if (x >= BADCHAR) return MODP_B64_ERROR; + return 3*chunks + (6*leftover)/8; +} + +#else /* LITTLE ENDIAN -- INTEL AND FRIENDS */ + +size_t modp_b64_decode(char* dest, const char* src, size_t len) +{ + if (len == 0) return 0; + +#ifdef DOPAD + /* + * if padding is used, then the message must be at least + * 4 chars and be a multiple of 4 + */ + if (len < 4 || (len % 4 != 0)) return MODP_B64_ERROR; /* error */ + /* there can be at most 2 pad chars at the end */ + if (src[len-1] == CHARPAD) { + len--; + if (src[len -1] == CHARPAD) { + len--; + } + } +#endif + + size_t i; + int leftover = len % 4; + size_t chunks = (leftover == 0) ? len / 4 - 1 : len /4; + + uint8_t* p = (uint8_t*)dest; + uint32_t x = 0; + const uint8_t* y = (uint8_t*)src; + for (i = 0; i < chunks; ++i, y += 4) { + x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]]; + if (x >= BADCHAR) return MODP_B64_ERROR; + *p++ = ((uint8_t*)(&x))[0]; + *p++ = ((uint8_t*)(&x))[1]; + *p++ = ((uint8_t*)(&x))[2]; + } + + switch (leftover) { + case 0: + x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]]; + + if (x >= BADCHAR) return MODP_B64_ERROR; + *p++ = ((uint8_t*)(&x))[0]; + *p++ = ((uint8_t*)(&x))[1]; + *p = ((uint8_t*)(&x))[2]; + return (chunks+1)*3; + break; + case 1: /* with padding this is an impossible case */ + x = d0[y[0]]; + *p = *((uint8_t*)(&x)); // i.e. first char/byte in int + break; + case 2: // * case 2, 1 output byte */ + x = d0[y[0]] | d1[y[1]]; + *p = *((uint8_t*)(&x)); // i.e. first char + break; + default: /* case 3, 2 output bytes */ + x = d0[y[0]] | d1[y[1]] | d2[y[2]]; /* 0x3c */ + *p++ = ((uint8_t*)(&x))[0]; + *p = ((uint8_t*)(&x))[1]; + break; + } + + if (x >= BADCHAR) return MODP_B64_ERROR; + + return 3*chunks + (6*leftover)/8; +} + +#endif /* if bigendian / else / endif */ diff --git a/extern/modp_b64/modp_b64.h b/extern/modp_b64/modp_b64.h new file mode 100644 index 000000000..3270e5fdf --- /dev/null +++ b/extern/modp_b64/modp_b64.h @@ -0,0 +1,171 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ +/* vi: set expandtab shiftwidth=4 tabstop=4: */ + +/** + * \file + *
+ * High performance base64 encoder / decoder
+ * Version 1.3 -- 17-Mar-2006
+ *
+ * Copyright © 2005, 2006, Nick Galbreath -- nickg [at] modp [dot] com
+ * All rights reserved.
+ *
+ * http://modp.com/release/base64
+ *
+ * Released under bsd license.  See modp_b64.c for details.
+ * 
+ * + * The default implementation is the standard b64 encoding with padding. + * It's easy to change this to use "URL safe" characters and to remove + * padding. See the modp_b64.c source code for details. + * + */ + +#ifndef MODP_B64 +#define MODP_B64 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Encode a raw binary string into base 64. + * src contains the bytes + * len contains the number of bytes in the src + * dest should be allocated by the caller to contain + * at least modp_b64_encode_len(len) bytes (see below) + * This will contain the null-terminated b64 encoded result + * returns length of the destination string plus the ending null byte + * i.e. the result will be equal to strlen(dest) + 1 + * + * Example + * + * \code + * char* src = ...; + * int srclen = ...; //the length of number of bytes in src + * char* dest = (char*) malloc(modp_b64_encode_len); + * int len = modp_b64_encode(dest, src, sourcelen); + * if (len == -1) { + * printf("Error\n"); + * } else { + * printf("b64 = %s\n", dest); + * } + * \endcode + * + */ +size_t modp_b64_encode(char* dest, const char* str, size_t len); + +/** + * Decode a base64 encoded string + * + * src should contain exactly len bytes of b64 characters. + * if src contains -any- non-base characters (such as white + * space, -1 is returned. + * + * dest should be allocated by the caller to contain at least + * len * 3 / 4 bytes. + * + * Returns the length (strlen) of the output, or -1 if unable to + * decode + * + * \code + * char* src = ...; + * int srclen = ...; // or if you don't know use strlen(src) + * char* dest = (char*) malloc(modp_b64_decode_len(srclen)); + * int len = modp_b64_decode(dest, src, sourcelen); + * if (len == -1) { error } + * \endcode + */ +size_t modp_b64_decode(char* dest, const char* src, size_t len); + +/** + * Given a source string of length len, this returns the amount of + * memory the destination string should have. + * + * remember, this is integer math + * 3 bytes turn into 4 chars + * ceiling[len / 3] * 4 + 1 + * + * +1 is for any extra null. + */ +#define modp_b64_encode_len(A) ((A+2)/3 * 4 + 1) + +/** + * Given a base64 string of length len, + * this returns the amount of memory required for output string + * It maybe be more than the actual number of bytes written. + * NOTE: remember this is integer math + * this allocates a bit more memory than traditional versions of b64 + * decode 4 chars turn into 3 bytes + * floor[len * 3/4] + 2 + */ +#define modp_b64_decode_len(A) (A / 4 * 3 + 2) + +/** + * Will return the strlen of the output from encoding. + * This may be less than the required number of bytes allocated. + * + * This allows you to 'deserialized' a struct + * \code + * char* b64encoded = "..."; + * int len = strlen(b64encoded); + * + * struct datastuff foo; + * if (modp_b64_encode_strlen(sizeof(struct datastuff)) != len) { + * // wrong size + * return false; + * } else { + * // safe to do; + * if (modp_b64_decode((char*) &foo, b64encoded, len) == -1) { + * // bad characters + * return false; + * } + * } + * // foo is filled out now + * \endcode + */ +#define modp_b64_encode_strlen(A) ((A + 2)/ 3 * 4) + +#define MODP_B64_ERROR ((size_t)-1) + +#ifdef __cplusplus +} + +#include + +inline std::string& modp_b64_encode(std::string& s) +{ + std::string x(modp_b64_encode_len(s.size()), '\0'); + size_t d = modp_b64_encode(const_cast(x.data()), s.data(), (int)s.size()); + x.erase(d, std::string::npos); + s.swap(x); + return s; +} + +/** + * base 64 decode a string (self-modifing) + * On failure, the string is empty. + * + * This function is for C++ only (duh) + * + * \param[in,out] s the string to be decoded + * \return a reference to the input string + */ +inline std::string& modp_b64_decode(std::string& s) +{ + std::string x(modp_b64_decode_len(s.size()), '\0'); + size_t d = modp_b64_decode(const_cast(x.data()), s.data(), (int)s.size()); + if (d == MODP_B64_ERROR) { + x.clear(); + } else { + x.erase(d, std::string::npos); + } + s.swap(x); + return s; +} + +#endif /* __cplusplus */ + +#endif /* MODP_B64 */ diff --git a/extern/modp_b64/modp_b64_data.h b/extern/modp_b64/modp_b64_data.h new file mode 100644 index 000000000..2ecf5977b --- /dev/null +++ b/extern/modp_b64/modp_b64_data.h @@ -0,0 +1,481 @@ +#include + +#define CHAR62 '+' +#define CHAR63 '/' +#define CHARPAD '=' +static const char e0[256] = { + 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', + 'C', 'C', 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E', + 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H', + 'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J', + 'K', 'K', 'K', 'K', 'L', 'L', 'L', 'L', 'M', 'M', + 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', + 'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R', + 'R', 'R', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'T', + 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W', + 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y', + 'Z', 'Z', 'Z', 'Z', 'a', 'a', 'a', 'a', 'b', 'b', + 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd', + 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', + 'g', 'g', 'h', 'h', 'h', 'h', 'i', 'i', 'i', 'i', + 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l', + 'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', + 'o', 'o', 'o', 'o', 'p', 'p', 'p', 'p', 'q', 'q', + 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's', + 't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v', + 'v', 'v', 'w', 'w', 'w', 'w', 'x', 'x', 'x', 'x', + 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0', + '0', '0', '1', '1', '1', '1', '2', '2', '2', '2', + '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', + '5', '5', '6', '6', '6', '6', '7', '7', '7', '7', + '8', '8', '8', '8', '9', '9', '9', '9', '+', '+', + '+', '+', '/', '/', '/', '/' +}; + +static const char e1[256] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', + 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '+', '/' +}; + +static const char e2[256] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', + 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '+', '/' +}; + + + +#ifdef WORDS_BIGENDIAN + + +/* SPECIAL DECODE TABLES FOR BIG ENDIAN (IBM/MOTOROLA/SUN) CPUS */ + +static const uint32_t d0[256] = { +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x00f80000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00fc0000, +0x00d00000, 0x00d40000, 0x00d80000, 0x00dc0000, 0x00e00000, 0x00e40000, +0x00e80000, 0x00ec0000, 0x00f00000, 0x00f40000, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, +0x00040000, 0x00080000, 0x000c0000, 0x00100000, 0x00140000, 0x00180000, +0x001c0000, 0x00200000, 0x00240000, 0x00280000, 0x002c0000, 0x00300000, +0x00340000, 0x00380000, 0x003c0000, 0x00400000, 0x00440000, 0x00480000, +0x004c0000, 0x00500000, 0x00540000, 0x00580000, 0x005c0000, 0x00600000, +0x00640000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x00680000, 0x006c0000, 0x00700000, 0x00740000, 0x00780000, +0x007c0000, 0x00800000, 0x00840000, 0x00880000, 0x008c0000, 0x00900000, +0x00940000, 0x00980000, 0x009c0000, 0x00a00000, 0x00a40000, 0x00a80000, +0x00ac0000, 0x00b00000, 0x00b40000, 0x00b80000, 0x00bc0000, 0x00c00000, +0x00c40000, 0x00c80000, 0x00cc0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff +}; + + +static const uint32_t d1[256] = { +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x0003e000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003f000, +0x00034000, 0x00035000, 0x00036000, 0x00037000, 0x00038000, 0x00039000, +0x0003a000, 0x0003b000, 0x0003c000, 0x0003d000, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, +0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, +0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, +0x0000d000, 0x0000e000, 0x0000f000, 0x00010000, 0x00011000, 0x00012000, +0x00013000, 0x00014000, 0x00015000, 0x00016000, 0x00017000, 0x00018000, +0x00019000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x0001a000, 0x0001b000, 0x0001c000, 0x0001d000, 0x0001e000, +0x0001f000, 0x00020000, 0x00021000, 0x00022000, 0x00023000, 0x00024000, +0x00025000, 0x00026000, 0x00027000, 0x00028000, 0x00029000, 0x0002a000, +0x0002b000, 0x0002c000, 0x0002d000, 0x0002e000, 0x0002f000, 0x00030000, +0x00031000, 0x00032000, 0x00033000, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff +}; + + +static const uint32_t d2[256] = { +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x00000f80, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000fc0, +0x00000d00, 0x00000d40, 0x00000d80, 0x00000dc0, 0x00000e00, 0x00000e40, +0x00000e80, 0x00000ec0, 0x00000f00, 0x00000f40, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, +0x00000040, 0x00000080, 0x000000c0, 0x00000100, 0x00000140, 0x00000180, +0x000001c0, 0x00000200, 0x00000240, 0x00000280, 0x000002c0, 0x00000300, +0x00000340, 0x00000380, 0x000003c0, 0x00000400, 0x00000440, 0x00000480, +0x000004c0, 0x00000500, 0x00000540, 0x00000580, 0x000005c0, 0x00000600, +0x00000640, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x00000680, 0x000006c0, 0x00000700, 0x00000740, 0x00000780, +0x000007c0, 0x00000800, 0x00000840, 0x00000880, 0x000008c0, 0x00000900, +0x00000940, 0x00000980, 0x000009c0, 0x00000a00, 0x00000a40, 0x00000a80, +0x00000ac0, 0x00000b00, 0x00000b40, 0x00000b80, 0x00000bc0, 0x00000c00, +0x00000c40, 0x00000c80, 0x00000cc0, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff +}; + + +static const uint32_t d3[256] = { +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x0000003e, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003f, +0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, +0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, +0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, +0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, +0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, 0x00000012, +0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, +0x00000019, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d, 0x0000001e, +0x0000001f, 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, +0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a, +0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030, +0x00000031, 0x00000032, 0x00000033, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff +}; + + +#else + + +/* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */ + +static const uint32_t d0[256] = { +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc, +0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, +0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, +0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018, +0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030, +0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048, +0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, +0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, +0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, +0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, +0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0, +0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff +}; + + +static const uint32_t d1[256] = { +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003, +0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, +0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, +0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, +0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, +0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001, +0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, +0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, +0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002, +0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002, +0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003, +0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff +}; + + +static const uint32_t d2[256] = { +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00, +0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, +0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, +0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100, +0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300, +0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400, +0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, +0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700, +0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900, +0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00, +0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00, +0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff +}; + + +static const uint32_t d3[256] = { +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000, +0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, +0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, +0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, +0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000, +0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000, +0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, +0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, +0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000, +0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000, +0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000, +0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, +0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff +}; + + +#endif From 474a2b81209ecd36aade5185026237b4658cac94 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 28 Jan 2021 10:20:22 +1100 Subject: [PATCH 58/61] Bring over generator changes from the cmpt branch. --- tools/generate-gltf-classes/generate.js | 23 ++++++++++++++++++----- tools/generate-gltf-classes/glTF.json | 3 +++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tools/generate-gltf-classes/generate.js b/tools/generate-gltf-classes/generate.js index 26d8a7801..e988ab17e 100644 --- a/tools/generate-gltf-classes/generate.js +++ b/tools/generate-gltf-classes/generate.js @@ -38,9 +38,11 @@ function generate(options, schema) { lodash.flatten(properties.map((property) => property.localTypes)) ); - const headers = lodash.uniq( - [`"CesiumGltf/${base}.h"`, ...lodash.flatten(properties.map((property) => property.headers))] - ); + const headers = lodash.uniq([ + `"CesiumGltf/Library.h"`, + `"CesiumGltf/${base}.h"`, + ...lodash.flatten(properties.map((property) => property.headers)) + ]); headers.sort(); @@ -55,7 +57,7 @@ function generate(options, schema) { /** * @brief ${schema.description} */ - struct ${name}${thisConfig.toBeInherited ? "Spec" : ""} : public ${base} { + struct CESIUMGLTF_API ${name}${thisConfig.toBeInherited ? "Spec" : (thisConfig.isBaseClass ? "" : " final")} : public ${base} { ${indent(localTypes.join("\n\n"), 16)} ${indent( @@ -65,7 +67,7 @@ function generate(options, schema) { .join("\n\n"), 16 )} - + ${thisConfig.toBeInherited ? privateSpecConstructor(name) : ""} }; } `; @@ -224,4 +226,15 @@ function formatReaderPropertyImpl(property) { return `if ("${property.name}"s == str) return property("${property.name}", this->_${property.name}, o.${property.name});`; } +function privateSpecConstructor(name) { + return ` + private: + /** + * @brief This class is not mean to be instantiated directly. Use {@link ${name}} instead. + */ + ${name}Spec() = default; + friend struct ${name}; + `; +} + module.exports = generate; diff --git a/tools/generate-gltf-classes/glTF.json b/tools/generate-gltf-classes/glTF.json index 98b43b0c2..91d74ee05 100644 --- a/tools/generate-gltf-classes/glTF.json +++ b/tools/generate-gltf-classes/glTF.json @@ -18,6 +18,9 @@ }, "Accessor": { "toBeInherited": true + }, + "Texture Info": { + "isBaseClass": true } }, "extensions": [ From 2932b5652bf43003b70045f3f54099c61890baaa Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 28 Jan 2021 16:25:52 +1100 Subject: [PATCH 59/61] Add test for decoding data urls. --- CesiumGltfReader/src/decodeDataUrls.cpp | 2 + CesiumGltfReader/test/TestReader.cpp | 43 ++++++++++++++- CesiumGltfReader/test/data/README.md | 2 + .../test/data/TriangleWithoutIndices.gltf | 54 +++++++++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 CesiumGltfReader/test/data/README.md create mode 100644 CesiumGltfReader/test/data/TriangleWithoutIndices.gltf diff --git a/CesiumGltfReader/src/decodeDataUrls.cpp b/CesiumGltfReader/src/decodeDataUrls.cpp index 9ae82caa8..d5276e3a5 100644 --- a/CesiumGltfReader/src/decodeDataUrls.cpp +++ b/CesiumGltfReader/src/decodeDataUrls.cpp @@ -12,6 +12,8 @@ namespace { if (resultLength == size_t(-1)) { result.clear(); result.shrink_to_fit(); + } else { + result.resize(resultLength); } return result; diff --git a/CesiumGltfReader/test/TestReader.cpp b/CesiumGltfReader/test/TestReader.cpp index 1627a336b..32de322f3 100644 --- a/CesiumGltfReader/test/TestReader.cpp +++ b/CesiumGltfReader/test/TestReader.cpp @@ -1,11 +1,34 @@ #include "catch2/catch.hpp" #include "CesiumGltf/Reader.h" +#include "CesiumGltf/AccessorView.h" #include #include #include +#include +#include using namespace CesiumGltf; +namespace { + std::vector readFile(const std::string& path) { + FILE* fp = std::fopen(path.c_str(), "rb"); + if (!fp) { + return {}; + } + + std::fseek(fp, 0, SEEK_END); + long pos = std::ftell(fp); + std::fseek(fp, 0, SEEK_SET); + + std::vector result(pos); + std::fread(result.data(), 1, result.size(), fp); + + std::fclose(fp); + + return result; + } +} + TEST_CASE("CesiumGltf::Reader") { using namespace std::string_literals; @@ -58,4 +81,22 @@ TEST_CASE("CesiumGltf::Reader") { REQUIRE(model.meshes[0].primitives[0].targets.size() == 1); CHECK(model.meshes[0].primitives[0].targets[0]["POSITION"] == 10); CHECK(model.meshes[0].primitives[0].targets[0]["NORMAL"] == 11); -} \ No newline at end of file +} + +TEST_CASE("Read TriangleWithoutIndices") { + std::vector data = readFile("../CesiumGltfReader/test/data/TriangleWithoutIndices.gltf"); + ModelReaderResult result = CesiumGltf::readModel(data); + REQUIRE(result.model); + + const Model& model = result.model.value(); + REQUIRE(model.meshes.size() == 1); + REQUIRE(model.meshes[0].primitives.size() == 1); + REQUIRE(model.meshes[0].primitives[0].attributes.size() == 1); + REQUIRE(model.meshes[0].primitives[0].attributes.begin()->second == 0); + + AccessorView position(model, 0); + REQUIRE(position.size() == 3); + CHECK(position[0] == glm::vec3(0.0, 0.0, 0.0)); + CHECK(position[1] == glm::vec3(1.0, 0.0, 0.0)); + CHECK(position[2] == glm::vec3(0.0, 1.0, 0.0)); +} diff --git a/CesiumGltfReader/test/data/README.md b/CesiumGltfReader/test/data/README.md new file mode 100644 index 000000000..472fc2be9 --- /dev/null +++ b/CesiumGltfReader/test/data/README.md @@ -0,0 +1,2 @@ +Test models from: +https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0 diff --git a/CesiumGltfReader/test/data/TriangleWithoutIndices.gltf b/CesiumGltfReader/test/data/TriangleWithoutIndices.gltf new file mode 100644 index 000000000..1c0736ab3 --- /dev/null +++ b/CesiumGltfReader/test/data/TriangleWithoutIndices.gltf @@ -0,0 +1,54 @@ +{ + "scene" : 0, + "scenes" : [ + { + "nodes" : [ 0 ] + } + ], + + "nodes" : [ + { + "mesh" : 0 + } + ], + + "meshes" : [ + { + "primitives" : [ { + "attributes" : { + "POSITION" : 0 + } + } ] + } + ], + + "buffers" : [ + { + "uri" : "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA", + "byteLength" : 36 + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteOffset" : 0, + "byteLength" : 36, + "target" : 34962 + } + ], + "accessors" : [ + { + "bufferView" : 0, + "byteOffset" : 0, + "componentType" : 5126, + "count" : 3, + "type" : "VEC3", + "max" : [ 1.0, 1.0, 0.0 ], + "min" : [ 0.0, 0.0, 0.0 ] + } + ], + + "asset" : { + "version" : "2.0" + } +} \ No newline at end of file From 92af1b4b6741052715efede51c0f8c17512a6dcf Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 28 Jan 2021 16:37:34 +1100 Subject: [PATCH 60/61] Fix gcc/clang warning. --- CesiumGltfReader/test/TestReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CesiumGltfReader/test/TestReader.cpp b/CesiumGltfReader/test/TestReader.cpp index 32de322f3..d99ca4bfa 100644 --- a/CesiumGltfReader/test/TestReader.cpp +++ b/CesiumGltfReader/test/TestReader.cpp @@ -20,7 +20,7 @@ namespace { long pos = std::ftell(fp); std::fseek(fp, 0, SEEK_SET); - std::vector result(pos); + std::vector result(static_cast(pos)); std::fread(result.data(), 1, result.size(), fp); std::fclose(fp); From e692908f28f954c71224d70822cf17482387f76d Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 28 Jan 2021 17:14:21 +1100 Subject: [PATCH 61/61] Fix gcc warning. --- CesiumGltfReader/test/TestReader.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/CesiumGltfReader/test/TestReader.cpp b/CesiumGltfReader/test/TestReader.cpp index d99ca4bfa..1aefc6494 100644 --- a/CesiumGltfReader/test/TestReader.cpp +++ b/CesiumGltfReader/test/TestReader.cpp @@ -12,20 +12,26 @@ using namespace CesiumGltf; namespace { std::vector readFile(const std::string& path) { FILE* fp = std::fopen(path.c_str(), "rb"); - if (!fp) { - return {}; - } + REQUIRE(fp); - std::fseek(fp, 0, SEEK_END); - long pos = std::ftell(fp); - std::fseek(fp, 0, SEEK_SET); + try { + std::fseek(fp, 0, SEEK_END); + long pos = std::ftell(fp); + std::fseek(fp, 0, SEEK_SET); - std::vector result(static_cast(pos)); - std::fread(result.data(), 1, result.size(), fp); + std::vector result(static_cast(pos)); + size_t itemsRead = std::fread(result.data(), 1, result.size(), fp); + REQUIRE(itemsRead == result.size()); - std::fclose(fp); + std::fclose(fp); - return result; + return result; + } catch(...) { + if (fp) { + std::fclose(fp); + } + throw; + } } }