133 lines
3.8 KiB
C
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
|