#pragma once #include #include #include #include #include #include #include #include #include #include #include namespace CesiumGltf { struct Model; struct Buffer; } // namespace CesiumGltf namespace Cesium3DTilesContent { namespace GltfConverterUtility { std::optional parseOffsetForSemantic( const rapidjson::Document& document, const char* semantic, CesiumUtility::ErrorList& errorList); typedef bool (rapidjson::Value::*ValuePredicate)() const; template bool isValue(const rapidjson::Value& value); template T getValue(const rapidjson::Value& value); template std::optional getOptional(const rapidjson::Value& value) { if (isValue(value)) { return std::make_optional(getValue(value)); } return {}; } template std::optional getValue(const rapidjson::Document& document, const char* semantic) { const auto valueIt = document.FindMember(semantic); if (valueIt == document.MemberEnd() || !isValue(valueIt->value)) { return {}; } return std::make_optional(getValue(valueIt->value)); } template <> inline bool isValue(const rapidjson::Value& value) { return value.IsBool(); } template <> inline bool getValue(const rapidjson::Value& value) { return value.GetBool(); } template <> inline bool isValue(const rapidjson::Value& value) { return value.IsUint(); } template <> inline uint32_t getValue(const rapidjson::Value& value) { return value.GetUint(); } bool validateJsonArrayValues( const rapidjson::Value& arrayValue, uint32_t expectedLength, ValuePredicate predicate); std::optional parseArrayValueDVec3(const rapidjson::Value& arrayValue); std::optional parseArrayValueDVec3(const rapidjson::Document& document, const char* name); int32_t createBufferInGltf(CesiumGltf::Model& gltf, std::vector buffer = {}); int32_t createBufferViewInGltf( CesiumGltf::Model& gltf, const int32_t bufferId, const int64_t byteLength, const int64_t byteStride); int32_t createAccessorInGltf( CesiumGltf::Model& gltf, const int32_t bufferViewId, const int32_t componentType, const int64_t count, const std::string type); /** * Applies the given relative-to-center (RTC) translation to the transforms of * all nodes in the glTF. This is useful in converting i3dm files, where the RTC * translation must be applied to the model before the i3dm instance * transform. It's also the 3D Tiles 1.1 "way" to do away with RTC and encode it * directly in the glTF. */ void applyRtcToNodes(CesiumGltf::Model& gltf, const glm::dvec3& rtc); template GlmType toGlm(const GLTFType& gltfVal); template GlmType toGlm(const CesiumGltf::AccessorTypes::VEC3& gltfVal) { return GlmType(gltfVal.value[0], gltfVal.value[1], gltfVal.value[2]); } template GlmType toGlmQuat(const CesiumGltf::AccessorTypes::VEC4& gltfVal) { if constexpr (std::is_same()) { return GlmType( gltfVal.value[3], gltfVal.value[0], gltfVal.value[1], gltfVal.value[2]); } else { return GlmType( CesiumGltf::normalize(gltfVal.value[3]), CesiumGltf::normalize(gltfVal.value[0]), CesiumGltf::normalize(gltfVal.value[1]), CesiumGltf::normalize(gltfVal.value[2])); } } } // namespace GltfConverterUtility } // namespace Cesium3DTilesContent