Files

133 lines
3.8 KiB
C++

#pragma once
#include <Cesium3DTilesContent/GltfConverters.h>
#include <CesiumAsync/IAssetAccessor.h>
#include <CesiumAsync/IAssetRequest.h>
#include <CesiumGltf/AccessorView.h>
#include <CesiumGltf/PropertyTransformations.h>
#include <CesiumUtility/ErrorList.h>
#include <glm/fwd.hpp>
#include <rapidjson/document.h>
#include <cstdint>
#include <optional>
#include <vector>
namespace CesiumGltf {
struct Model;
struct Buffer;
} // namespace CesiumGltf
namespace Cesium3DTilesContent {
namespace GltfConverterUtility {
std::optional<uint32_t> parseOffsetForSemantic(
const rapidjson::Document& document,
const char* semantic,
CesiumUtility::ErrorList& errorList);
typedef bool (rapidjson::Value::*ValuePredicate)() const;
template <typename T> bool isValue(const rapidjson::Value& value);
template <typename T> T getValue(const rapidjson::Value& value);
template <typename T>
std::optional<T> getOptional(const rapidjson::Value& value) {
if (isValue<T>(value)) {
return std::make_optional(getValue<T>(value));
}
return {};
}
template <typename T>
std::optional<T>
getValue(const rapidjson::Document& document, const char* semantic) {
const auto valueIt = document.FindMember(semantic);
if (valueIt == document.MemberEnd() || !isValue<T>(valueIt->value)) {
return {};
}
return std::make_optional(getValue<T>(valueIt->value));
}
template <> inline bool isValue<bool>(const rapidjson::Value& value) {
return value.IsBool();
}
template <> inline bool getValue<bool>(const rapidjson::Value& value) {
return value.GetBool();
}
template <> inline bool isValue<uint32_t>(const rapidjson::Value& value) {
return value.IsUint();
}
template <> inline uint32_t getValue<uint32_t>(const rapidjson::Value& value) {
return value.GetUint();
}
bool validateJsonArrayValues(
const rapidjson::Value& arrayValue,
uint32_t expectedLength,
ValuePredicate predicate);
std::optional<glm::dvec3>
parseArrayValueDVec3(const rapidjson::Value& arrayValue);
std::optional<glm::dvec3>
parseArrayValueDVec3(const rapidjson::Document& document, const char* name);
int32_t
createBufferInGltf(CesiumGltf::Model& gltf, std::vector<std::byte> 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 <typename GlmType, typename GLTFType>
GlmType toGlm(const GLTFType& gltfVal);
template <typename GlmType, typename ComponentType>
GlmType toGlm(const CesiumGltf::AccessorTypes::VEC3<ComponentType>& gltfVal) {
return GlmType(gltfVal.value[0], gltfVal.value[1], gltfVal.value[2]);
}
template <typename GlmType, typename ComponentType>
GlmType
toGlmQuat(const CesiumGltf::AccessorTypes::VEC4<ComponentType>& gltfVal) {
if constexpr (std::is_same<ComponentType, float>()) {
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