cesium-native 0.56.0
Loading...
Searching...
No Matches
PropertyView.h
1#pragma once
2
3#include <CesiumGltf/ClassProperty.h>
4#include <CesiumGltf/Enum.h>
5#include <CesiumGltf/PropertyArrayView.h>
6#include <CesiumGltf/PropertyAttributeProperty.h>
7#include <CesiumGltf/PropertyTableProperty.h>
8#include <CesiumGltf/PropertyTextureProperty.h>
9#include <CesiumGltf/PropertyType.h>
10#include <CesiumGltf/PropertyTypeTraits.h>
11
12#include <algorithm>
13#include <cstddef>
14#include <cstring>
15#include <optional>
16
17namespace CesiumGltf {
18
22typedef int32_t PropertyViewStatusType;
23
122
136template <typename T>
138 const ClassProperty& classProperty,
139 const CesiumGltf::Enum* pEnumDefinition = nullptr) {
140
142 convertStringToPropertyType(classProperty.type))) {
144 }
145
146 const bool isEnum = classProperty.type == ClassProperty::Type::ENUM;
147 const bool hasEnumDefinition = pEnumDefinition != nullptr;
148 if (isEnum != hasEnumDefinition) {
150 }
151
152 PropertyComponentType expectedComponentType =
154 if (isEnum) {
155 if (expectedComponentType !=
156 convertStringToPropertyComponentType(pEnumDefinition->valueType)) {
158 }
159 } else {
160 if (!classProperty.componentType &&
161 expectedComponentType != PropertyComponentType::None) {
163 }
164
165 if (classProperty.componentType &&
166 expectedComponentType != convertStringToPropertyComponentType(
167 *classProperty.componentType)) {
169 }
170 }
171
172 if (classProperty.array) {
174 }
175
177}
178
192template <typename T>
194 const ClassProperty& classProperty,
195 const CesiumGltf::Enum* pEnumDefinition = nullptr) {
196 using ElementType = typename MetadataArrayType<T>::type;
197
199 convertStringToPropertyType(classProperty.type))) {
201 }
202
203 const bool isEnum = classProperty.type == ClassProperty::Type::ENUM;
204 const bool hasEnumDefinition = pEnumDefinition != nullptr;
205 if (isEnum != hasEnumDefinition) {
207 }
208
209 PropertyComponentType expectedComponentType =
211 if (isEnum) {
212 if (expectedComponentType !=
213 convertStringToPropertyComponentType(pEnumDefinition->valueType)) {
215 }
216 } else {
217 if (!classProperty.componentType &&
218 expectedComponentType != PropertyComponentType::None) {
220 }
221
222 if (classProperty.componentType &&
223 expectedComponentType != convertStringToPropertyComponentType(
224 *classProperty.componentType)) {
226 }
227 }
228
229 if (!classProperty.array) {
231 }
232
234}
235
243template <typename T>
244static std::optional<T> getScalar(const CesiumUtility::JsonValue& jsonValue) {
245 return jsonValue.getSafeNumber<T>();
246}
247
257template <typename VecType>
258static std::optional<VecType>
259getVecN(const CesiumUtility::JsonValue& jsonValue) {
260 if (!jsonValue.isArray()) {
261 return std::nullopt;
262 }
263
264 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
265 constexpr glm::length_t N = VecType::length();
266 if (array.size() != N) {
267 return std::nullopt;
268 }
269
270 using T = typename VecType::value_type;
271
272 VecType result;
273 for (glm::length_t i = 0; i < N; i++) {
274 std::optional<T> value = getScalar<T>(array[static_cast<size_t>(i)]);
275 if (!value) {
276 return std::nullopt;
277 }
278
279 result[i] = *value;
280 }
281
282 return result;
283}
284
295template <typename MatType>
296static std::optional<MatType>
297getMatN(const CesiumUtility::JsonValue& jsonValue) {
298 if (!jsonValue.isArray()) {
299 return std::nullopt;
300 }
301
302 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
303 constexpr glm::length_t N = MatType::length();
304 if (array.size() != static_cast<size_t>(N * N)) {
305 return std::nullopt;
306 }
307
308 using T = typename MatType::value_type;
309
310 MatType result;
311 for (glm::length_t i = 0; i < N; i++) {
312 // Try to parse each value in the column.
313 for (glm::length_t j = 0; j < N; j++) {
314 std::optional<T> value =
315 getScalar<T>(array[static_cast<size_t>(i * N + j)]);
316 if (!value) {
317 return std::nullopt;
318 }
319
320 result[i][j] = *value;
321 }
322 }
323
324 return result;
325}
326
336template <typename ElementType>
337int64_t getCount(std::optional<std::vector<std::byte>>& buffer) {
338 if (!buffer) {
339 return 0;
340 }
341
342 return static_cast<int64_t>(buffer->size() / sizeof(ElementType));
343}
344
348template <typename ElementType, bool Normalized = false> class PropertyView;
349
362template <typename ElementType> class PropertyView<ElementType, false> {
363public:
368 : _status(PropertyViewStatus::ErrorNonexistentProperty),
369 _name(std::nullopt),
370 _semantic(std::nullopt),
371 _description(std::nullopt),
372 _offset(std::nullopt),
373 _scale(std::nullopt),
374 _max(std::nullopt),
375 _min(std::nullopt),
376 _required(false),
377 _noData(std::nullopt),
378 _defaultValue(std::nullopt),
379 _propertyType(PropertyType::Invalid) {}
380
384 PropertyView(const ClassProperty& classProperty)
385 : PropertyView(classProperty, nullptr) {}
386
392 const ClassProperty& classProperty,
393 const CesiumGltf::Enum* pEnumDefinition)
394 : _status(
395 validatePropertyType<ElementType>(classProperty, pEnumDefinition)),
396 _name(classProperty.name),
397 _semantic(classProperty.semantic),
398 _description(classProperty.description),
399 _offset(std::nullopt),
400 _scale(std::nullopt),
401 _max(std::nullopt),
402 _min(std::nullopt),
403 _required(classProperty.required),
404 _noData(std::nullopt),
405 _defaultValue(std::nullopt),
406 _propertyType(convertStringToPropertyType(classProperty.type)) {
408 return;
409 }
410
411 if (classProperty.normalized) {
412 _status = PropertyViewStatus::ErrorNormalizationMismatch;
413 return;
414 }
415
416 if (classProperty.type != ClassProperty::Type::ENUM) {
417 getNumericPropertyValues(classProperty);
418 }
419
421 return;
422 }
423
424 if (classProperty.noData) {
425 if (!_required && _propertyType == PropertyType::Enum) {
426 CESIUM_ASSERT(pEnumDefinition != nullptr);
427 if constexpr (IsMetadataInteger<ElementType>::value) {
428 // "noData" can only be defined if the property is not required.
429 _noData = getEnumValue(*classProperty.noData, *pEnumDefinition);
430 }
431 } else if (!_required && _propertyType != PropertyType::Enum) {
432 _noData = getValue(*classProperty.noData);
433 }
434
435 if (!_noData) {
436 // The value was specified but something went wrong.
438 return;
439 }
440 }
441
442 if (classProperty.defaultProperty) {
443 if (!_required && _propertyType == PropertyType::Enum) {
444 CESIUM_ASSERT(pEnumDefinition != nullptr);
445 if constexpr (IsMetadataInteger<ElementType>::value) {
446 // "default" can only be defined if the property is not required.
447 _defaultValue =
448 getEnumValue(*classProperty.defaultProperty, *pEnumDefinition);
449 }
450 } else if (!_required && _propertyType != PropertyType::Enum) {
451 _defaultValue = getValue(*classProperty.defaultProperty);
452 }
453
454 if (!_defaultValue) {
455 // The value was specified but something went wrong.
457 return;
458 }
459 }
460 }
461
462protected:
470 : _status(status),
471 _name(std::nullopt),
472 _semantic(std::nullopt),
473 _description(std::nullopt),
474 _offset(std::nullopt),
475 _scale(std::nullopt),
476 _max(std::nullopt),
477 _min(std::nullopt),
478 _required(false),
479 _noData(std::nullopt),
480 _defaultValue(std::nullopt),
481 _propertyType(PropertyType::Invalid) {}
482
488 const ClassProperty& classProperty,
489 const PropertyTableProperty& property,
490 const CesiumGltf::Enum* pEnumDefinition = nullptr)
491 : PropertyView(classProperty, pEnumDefinition) {
493 return;
494 }
495
496 // If the property has its own values, override the class-provided values.
497 if (classProperty.type != ClassProperty::Type::ENUM) {
498 getNumericPropertyValues(property);
499 }
500 }
501
507 const ClassProperty& classProperty,
508 const PropertyTextureProperty& property,
509 const CesiumGltf::Enum* pEnumDefinition = nullptr)
510 : PropertyView(classProperty, pEnumDefinition) {
512 return;
513 }
514
515 if (classProperty.type != ClassProperty::Type::ENUM) {
516 getNumericPropertyValues(property);
517 }
518 }
519
525 const ClassProperty& classProperty,
526 const PropertyAttributeProperty& property,
527 const CesiumGltf::Enum* pEnumDefinition = nullptr)
528 : PropertyView(classProperty, pEnumDefinition) {
530 return;
531 }
532
533 // If the property has its own values, override the class-provided values.
534 if (classProperty.type != ClassProperty::Type::ENUM) {
535 getNumericPropertyValues(property);
536 }
537 }
538
539public:
546 PropertyViewStatusType status() const noexcept { return _status; }
547
552 const std::optional<std::string>& name() const noexcept { return _name; }
553
560 const std::optional<std::string>& semantic() const noexcept {
561 return _semantic;
562 }
563
568 const std::optional<std::string>& description() const noexcept {
569 return _description;
570 }
571
578 int64_t arrayCount() const noexcept { return 0; }
579
583 bool normalized() const noexcept { return false; }
584
592 std::optional<ElementType> offset() const noexcept { return _offset; }
593
601 std::optional<ElementType> scale() const noexcept { return _scale; }
602
612 std::optional<ElementType> max() const noexcept { return _max; }
613
623 std::optional<ElementType> min() const noexcept { return _min; }
624
630 bool required() const noexcept { return _required; }
631
641 std::optional<ElementType> noData() const noexcept { return _noData; }
642
651 std::optional<ElementType> defaultValue() const noexcept {
652 return _defaultValue;
653 }
654
659 PropertyType propertyType() const noexcept { return _propertyType; }
660
661protected:
664
665private:
666 std::optional<std::string> _name;
667 std::optional<std::string> _semantic;
668 std::optional<std::string> _description;
669
670 std::optional<ElementType> _offset;
671 std::optional<ElementType> _scale;
672 std::optional<ElementType> _max;
673 std::optional<ElementType> _min;
674
675 bool _required;
676 std::optional<ElementType> _noData;
677 std::optional<ElementType> _defaultValue;
678 PropertyType _propertyType;
679
690 static std::optional<ElementType>
691 getValue(const CesiumUtility::JsonValue& jsonValue) {
693 return getScalar<ElementType>(jsonValue);
694 }
695
697 return getVecN<ElementType>(jsonValue);
698 }
699
701 return getMatN<ElementType>(jsonValue);
702 }
703 }
704
705 static std::optional<ElementType> getEnumValue(
706 const CesiumUtility::JsonValue& value,
707 const CesiumGltf::Enum& enumDefinition) {
708 if (!value.isString()) {
709 return std::nullopt;
710 }
711
712 const CesiumUtility::JsonValue::String& valueStr = value.getString();
713 const auto foundValue = std::find_if(
714 enumDefinition.values.begin(),
715 enumDefinition.values.end(),
716 [&valueStr](const CesiumGltf::EnumValue& enumValue) {
717 return enumValue.name == valueStr;
718 });
719
720 if (foundValue == enumDefinition.values.end()) {
721 return std::nullopt;
722 }
723
724 return static_cast<ElementType>(foundValue->value);
725 }
726
727 using PropertyDefinitionType = std::variant<
728 ClassProperty,
729 PropertyTableProperty,
730 PropertyTextureProperty,
731 PropertyAttributeProperty>;
732
737 void getNumericPropertyValues(const PropertyDefinitionType& inProperty) {
738 std::visit(
739 [this](auto property) {
740 if (property.offset) {
741 // Only floating point types can specify an offset.
742 switch (TypeToPropertyType<ElementType>::component) {
743 case PropertyComponentType::Float32:
744 case PropertyComponentType::Float64:
745 this->_offset = getValue(*property.offset);
746 if (this->_offset) {
747 break;
748 }
749 // If it does not break here, something went wrong.
750 [[fallthrough]];
751 default:
752 this->_status = PropertyViewStatus::ErrorInvalidOffset;
753 return;
754 }
755 }
756
757 if (property.scale) {
758 // Only floating point types can specify a scale.
759 switch (TypeToPropertyType<ElementType>::component) {
760 case PropertyComponentType::Float32:
761 case PropertyComponentType::Float64:
762 this->_scale = getValue(*property.scale);
763 if (this->_scale) {
764 break;
765 }
766 // If it does not break here, something went wrong.
767 [[fallthrough]];
768 default:
769 this->_status = PropertyViewStatus::ErrorInvalidScale;
770 return;
771 }
772 }
773
774 if (property.max) {
775 this->_max = getValue(*property.max);
776 if (!this->_max) {
777 // The value was specified but something went wrong.
778 this->_status = PropertyViewStatus::ErrorInvalidMax;
779 return;
780 }
781 }
782
783 if (property.min) {
784 this->_min = getValue(*property.min);
785 if (!this->_min) {
786 // The value was specified but something went wrong.
787 this->_status = PropertyViewStatus::ErrorInvalidMin;
788 return;
789 }
790 }
791 },
792 inProperty);
793 }
794};
795
809template <typename ElementType> class PropertyView<ElementType, true> {
810private:
811 using NormalizedType = typename TypeToNormalizedType<ElementType>::type;
812
813public:
818 : _status(PropertyViewStatus::ErrorNonexistentProperty),
819 _name(std::nullopt),
820 _semantic(std::nullopt),
821 _description(std::nullopt),
822 _offset(std::nullopt),
823 _scale(std::nullopt),
824 _max(std::nullopt),
825 _min(std::nullopt),
826 _required(false),
827 _noData(std::nullopt),
828 _defaultValue(std::nullopt),
829 _propertyType(PropertyType::Invalid) {}
830
834 PropertyView(const ClassProperty& classProperty)
835 : _status(validatePropertyType<ElementType>(classProperty)),
836 _name(classProperty.name),
837 _semantic(classProperty.semantic),
838 _description(classProperty.description),
839 _offset(std::nullopt),
840 _scale(std::nullopt),
841 _max(std::nullopt),
842 _min(std::nullopt),
843 _required(classProperty.required),
844 _noData(std::nullopt),
845 _defaultValue(std::nullopt),
846 _propertyType(convertStringToPropertyType(classProperty.type)) {
848 return;
849 }
850
851 if (!classProperty.normalized) {
852 _status = PropertyViewStatus::ErrorNormalizationMismatch;
853 }
854
855 getNumericPropertyValues(classProperty);
857 return;
858 }
859
860 if (classProperty.noData) {
861 if (!_required) {
862 // "noData" should not be defined if the property is required.
863 _noData = getValue<ElementType>(*classProperty.noData);
864 }
865 if (!_noData) {
866 // The value was specified but something went wrong.
868 return;
869 }
870 }
871
872 if (classProperty.defaultProperty) {
873 // default value should not be defined if the property is required.
874 if (!_required) {
875 _defaultValue =
876 getValue<NormalizedType>(*classProperty.defaultProperty);
877 }
878 if (!_defaultValue) {
879 // The value was specified but something went wrong.
881 return;
882 }
883 }
884 }
885
886protected:
893 : _status(status),
894 _name(std::nullopt),
895 _semantic(std::nullopt),
896 _description(std::nullopt),
897 _offset(std::nullopt),
898 _scale(std::nullopt),
899 _max(std::nullopt),
900 _min(std::nullopt),
901 _required(false),
902 _noData(std::nullopt),
903 _defaultValue(std::nullopt),
904 _propertyType(PropertyType::Invalid) {}
905
911 const ClassProperty& classProperty,
912 const PropertyTableProperty& property)
913 : PropertyView(classProperty) {
915 return;
916 }
917
918 // If the property has its own values, override the class-provided values.
919 getNumericPropertyValues(property);
920 }
921
927 const ClassProperty& classProperty,
928 const PropertyTextureProperty& property)
929 : PropertyView(classProperty) {
931 return;
932 }
933
934 // If the property has its own values, override the class-provided values.
935 getNumericPropertyValues(property);
936 }
937
943 const ClassProperty& classProperty,
944 const PropertyAttributeProperty& property)
945 : PropertyView(classProperty) {
947 return;
948 }
949
950 // If the property has its own values, override the class-provided values.
951 getNumericPropertyValues(property);
952 }
953
954public:
958 PropertyViewStatusType status() const noexcept { return _status; }
959
963 const std::optional<std::string>& name() const noexcept { return _name; }
964
968 const std::optional<std::string>& semantic() const noexcept {
969 return _semantic;
970 }
971
975 const std::optional<std::string>& description() const noexcept {
976 return _description;
977 }
978
982 int64_t arrayCount() const noexcept { return 0; }
983
987 bool normalized() const noexcept { return true; }
988
992 std::optional<NormalizedType> offset() const noexcept { return _offset; }
993
997 std::optional<NormalizedType> scale() const noexcept { return _scale; }
998
1002 std::optional<NormalizedType> max() const noexcept { return _max; }
1003
1007 std::optional<NormalizedType> min() const noexcept { return _min; }
1008
1012 bool required() const noexcept { return _required; }
1013
1017 std::optional<ElementType> noData() const noexcept { return _noData; }
1018
1022 std::optional<NormalizedType> defaultValue() const noexcept {
1023 return _defaultValue;
1024 }
1025
1030 PropertyType propertyType() const noexcept { return _propertyType; }
1031
1032protected:
1035
1036private:
1037 std::optional<std::string> _name;
1038 std::optional<std::string> _semantic;
1039 std::optional<std::string> _description;
1040
1041 std::optional<NormalizedType> _offset;
1042 std::optional<NormalizedType> _scale;
1043 std::optional<NormalizedType> _max;
1044 std::optional<NormalizedType> _min;
1045
1046 bool _required;
1047 std::optional<ElementType> _noData;
1048 std::optional<NormalizedType> _defaultValue;
1049 PropertyType _propertyType;
1050
1060 template <typename T>
1061 static std::optional<T> getValue(const CesiumUtility::JsonValue& jsonValue) {
1062 if constexpr (IsMetadataScalar<T>::value) {
1063 return getScalar<T>(jsonValue);
1064 }
1065
1066 if constexpr (IsMetadataVecN<T>::value) {
1067 return getVecN<T>(jsonValue);
1068 }
1069
1070 if constexpr (IsMetadataMatN<T>::value) {
1071 return getMatN<T>(jsonValue);
1072 }
1073 }
1074
1075 using PropertyDefinitionType = std::variant<
1080
1085 void getNumericPropertyValues(const PropertyDefinitionType& inProperty) {
1086 std::visit(
1087 [this](auto property) {
1088 if (property.offset) {
1089 _offset = getValue<NormalizedType>(*property.offset);
1090 if (!_offset) {
1091 // The value was specified but something went wrong.
1093 return;
1094 }
1095 }
1096
1097 if (property.scale) {
1098 _scale = getValue<NormalizedType>(*property.scale);
1099 if (!_scale) {
1100 // The value was specified but something went wrong.
1101 _status = PropertyViewStatus::ErrorInvalidScale;
1102 return;
1103 }
1104 }
1105
1106 if (property.max) {
1107 _max = getValue<NormalizedType>(*property.max);
1108 if (!_scale) {
1109 // The value was specified but something went wrong.
1110 _status = PropertyViewStatus::ErrorInvalidMax;
1111 return;
1112 }
1113 }
1114
1115 if (property.min) {
1116 _min = getValue<NormalizedType>(*property.min);
1117 if (!_scale) {
1118 // The value was specified but something went wrong.
1119 _status = PropertyViewStatus::ErrorInvalidMin;
1120 return;
1121 }
1122 }
1123 },
1124 inProperty);
1125 }
1126};
1127
1132template <> class PropertyView<bool> {
1133public:
1138 : _status(PropertyViewStatus::ErrorNonexistentProperty),
1139 _name(std::nullopt),
1140 _semantic(std::nullopt),
1141 _description(std::nullopt),
1142 _required(false),
1143 _defaultValue(std::nullopt) {}
1144
1148 PropertyView(const ClassProperty& classProperty)
1149 : _status(validatePropertyType<bool>(classProperty)),
1150 _name(classProperty.name),
1151 _semantic(classProperty.semantic),
1152 _description(classProperty.description),
1153 _required(classProperty.required),
1154 _defaultValue(std::nullopt) {
1156 return;
1157 }
1158
1159 if (classProperty.defaultProperty) {
1160 if (!_required) {
1161 _defaultValue = getBooleanValue(*classProperty.defaultProperty);
1162 }
1163
1164 if (!_defaultValue) {
1165 // The value was specified but something went wrong.
1167 return;
1168 }
1169 }
1170 }
1171
1172protected:
1179 : _status(status),
1180 _name(std::nullopt),
1181 _semantic(std::nullopt),
1182 _description(std::nullopt),
1183 _required(false),
1184 _defaultValue(std::nullopt) {}
1185
1191 const ClassProperty& classProperty,
1192 const PropertyTableProperty& /*property*/,
1193 const CesiumGltf::Enum* /*pEnumDefinition*/)
1194 : PropertyView(classProperty) {}
1195
1196public:
1200 PropertyViewStatusType status() const noexcept { return _status; }
1201
1205 const std::optional<std::string>& name() const noexcept { return _name; }
1206
1210 const std::optional<std::string>& semantic() const noexcept {
1211 return _semantic;
1212 }
1213
1217 const std::optional<std::string>& description() const noexcept {
1218 return _description;
1219 }
1220
1224 int64_t arrayCount() const noexcept { return 0; }
1225
1229 bool normalized() const noexcept { return false; }
1230
1234 std::optional<bool> offset() const noexcept { return std::nullopt; }
1235
1239 std::optional<bool> scale() const noexcept { return std::nullopt; }
1240
1244 std::optional<bool> max() const noexcept { return std::nullopt; }
1245
1249 std::optional<bool> min() const noexcept { return std::nullopt; }
1250
1254 bool required() const noexcept { return _required; }
1255
1259 std::optional<bool> noData() const noexcept { return std::nullopt; }
1260
1264 std::optional<bool> defaultValue() const noexcept { return _defaultValue; }
1265
1271
1272protected:
1275
1276private:
1277 std::optional<std::string> _name;
1278 std::optional<std::string> _semantic;
1279 std::optional<std::string> _description;
1280
1281 bool _required;
1282 std::optional<bool> _defaultValue;
1283
1284 static std::optional<bool>
1285 getBooleanValue(const CesiumUtility::JsonValue& value) {
1286 if (!value.isBool()) {
1287 return std::nullopt;
1288 }
1289
1290 return value.getBool();
1291 }
1292};
1293
1298template <> class PropertyView<std::string_view> {
1299public:
1304 : _status(PropertyViewStatus::ErrorNonexistentProperty),
1305 _name(std::nullopt),
1306 _semantic(std::nullopt),
1307 _description(std::nullopt),
1308 _required(false),
1309 _noData(std::nullopt),
1310 _defaultValue(std::nullopt) {}
1311
1315 PropertyView(const ClassProperty& classProperty)
1316 : _status(validatePropertyType<std::string_view>(classProperty)),
1317 _name(classProperty.name),
1318 _semantic(classProperty.semantic),
1319 _description(classProperty.description),
1320 _required(classProperty.required),
1321 _noData(std::nullopt),
1322 _defaultValue(std::nullopt) {
1324 return;
1325 }
1326
1327 if (classProperty.noData) {
1328 if (!_required) {
1329 _noData = getStringValue(*classProperty.noData);
1330 }
1331
1332 if (!_noData) {
1333 // The value was specified but something went wrong.
1335 return;
1336 }
1337 }
1338
1339 if (classProperty.defaultProperty) {
1340 if (!_required) {
1341 _defaultValue = getStringValue(*classProperty.defaultProperty);
1342 }
1343
1344 if (!_defaultValue) {
1345 // The value was specified but something went wrong.
1347 return;
1348 }
1349 }
1350 }
1351
1352protected:
1359 : _status(status),
1360 _name(std::nullopt),
1361 _semantic(std::nullopt),
1362 _description(std::nullopt),
1363 _required(false),
1364 _noData(std::nullopt),
1365 _defaultValue(std::nullopt) {}
1366
1372 const ClassProperty& classProperty,
1373 const PropertyTableProperty& /*property*/,
1374 const CesiumGltf::Enum* /*pEnumDefinition*/)
1375 : PropertyView(classProperty) {}
1376
1377public:
1381 PropertyViewStatusType status() const noexcept { return _status; }
1382
1386 const std::optional<std::string>& name() const noexcept { return _name; }
1387
1391 const std::optional<std::string>& semantic() const noexcept {
1392 return _semantic;
1393 }
1394
1398 const std::optional<std::string>& description() const noexcept {
1399 return _description;
1400 }
1401
1405 int64_t arrayCount() const noexcept { return 0; }
1406
1410 bool normalized() const noexcept { return false; }
1411
1415 std::optional<std::string_view> offset() const noexcept {
1416 return std::nullopt;
1417 }
1418
1422 std::optional<std::string_view> scale() const noexcept {
1423 return std::nullopt;
1424 }
1425
1429 std::optional<std::string_view> max() const noexcept { return std::nullopt; }
1430
1434 std::optional<std::string_view> min() const noexcept { return std::nullopt; }
1435
1439 bool required() const noexcept { return _required; }
1440
1444 std::optional<std::string_view> noData() const noexcept {
1445 if (_noData)
1446 return std::string_view(*_noData);
1447
1448 return std::nullopt;
1449 }
1450
1454 std::optional<std::string_view> defaultValue() const noexcept {
1455 if (_defaultValue)
1456 return std::string_view(*_defaultValue);
1457
1458 return std::nullopt;
1459 }
1460
1466
1467protected:
1470
1471private:
1472 std::optional<std::string> _name;
1473 std::optional<std::string> _semantic;
1474 std::optional<std::string> _description;
1475
1476 bool _required;
1477 std::optional<std::string> _noData;
1478 std::optional<std::string> _defaultValue;
1479
1480 static std::optional<std::string>
1481 getStringValue(const CesiumUtility::JsonValue& value) {
1482 if (!value.isString()) {
1483 return std::nullopt;
1484 }
1485
1486 return std::string(value.getString().c_str());
1487 }
1488};
1489
1503template <typename ElementType>
1504class PropertyView<PropertyArrayView<ElementType>, false> {
1505public:
1510 : _status(PropertyViewStatus::ErrorNonexistentProperty),
1511 _name(std::nullopt),
1512 _semantic(std::nullopt),
1513 _description(std::nullopt),
1514 _count(0),
1515 _offset(),
1516 _scale(),
1517 _max(),
1518 _min(),
1519 _required(false),
1520 _noData(),
1521 _defaultValue(),
1522 _propertyType(PropertyType::Invalid) {}
1523
1527 PropertyView(const ClassProperty& classProperty)
1528 : PropertyView(classProperty, nullptr) {}
1529
1535 const ClassProperty& classProperty,
1536 const CesiumGltf::Enum* pEnumDefinition)
1538 classProperty,
1539 pEnumDefinition)),
1540 _name(classProperty.name),
1541 _semantic(classProperty.semantic),
1542 _description(classProperty.description),
1543 _count(classProperty.count ? *classProperty.count : 0),
1544 _offset(),
1545 _scale(),
1546 _max(),
1547 _min(),
1548 _required(classProperty.required),
1549 _noData(),
1550 _defaultValue(),
1551 _propertyType(convertStringToPropertyType(classProperty.type)) {
1553 return;
1554 }
1555
1556 if (classProperty.normalized) {
1557 _status = PropertyViewStatus::ErrorNormalizationMismatch;
1558 return;
1559 }
1560
1561 if (classProperty.type != ClassProperty::Type::ENUM) {
1562 getNumericPropertyValues(classProperty);
1563 }
1564
1566 return;
1567 }
1568
1569 if (classProperty.noData) {
1570 if (!this->_required && this->_propertyType == PropertyType::Enum) {
1571 CESIUM_ASSERT(pEnumDefinition != nullptr);
1572 if constexpr (IsMetadataInteger<ElementType>::value) {
1573 this->_noData =
1574 getEnumArrayValue(*classProperty.noData, *pEnumDefinition);
1575 }
1576 } else if (!this->_required) {
1577 this->_noData = getArrayValue(*classProperty.noData);
1578 }
1579
1580 if (this->_noData.size() == 0) {
1581 // The value was specified but something went wrong.
1582 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
1583 return;
1584 }
1585 }
1586
1587 if (classProperty.defaultProperty) {
1588 if (!this->_required && this->_propertyType == PropertyType::Enum) {
1589 CESIUM_ASSERT(pEnumDefinition != nullptr);
1590 if constexpr (IsMetadataInteger<ElementType>::value) {
1591 this->_defaultValue = getEnumArrayValue(
1592 *classProperty.defaultProperty,
1593 *pEnumDefinition);
1594 }
1595 } else if (!this->_required) {
1596 this->_defaultValue = getArrayValue(*classProperty.defaultProperty);
1597 }
1598
1599 if (this->_defaultValue.size() == 0) {
1600 // The value was specified but something went wrong.
1601 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
1602 return;
1603 }
1604 }
1605 }
1606
1607protected:
1614 : _status(status),
1615 _name(std::nullopt),
1616 _semantic(std::nullopt),
1617 _description(std::nullopt),
1618 _count(0),
1619 _offset(),
1620 _scale(),
1621 _max(),
1622 _min(),
1623 _required(false),
1624 _noData(),
1625 _defaultValue(),
1626 _propertyType(PropertyType::Invalid) {}
1627
1633 const ClassProperty& classProperty,
1634 const PropertyTableProperty& property,
1635 const CesiumGltf::Enum* pEnumDefinition = nullptr)
1636 : PropertyView(classProperty, pEnumDefinition) {
1638 return;
1639 }
1640
1641 // If the property has its own values, override the class-provided values.
1642 if (classProperty.type != ClassProperty::Type::ENUM) {
1643 getNumericPropertyValues(property);
1644 }
1645 }
1646
1652 const ClassProperty& classProperty,
1653 const PropertyTextureProperty& property,
1654 const CesiumGltf::Enum* pEnumDefinition = nullptr)
1655 : PropertyView(classProperty, pEnumDefinition) {
1657 return;
1658 }
1659
1660 // If the property has its own values, override the class-provided values.
1661 if (classProperty.type != ClassProperty::Type::ENUM) {
1662 getNumericPropertyValues(property);
1663 }
1664 }
1665
1666public:
1670 PropertyViewStatusType status() const noexcept { return _status; }
1671
1675 const std::optional<std::string>& name() const noexcept { return _name; }
1676
1680 const std::optional<std::string>& semantic() const noexcept {
1681 return _semantic;
1682 }
1683
1687 const std::optional<std::string>& description() const noexcept {
1688 return _description;
1689 }
1690
1694 int64_t arrayCount() const noexcept { return _count; }
1695
1699 bool normalized() const noexcept { return false; }
1700
1704 std::optional<PropertyArrayView<ElementType>> offset() const noexcept {
1705 return this->_offset.size() > 0 ? std::make_optional(this->_offset.view())
1706 : std::nullopt;
1707 }
1708
1712 std::optional<PropertyArrayView<ElementType>> scale() const noexcept {
1713 return this->_scale.size() > 0 ? std::make_optional(this->_scale.view())
1714 : std::nullopt;
1715 }
1716
1720 std::optional<PropertyArrayView<ElementType>> max() const noexcept {
1721 return this->_max.size() > 0 ? std::make_optional(this->_max.view())
1722 : std::nullopt;
1723 }
1724
1728 std::optional<PropertyArrayView<ElementType>> min() const noexcept {
1729 return this->_min.size() > 0 ? std::make_optional(this->_min.view())
1730 : std::nullopt;
1731 }
1732
1736 bool required() const noexcept { return _required; }
1737
1741 std::optional<PropertyArrayView<ElementType>> noData() const noexcept {
1742 return this->_noData.size() > 0 ? std::make_optional(this->_noData.view())
1743 : std::nullopt;
1744 }
1745
1749 std::optional<PropertyArrayView<ElementType>> defaultValue() const noexcept {
1750 return this->_defaultValue.size() > 0
1751 ? std::make_optional(this->_defaultValue.view())
1752 : std::nullopt;
1753 }
1754
1759 PropertyType propertyType() const noexcept { return _propertyType; }
1760
1761protected:
1764
1765private:
1766 std::optional<std::string> _name;
1767 std::optional<std::string> _semantic;
1768 std::optional<std::string> _description;
1769
1770 int64_t _count;
1771
1776
1777 bool _required;
1779 PropertyArrayCopy<ElementType> _defaultValue;
1780 PropertyType _propertyType;
1781
1782 using PropertyDefinitionType = std::
1783 variant<ClassProperty, PropertyTableProperty, PropertyTextureProperty>;
1784 void getNumericPropertyValues(const PropertyDefinitionType& inProperty) {
1785 std::visit(
1786 [this](auto property) {
1787 bool isFixedSizeArray = this->_count > 0;
1788
1789 if (property.offset) {
1790 // Only floating point types can specify an offset.
1794 if (isFixedSizeArray) {
1795 this->_offset = getArrayValue(*property.offset);
1796 if (this->_offset.size() == this->_count) {
1797 break;
1798 }
1799 }
1800 // If it does not break here, something went wrong.
1801 [[fallthrough]];
1802 default:
1804 return;
1805 }
1806 }
1807
1808 if (property.scale) {
1809 // Only floating point types can specify a scale.
1813 if (isFixedSizeArray) {
1814 this->_scale = getArrayValue(*property.scale);
1815 if (this->_scale.size() == this->_count) {
1816 break;
1817 }
1818 }
1819 // If it does not break here, something went wrong.
1820 [[fallthrough]];
1821 default:
1823 return;
1824 }
1825 }
1826
1827 if (property.max) {
1828 if (isFixedSizeArray) {
1829 this->_max = getArrayValue(*property.max);
1830 }
1831 if (!isFixedSizeArray || this->_max.size() != this->_count) {
1832 // The value was specified but something went wrong.
1834 return;
1835 }
1836 }
1837
1838 if (property.min) {
1839 if (isFixedSizeArray) {
1840 this->_min = getArrayValue(*property.min);
1841 }
1842 if (!isFixedSizeArray || this->_min.size() != this->_count) {
1843 // The value was specified but something went wrong.
1845 return;
1846 }
1847 }
1848 },
1849 inProperty);
1850 }
1851
1853 getArrayValue(const CesiumUtility::JsonValue& jsonValue) {
1854 if (!jsonValue.isArray()) {
1856 }
1857
1858 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
1859 std::vector<ElementType> values(array.size());
1860
1861 if constexpr (IsMetadataScalar<ElementType>::value) {
1862 for (size_t i = 0; i < array.size(); i++) {
1863 std::optional<ElementType> maybeValue =
1864 getScalar<ElementType>(array[i]);
1865 if (!maybeValue.has_value()) {
1866 return PropertyArrayCopy<ElementType>();
1867 }
1868
1869 values[i] = *maybeValue;
1870 }
1871 }
1872 if constexpr (IsMetadataVecN<ElementType>::value) {
1873 for (size_t i = 0; i < array.size(); i++) {
1874 std::optional<ElementType> maybeValue = getVecN<ElementType>(array[i]);
1875 if (!maybeValue.has_value()) {
1876 return PropertyArrayCopy<ElementType>();
1877 }
1878
1879 values[i] = *maybeValue;
1880 }
1881 }
1882
1883 if constexpr (IsMetadataMatN<ElementType>::value) {
1884 for (size_t i = 0; i < array.size(); i++) {
1885 std::optional<ElementType> maybeValue = getMatN<ElementType>(array[i]);
1886 if (!maybeValue.has_value()) {
1887 return PropertyArrayCopy<ElementType>();
1888 }
1889
1890 values[i] = *maybeValue;
1891 }
1892 }
1893
1894 return PropertyArrayCopy<ElementType>(values);
1895 }
1896
1897 static PropertyArrayCopy<ElementType> getEnumArrayValue(
1898 const CesiumUtility::JsonValue& jsonValue,
1899 const CesiumGltf::Enum& enumDefinition) {
1900 if (!jsonValue.isArray()) {
1901 return PropertyArrayCopy<ElementType>();
1902 }
1903
1904 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
1905 std::vector<ElementType> values(array.size());
1906
1907 for (size_t i = 0; i < array.size(); i++) {
1908 if (!array[i].isString()) {
1909 return PropertyArrayCopy<ElementType>();
1910 }
1911
1912 // default and noData values for enums contain the name of the enum as a
1913 // string
1914 CesiumUtility::JsonValue::String str = array[i].getString();
1915 auto foundValue = std::find_if(
1916 enumDefinition.values.begin(),
1917 enumDefinition.values.end(),
1918 [&str](const CesiumGltf::EnumValue& enumValue) {
1919 return enumValue.name == str;
1920 });
1921
1922 if (foundValue == enumDefinition.values.end()) {
1923 return PropertyArrayCopy<ElementType>();
1924 }
1925
1926 values[i] = static_cast<ElementType>(foundValue->value);
1927 }
1928
1929 return PropertyArrayCopy<ElementType>(values);
1930 }
1931};
1932
1946template <typename ElementType>
1947class PropertyView<PropertyArrayView<ElementType>, true> {
1948private:
1949 using NormalizedType = typename TypeToNormalizedType<ElementType>::type;
1950
1951public:
1956 : _status(PropertyViewStatus::ErrorNonexistentProperty),
1957 _name(std::nullopt),
1958 _semantic(std::nullopt),
1959 _description(std::nullopt),
1960 _count(0),
1961 _offset(),
1962 _scale(),
1963 _max(),
1964 _min(),
1965 _required(false),
1966 _noData(),
1967 _defaultValue(),
1968 _propertyType(PropertyType::Invalid) {}
1969
1973 PropertyView(const ClassProperty& classProperty)
1975 classProperty)),
1976 _name(classProperty.name),
1977 _semantic(classProperty.semantic),
1978 _description(classProperty.description),
1979 _count(classProperty.count ? *classProperty.count : 0),
1980 _offset(),
1981 _scale(),
1982 _max(),
1983 _min(),
1984 _required(classProperty.required),
1985 _noData(),
1986 _defaultValue(),
1987 _propertyType(convertStringToPropertyType(classProperty.type)) {
1989 return;
1990 }
1991
1992 if (!classProperty.normalized) {
1993 _status = PropertyViewStatus::ErrorNormalizationMismatch;
1994 return;
1995 }
1996
1997 getNumericPropertyValues(classProperty);
1999 return;
2000 }
2001
2002 if (classProperty.noData) {
2003 if (!this->_required) {
2004 this->_noData = getArrayValue<ElementType>(*classProperty.noData);
2005 }
2006
2007 if (this->_noData.size() == 0) {
2008 // The value was specified but something went wrong.
2009 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
2010 return;
2011 }
2012 }
2013
2014 if (classProperty.defaultProperty) {
2015 if (!this->_required) {
2016 this->_defaultValue =
2017 getArrayValue<NormalizedType>(*classProperty.defaultProperty);
2018 }
2019
2020 if (this->_defaultValue.size() == 0) {
2021 // The value was specified but something went wrong.
2022 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2023 return;
2024 }
2025 }
2026 }
2027
2028protected:
2035 : _status(status),
2036 _name(std::nullopt),
2037 _semantic(std::nullopt),
2038 _description(std::nullopt),
2039 _count(0),
2040 _offset(),
2041 _scale(),
2042 _max(),
2043 _min(),
2044 _required(false),
2045 _noData(),
2046 _defaultValue(),
2047 _propertyType(PropertyType::Invalid) {}
2048
2054 const ClassProperty& classProperty,
2055 const PropertyTableProperty& property)
2056 : PropertyView(classProperty) {
2058 return;
2059 }
2060
2061 // If the property has its own values, override the class-provided values.
2062 getNumericPropertyValues(property);
2063 }
2064
2070 const ClassProperty& classProperty,
2071 const PropertyTextureProperty& property)
2072 : PropertyView(classProperty) {
2074 return;
2075 }
2076
2077 // If the property has its own values, override the class-provided values.
2078 getNumericPropertyValues(property);
2079 }
2080
2081public:
2085 PropertyViewStatusType status() const noexcept { return _status; }
2086
2090 const std::optional<std::string>& name() const noexcept { return _name; }
2091
2095 const std::optional<std::string>& semantic() const noexcept {
2096 return _semantic;
2097 }
2098
2102 const std::optional<std::string>& description() const noexcept {
2103 return _description;
2104 }
2105
2109 int64_t arrayCount() const noexcept { return _count; }
2110
2114 bool normalized() const noexcept { return true; }
2115
2119 std::optional<PropertyArrayView<NormalizedType>> offset() const noexcept {
2120 return this->_offset.size() > 0 ? std::make_optional(this->_offset.view())
2121 : std::nullopt;
2122 }
2123
2127 std::optional<PropertyArrayView<NormalizedType>> scale() const noexcept {
2128 return this->_scale.size() > 0 ? std::make_optional(this->_scale.view())
2129 : std::nullopt;
2130 }
2131
2135 std::optional<PropertyArrayView<NormalizedType>> max() const noexcept {
2136 return this->_max.size() > 0 ? std::make_optional(this->_max.view())
2137 : std::nullopt;
2138 }
2139
2143 std::optional<PropertyArrayView<NormalizedType>> min() const noexcept {
2144 return this->_min.size() > 0 ? std::make_optional(this->_min.view())
2145 : std::nullopt;
2146 }
2147
2151 bool required() const noexcept { return _required; }
2152
2156 std::optional<PropertyArrayView<ElementType>> noData() const noexcept {
2157 return this->_noData.size() > 0 ? std::make_optional(this->_noData.view())
2158 : std::nullopt;
2159 }
2160
2164 std::optional<PropertyArrayView<NormalizedType>>
2165 defaultValue() const noexcept {
2166 return this->_defaultValue.size() > 0
2167 ? std::make_optional(this->_defaultValue.view())
2168 : std::nullopt;
2169 }
2170
2175 PropertyType propertyType() const noexcept { return _propertyType; }
2176
2177protected:
2180
2181private:
2182 std::optional<std::string> _name;
2183 std::optional<std::string> _semantic;
2184 std::optional<std::string> _description;
2185
2186 int64_t _count;
2187
2192
2193 bool _required;
2196 PropertyType _propertyType;
2197
2198 using PropertyDefinitionType = std::
2199 variant<ClassProperty, PropertyTableProperty, PropertyTextureProperty>;
2200 void getNumericPropertyValues(const PropertyDefinitionType& inProperty) {
2201 std::visit(
2202 [this](auto property) {
2203 bool isFixedSizeArray = this->_count > 0;
2204 if (property.offset) {
2205 if (isFixedSizeArray) {
2206 this->_offset = getArrayValue<NormalizedType>(*property.offset);
2207 }
2208 if (!isFixedSizeArray || this->_offset.size() != this->_count) {
2209 // The value was specified but something went wrong.
2211 return;
2212 }
2213 }
2214
2215 if (property.scale) {
2216 if (isFixedSizeArray) {
2217 this->_scale = getArrayValue<NormalizedType>(*property.scale);
2218 }
2219 if (!isFixedSizeArray || this->_scale.size() != this->_count) {
2220 // The value was specified but something went wrong.
2222 return;
2223 }
2224 }
2225
2226 if (property.max) {
2227 if (isFixedSizeArray) {
2228 this->_max = getArrayValue<NormalizedType>(*property.max);
2229 }
2230 if (!isFixedSizeArray || this->_max.size() != this->_count) {
2231 // The value was specified but something went wrong.
2233 return;
2234 }
2235 }
2236
2237 if (property.min) {
2238 if (isFixedSizeArray) {
2239 this->_min = getArrayValue<NormalizedType>(*property.min);
2240 }
2241 if (!isFixedSizeArray || this->_min.size() != this->_count) {
2242 // The value was specified but something went wrong.
2244 return;
2245 }
2246 }
2247 },
2248 inProperty);
2249 }
2250
2251 template <typename T>
2253 getArrayValue(const CesiumUtility::JsonValue& jsonValue) {
2254 if (!jsonValue.isArray()) {
2255 return PropertyArrayCopy<T>();
2256 }
2257
2258 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
2259 std::vector<T> values(array.size());
2260
2261 if constexpr (IsMetadataScalar<T>::value) {
2262 for (size_t i = 0; i < array.size(); i++) {
2263 std::optional<T> maybeElement = getScalar<T>(array[i]);
2264 if (!maybeElement.has_value()) {
2265 return PropertyArrayCopy<T>();
2266 }
2267 values[i] = *maybeElement;
2268 }
2269 }
2270
2271 if constexpr (IsMetadataVecN<T>::value) {
2272 for (size_t i = 0; i < array.size(); i++) {
2273 std::optional<T> maybeElement = getVecN<T>(array[i]);
2274 if (!maybeElement.has_value()) {
2275 return PropertyArrayCopy<T>();
2276 }
2277 values[i] = *maybeElement;
2278 }
2279 }
2280
2281 if constexpr (IsMetadataMatN<T>::value) {
2282 for (size_t i = 0; i < array.size(); i++) {
2283 std::optional<T> maybeElement = getMatN<T>(array[i]);
2284 if (!maybeElement.has_value()) {
2285 return PropertyArrayCopy<T>();
2286 }
2287 values[i] = *maybeElement;
2288 }
2289 }
2290
2291 return PropertyArrayCopy<T>(values);
2292 }
2293};
2294
2299template <> class PropertyView<PropertyArrayView<bool>> {
2300public:
2305 : _status(PropertyViewStatus::ErrorNonexistentProperty),
2306 _name(std::nullopt),
2307 _semantic(std::nullopt),
2308 _description(std::nullopt),
2309 _count(0),
2310 _required(false),
2311 _defaultValue() {}
2312
2316 PropertyView(const ClassProperty& classProperty)
2317 : _status(
2318 validateArrayPropertyType<PropertyArrayView<bool>>(classProperty)),
2319 _name(classProperty.name),
2320 _semantic(classProperty.semantic),
2321 _description(classProperty.description),
2322 _count(classProperty.count ? *classProperty.count : 0),
2323 _required(classProperty.required),
2324 _defaultValue() {
2326 return;
2327 }
2328
2329 if (classProperty.defaultProperty) {
2330 if (!this->_required) {
2331 this->_defaultValue =
2332 getBooleanArrayValue(*classProperty.defaultProperty);
2333 }
2334
2335 if (this->_defaultValue.size() == 0 ||
2336 (this->_count > 0 && this->_defaultValue.size() != this->_count)) {
2337 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2338 return;
2339 }
2340 }
2341 }
2342
2343protected:
2350 : _status(status),
2351 _name(std::nullopt),
2352 _semantic(std::nullopt),
2353 _description(std::nullopt),
2354 _count(0),
2355 _required(false),
2356 _defaultValue() {}
2357
2363 const ClassProperty& classProperty,
2364 const PropertyTableProperty& /*property*/,
2365 const CesiumGltf::Enum* /*pEnumDefinition*/)
2366 : PropertyView(classProperty) {}
2367
2368public:
2372 PropertyViewStatusType status() const noexcept { return _status; }
2373
2377 const std::optional<std::string>& name() const noexcept { return _name; }
2378
2382 const std::optional<std::string>& semantic() const noexcept {
2383 return _semantic;
2384 }
2385
2389 const std::optional<std::string>& description() const noexcept {
2390 return _description;
2391 }
2392
2396 int64_t arrayCount() const noexcept { return _count; }
2397
2401 bool normalized() const noexcept { return false; }
2402
2406 std::optional<PropertyArrayView<bool>> offset() const noexcept {
2407 return std::nullopt;
2408 }
2409
2413 std::optional<PropertyArrayView<bool>> scale() const noexcept {
2414 return std::nullopt;
2415 }
2416
2420 std::optional<PropertyArrayView<bool>> max() const noexcept {
2421 return std::nullopt;
2422 }
2423
2427 std::optional<PropertyArrayView<bool>> min() const noexcept {
2428 return std::nullopt;
2429 }
2430
2434 bool required() const noexcept { return _required; }
2435
2439 std::optional<PropertyArrayView<bool>> noData() const noexcept {
2440 return std::nullopt;
2441 }
2442
2446 std::optional<PropertyArrayView<bool>> defaultValue() const noexcept {
2447 return this->_defaultValue.size() > 0
2448 ? std::make_optional(this->_defaultValue.view())
2449 : std::nullopt;
2450 }
2451
2457
2458protected:
2461
2462private:
2463 std::optional<std::string> _name;
2464 std::optional<std::string> _semantic;
2465 std::optional<std::string> _description;
2466
2467 int64_t _count;
2468 bool _required;
2469
2470 PropertyArrayCopy<bool> _defaultValue;
2471
2473 getBooleanArrayValue(const CesiumUtility::JsonValue& jsonValue) {
2474 if (!jsonValue.isArray()) {
2475 return PropertyArrayCopy<bool>();
2476 }
2477 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
2478
2479 std::vector<bool> values(array.size());
2480 for (size_t i = 0; i < array.size(); i++) {
2481 if (!array[i].isBool()) {
2482 // The entire array is invalidated; return.
2483 return PropertyArrayCopy<bool>();
2484 }
2485 values[i] = array[i].getBool();
2486 }
2487 return values;
2488 }
2489};
2490
2495template <> class PropertyView<PropertyArrayView<std::string_view>> {
2496public:
2501 : _status(PropertyViewStatus::ErrorNonexistentProperty),
2502 _name(std::nullopt),
2503 _semantic(std::nullopt),
2504 _description(std::nullopt),
2505 _count(0),
2506 _required(false),
2507 _noData(),
2508 _defaultValue() {}
2509
2513 PropertyView(const ClassProperty& classProperty)
2515 classProperty)),
2516 _name(classProperty.name),
2517 _semantic(classProperty.semantic),
2518 _description(classProperty.description),
2519 _count(classProperty.count ? *classProperty.count : 0),
2520 _required(classProperty.required),
2521 _noData(),
2522 _defaultValue() {
2524 return;
2525 }
2526
2527 if (classProperty.noData) {
2528 if (!this->_required) {
2529 this->_noData = getStringArrayValue(*classProperty.noData);
2530 }
2531
2532 if (this->_noData.size() == 0 ||
2533 (this->_count > 0 && this->_noData.size() != this->_count)) {
2534 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
2535 return;
2536 }
2537 }
2538
2539 if (classProperty.defaultProperty) {
2540 if (!this->_required) {
2541 this->_defaultValue =
2542 getStringArrayValue(*classProperty.defaultProperty);
2543 }
2544
2545 if (this->_defaultValue.size() == 0 ||
2546 (this->_count > 0 && this->_defaultValue.size() != this->_count)) {
2547 // The value was specified but something went wrong.
2548 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2549 return;
2550 }
2551 }
2552 }
2553
2554protected:
2561 : _status(status),
2562 _name(std::nullopt),
2563 _semantic(std::nullopt),
2564 _description(std::nullopt),
2565 _count(0),
2566 _required(false),
2567 _noData(),
2568 _defaultValue() {}
2569
2575 const ClassProperty& classProperty,
2576 const PropertyTableProperty& /*property*/,
2577 const CesiumGltf::Enum* /*pEnumDefinition*/)
2578 : PropertyView(classProperty) {}
2579
2580public:
2584 PropertyViewStatusType status() const noexcept { return _status; }
2585
2589 const std::optional<std::string>& name() const noexcept { return _name; }
2590
2594 const std::optional<std::string>& semantic() const noexcept {
2595 return _semantic;
2596 }
2597
2601 const std::optional<std::string>& description() const noexcept {
2602 return _description;
2603 }
2604
2608 int64_t arrayCount() const noexcept { return _count; }
2609
2613 bool normalized() const noexcept { return false; }
2614
2618 std::optional<PropertyArrayView<std::string_view>> offset() const noexcept {
2619 return std::nullopt;
2620 }
2621
2625 std::optional<PropertyArrayView<std::string_view>> scale() const noexcept {
2626 return std::nullopt;
2627 }
2628
2632 std::optional<PropertyArrayView<std::string_view>> max() const noexcept {
2633 return std::nullopt;
2634 }
2635
2639 std::optional<PropertyArrayView<std::string_view>> min() const noexcept {
2640 return std::nullopt;
2641 }
2642
2646 bool required() const noexcept { return _required; }
2647
2651 std::optional<PropertyArrayView<std::string_view>> noData() const noexcept {
2652 return this->_noData.size() > 0 ? std::make_optional(this->_noData.view())
2653 : std::nullopt;
2654 }
2655
2659 std::optional<PropertyArrayView<std::string_view>>
2660 defaultValue() const noexcept {
2661 return this->_defaultValue.size() > 0
2662 ? std::make_optional(this->_defaultValue.view())
2663 : std::nullopt;
2664 }
2665
2671
2672protected:
2675
2676private:
2677 std::optional<std::string> _name;
2678 std::optional<std::string> _semantic;
2679 std::optional<std::string> _description;
2680
2681 int64_t _count;
2682 bool _required;
2683
2686
2688 getStringArrayValue(const CesiumUtility::JsonValue& jsonValue) {
2689 if (!jsonValue.isArray()) {
2691 }
2692
2693 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
2694 std::vector<std::string> strings(array.size());
2695
2696 for (size_t i = 0; i < array.size(); i++) {
2697 if (!array[i].isString()) {
2698 // The entire array is invalidated; return.
2700 }
2701 strings[i] = array[i].getString();
2702 }
2703
2705 }
2706};
2707
2708} // namespace CesiumGltf
A copy of an array element of a PropertyTableProperty or PropertyTextureProperty.
int64_t size() const noexcept
The number of elements in this array.
const PropertyArrayView< ElementType > & view() const
Obtains a PropertyArrayView over the contents of this copy.
A view on an array element of a PropertyTableProperty or PropertyTextureProperty.
Indicates the status of a property view.
static const PropertyViewStatusType ErrorTypeMismatch
This property view's type does not match what is specified in ClassProperty::type.
static const PropertyViewStatusType ErrorInvalidDefaultValue
The property provided an invalid default value.
static const PropertyViewStatusType ErrorInvalidMin
The property provided an invalid minimum value.
static const PropertyViewStatusType ErrorInvalidMax
The property provided an invalid maximum value.
static const PropertyViewStatusType ErrorInvalidOffset
The property provided an invalid offset value.
static const PropertyViewStatusType Valid
This property view is valid and ready to use.
static const PropertyViewStatusType ErrorNonexistentProperty
This property view is trying to view a property that does not exist.
static const PropertyViewStatusType ErrorInvalidNormalization
This property says it is normalized, but it does not have an integer component type.
static const PropertyViewStatusType ErrorArrayTypeMismatch
This property view differs from what is specified in ClassProperty::array.
static const PropertyViewStatusType ErrorInvalidNoDataValue
The property provided an invalid "no data" value.
static const PropertyViewStatusType ErrorNormalizationMismatch
This property view's normalization differs from what is specified in ClassProperty::normalized.
static const PropertyViewStatusType ErrorInvalidEnum
The property provided an invalid enum value.
static const PropertyViewStatusType EmptyPropertyWithDefault
This property view does not contain any data, but specifies a default value. This happens when a clas...
static const PropertyViewStatusType ErrorInvalidScale
The property provided an invalid scale value.
static const PropertyViewStatusType ErrorComponentTypeMismatch
This property view's component type does not match what is specified in ClassProperty::componentType.
std::optional< ElementType > offset() const noexcept
Gets the offset to apply to property values. Only applicable to SCALAR, VECN, and MATN types when the...
std::optional< ElementType > scale() const noexcept
Gets the scale to apply to property values. Only applicable to SCALAR, VECN, and MATN types when the ...
bool required() const noexcept
Whether the property must be present in every entity conforming to the class. If not required,...
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property table property and its class definition,...
std::optional< ElementType > defaultValue() const noexcept
Gets the default value to use when encountering a "no data" value or an omitted property....
PropertyView(const ClassProperty &classProperty, const PropertyTextureProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property texture property, class definition,...
PropertyView(const ClassProperty &classProperty, const PropertyAttributeProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property attribute property and its class definition,...
const std::optional< std::string > & name() const noexcept
Gets the name of the property being viewed. Returns std::nullopt if no name was specified.
PropertyViewStatusType _status
Indicates the status of a property view.
const std::optional< std::string > & semantic() const noexcept
Gets the semantic of the property being viewed. The semantic is an identifier that describes how this...
bool normalized() const noexcept
Whether this property has a normalized integer type.
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
int64_t arrayCount() const noexcept
Get the element count of the fixed-length arrays in this property. Only applicable when the property ...
PropertyViewStatusType status() const noexcept
Gets the status of this property view, indicating whether an error occurred.
std::optional< ElementType > noData() const noexcept
Gets the "no data" value, i.e., the value representing missing data in the property wherever it appea...
std::optional< ElementType > min() const noexcept
Gets the minimum allowed value for the property. Only applicable to SCALAR, VECN, and MATN types....
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
std::optional< ElementType > max() const noexcept
Gets the maximum allowed value for the property. Only applicable to SCALAR, VECN, and MATN types....
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
PropertyView(const ClassProperty &classProperty, const CesiumGltf::Enum *pEnumDefinition)
Constructs a property instance from a class definition and enum definition.
const std::optional< std::string > & description() const noexcept
Gets the description of the property being viewed. Returns std::nullopt if no description was specifi...
PropertyView()
Constructs an empty property instance.
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &property)
Constructs a property instance from a property table property and its class definition.
std::optional< ElementType > noData() const noexcept
Constructs an empty property instance. false>noData
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
std::optional< NormalizedType > max() const noexcept
Constructs an empty property instance. false>max
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
PropertyView(const ClassProperty &classProperty, const PropertyTextureProperty &property)
Constructs a property instance from a property texture property and its class definition.
PropertyView(const ClassProperty &classProperty, const PropertyAttributeProperty &property)
Constructs a property instance from a property attribute property and its class definition.
PropertyViewStatusType _status
Indicates the status of a property view.
std::optional< NormalizedType > scale() const noexcept
Constructs an empty property instance. false>scale
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyView()
Constructs an empty property instance.
std::optional< NormalizedType > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
bool required() const noexcept
Constructs an empty property instance. false>required
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
std::optional< NormalizedType > offset() const noexcept
Constructs an empty property instance. false>offset
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
std::optional< NormalizedType > min() const noexcept
Constructs an empty property instance. false>min
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
PropertyView(const ClassProperty &classProperty, const PropertyTextureProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property texture property, its class definition,...
std::optional< PropertyArrayView< ElementType > > noData() const noexcept
Constructs an empty property instance. false>noData
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
std::optional< PropertyArrayView< ElementType > > offset() const noexcept
Constructs an empty property instance. false>offset
std::optional< PropertyArrayView< ElementType > > max() const noexcept
Constructs an empty property instance. false>max
std::optional< PropertyArrayView< ElementType > > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
std::optional< PropertyArrayView< ElementType > > min() const noexcept
Constructs an empty property instance. false>min
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
PropertyView(const ClassProperty &classProperty, const CesiumGltf::Enum *pEnumDefinition)
Constructs a property instance from a class definition and enum definition.
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
PropertyType propertyType() const noexcept
Returns the PropertyType of the property that this view is accessing.
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
bool required() const noexcept
Constructs an empty property instance. false>required
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property table property, its class definition,...
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
std::optional< PropertyArrayView< ElementType > > scale() const noexcept
Constructs an empty property instance. false>scale
PropertyViewStatusType _status
Indicates the status of a property view.
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
std::optional< PropertyArrayView< NormalizedType > > max() const noexcept
Constructs an empty property instance. false>max
PropertyViewStatusType _status
Indicates the status of a property view.
std::optional< PropertyArrayView< NormalizedType > > scale() const noexcept
Constructs an empty property instance. false>scale
std::optional< PropertyArrayView< ElementType > > noData() const noexcept
Constructs an empty property instance. false>noData
std::optional< PropertyArrayView< NormalizedType > > min() const noexcept
Constructs an empty property instance. false>min
PropertyView(const ClassProperty &classProperty, const PropertyTextureProperty &property)
Constructs a property instance from a property texture property and its class definition.
std::optional< PropertyArrayView< NormalizedType > > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &property)
Constructs a property instance from a property table property and its class definition.
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
std::optional< PropertyArrayView< NormalizedType > > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
bool required() const noexcept
Constructs an empty property instance. false>required
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
std::optional< PropertyArrayView< bool > > min() const noexcept
Constructs an empty property instance. false>min
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
std::optional< PropertyArrayView< bool > > max() const noexcept
Constructs an empty property instance. false>max
std::optional< PropertyArrayView< bool > > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
PropertyView()
Constructs an empty property instance.
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &, const CesiumGltf::Enum *)
Constructs a property instance from a property table property and its class definition.
PropertyViewStatusType _status
Indicates the status of a property view.
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
bool required() const noexcept
Constructs an empty property instance. false>required
std::optional< PropertyArrayView< bool > > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
std::optional< PropertyArrayView< bool > > scale() const noexcept
Constructs an empty property instance. false>scale
std::optional< PropertyArrayView< bool > > noData() const noexcept
Constructs an empty property instance. false>noData
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
std::optional< PropertyArrayView< std::string_view > > max() const noexcept
Constructs an empty property instance. false>max
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
std::optional< PropertyArrayView< std::string_view > > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyViewStatusType _status
Indicates the status of a property view.
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
std::optional< PropertyArrayView< std::string_view > > min() const noexcept
Constructs an empty property instance. false>min
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
std::optional< PropertyArrayView< std::string_view > > noData() const noexcept
Constructs an empty property instance. false>noData
bool required() const noexcept
Constructs an empty property instance. false>required
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &, const CesiumGltf::Enum *)
Constructs a property instance from a property table property and its class definition.
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
std::optional< PropertyArrayView< std::string_view > > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
std::optional< PropertyArrayView< std::string_view > > scale() const noexcept
Constructs an empty property instance. false>scale
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
std::optional< bool > min() const noexcept
Constructs an empty property instance. false>min
std::optional< bool > noData() const noexcept
Constructs an empty property instance. false>noData
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
bool required() const noexcept
Constructs an empty property instance. false>required
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
std::optional< bool > scale() const noexcept
Constructs an empty property instance. false>scale
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &, const CesiumGltf::Enum *)
Constructs a property instance from a property table property and its class definition.
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyViewStatusType _status
Indicates the status of a property view.
PropertyView()
Constructs an empty property instance.
std::optional< bool > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
std::optional< bool > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
std::optional< bool > max() const noexcept
Constructs an empty property instance. false>max
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
bool required() const noexcept
Constructs an empty property instance. false>required
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
PropertyView()
Constructs an empty property instance.
std::optional< std::string_view > min() const noexcept
Constructs an empty property instance. false>min
std::optional< std::string_view > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyViewStatusType _status
Indicates the status of a property view.
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
std::optional< std::string_view > scale() const noexcept
Constructs an empty property instance. false>scale
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &, const CesiumGltf::Enum *)
Constructs a property instance from a property table property and its class definition.
std::optional< std::string_view > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
std::optional< std::string_view > noData() const noexcept
Constructs an empty property instance. false>noData
std::optional< std::string_view > max() const noexcept
Constructs an empty property instance. false>max
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
Represents a metadata property in EXT_structural_metadata.
A generic implementation of a value in a JSON structure.
Definition JsonValue.h:53
bool getBool() const
Gets the bool from the value.
Definition JsonValue.h:449
const JsonValue::String & getString() const
Gets the string from the value.
Definition JsonValue.h:418
std::vector< JsonValue > Array
The type to represent an Array JSON value.
Definition JsonValue.h:78
bool isBool() const noexcept
Returns whether this value is a Bool value.
Definition JsonValue.h:570
std::string String
The type to represent a String JSON value.
Definition JsonValue.h:68
bool isArray() const noexcept
Returns whether this value is an Array value.
Definition JsonValue.h:591
bool isString() const noexcept
Returns whether this value is a String value.
Definition JsonValue.h:577
std::optional< To > getSafeNumber() const
Gets the numerical quantity from the value casted to the To type. This function should be used over g...
Definition JsonValue.h:351
const JsonValue::Array & getArray() const
Gets the array from the value.
Definition JsonValue.h:428
Classes for working with glTF models.
PropertyComponentType
The possible types of a property component.
@ Float32
A property component equivalent to a float.
@ Float64
A property component equivalent to a double.
PropertyComponentType convertStringToPropertyComponentType(const std::string &str)
Converts a string into a PropertyComponentType.
PropertyViewStatusType validatePropertyType(const ClassProperty &classProperty, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Validates a ClassProperty representing a property, checking for any type mismatches.
PropertyViewStatusType validateArrayPropertyType(const ClassProperty &classProperty, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Validates a ClassProperty representing an array of values, checking for any type mismatches.
bool canRepresentPropertyType(PropertyType type)
Returns whether the type T can represent the given PropertyType.
int64_t getCount(std::optional< std::vector< std::byte > > &buffer)
Obtains the number of values of type ElementType that could fit in the buffer.
PropertyType convertStringToPropertyType(const std::string &str)
Converts a string into a PropertyType.
PropertyType
The possible types of a property in a PropertyTableView.
@ Invalid
An invalid property type.
int32_t PropertyViewStatusType
The type used for fields of PropertyViewStatus.
STL namespace.
static const std::string ENUM
ENUM
bool normalized
Specifies whether integer values are normalized. Only applicable to SCALAR, VECN, and MATN types with...
std::optional< std::string > componentType
The datatype of the element's components. Only applicable to SCALAR, VECN, and MATN types.
bool array
Whether the property is an array. When count is defined the property is a fixed-length array....
std::optional< CesiumUtility::JsonValue > noData
A noData value represents missing data — also known as a sentinel value — wherever it appears....
std::string type
The element type.
std::optional< CesiumUtility::JsonValue > defaultProperty
A default value to use when encountering a noData value or an omitted property. The value is given in...
std::vector< CesiumGltf::EnumValue > values
An array of enum values. Duplicate names or duplicate integer values are not allowed.
Definition EnumSpec.h:74
An enum value.
Definition EnumValue.h:16
This class is not meant to be instantiated directly. Use Enum instead.
Definition Enum.h:12
Check if a C++ type can be represented as a matN type.
Check if a C++ type can be represented as a scalar property type.
Check if a C++ type can be represented as a vecN type.
void type
The component type of this metadata array.
An attribute containing property values.
An array of binary property values.
A texture containing property values.
Convert an integer numeric type to the corresponding representation as a double type....
Infer the best-fitting PropertyType and PropertyComponentType for a C++ type.