cesium-native 0.64.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:
894 : _status(status),
895 _name(std::nullopt),
896 _semantic(std::nullopt),
897 _description(std::nullopt),
898 _offset(std::nullopt),
899 _scale(std::nullopt),
900 _max(std::nullopt),
901 _min(std::nullopt),
902 _required(false),
903 _noData(std::nullopt),
904 _defaultValue(std::nullopt),
905 _propertyType(PropertyType::Invalid) {}
906
912 const ClassProperty& classProperty,
913 const PropertyTableProperty& property)
914 : PropertyView(classProperty) {
916 return;
917 }
918
919 // If the property has its own values, override the class-provided values.
920 getNumericPropertyValues(property);
921 }
922
928 const ClassProperty& classProperty,
929 const PropertyTextureProperty& property)
930 : PropertyView(classProperty) {
932 return;
933 }
934
935 // If the property has its own values, override the class-provided values.
936 getNumericPropertyValues(property);
937 }
938
944 const ClassProperty& classProperty,
945 const PropertyAttributeProperty& property)
946 : PropertyView(classProperty) {
948 return;
949 }
950
951 // If the property has its own values, override the class-provided values.
952 getNumericPropertyValues(property);
953 }
954
955public:
959 PropertyViewStatusType status() const noexcept { return _status; }
960
964 const std::optional<std::string>& name() const noexcept { return _name; }
965
969 const std::optional<std::string>& semantic() const noexcept {
970 return _semantic;
971 }
972
976 const std::optional<std::string>& description() const noexcept {
977 return _description;
978 }
979
983 int64_t arrayCount() const noexcept { return 0; }
984
988 bool normalized() const noexcept { return true; }
989
993 std::optional<NormalizedType> offset() const noexcept { return _offset; }
994
998 std::optional<NormalizedType> scale() const noexcept { return _scale; }
999
1003 std::optional<NormalizedType> max() const noexcept { return _max; }
1004
1008 std::optional<NormalizedType> min() const noexcept { return _min; }
1009
1013 bool required() const noexcept { return _required; }
1014
1018 std::optional<ElementType> noData() const noexcept { return _noData; }
1019
1023 std::optional<NormalizedType> defaultValue() const noexcept {
1024 return _defaultValue;
1025 }
1026
1031 PropertyType propertyType() const noexcept { return _propertyType; }
1032
1033protected:
1036
1037private:
1038 std::optional<std::string> _name;
1039 std::optional<std::string> _semantic;
1040 std::optional<std::string> _description;
1041
1042 std::optional<NormalizedType> _offset;
1043 std::optional<NormalizedType> _scale;
1044 std::optional<NormalizedType> _max;
1045 std::optional<NormalizedType> _min;
1046
1047 bool _required;
1048 std::optional<ElementType> _noData;
1049 std::optional<NormalizedType> _defaultValue;
1050 PropertyType _propertyType;
1051
1061 template <typename T>
1062 static std::optional<T> getValue(const CesiumUtility::JsonValue& jsonValue) {
1063 if constexpr (IsMetadataScalar<T>::value) {
1064 return getScalar<T>(jsonValue);
1065 }
1066
1067 if constexpr (IsMetadataVecN<T>::value) {
1068 return getVecN<T>(jsonValue);
1069 }
1070
1071 if constexpr (IsMetadataMatN<T>::value) {
1072 return getMatN<T>(jsonValue);
1073 }
1074 }
1075
1076 using PropertyDefinitionType = std::variant<
1081
1086 void getNumericPropertyValues(const PropertyDefinitionType& inProperty) {
1087 std::visit(
1088 [this](auto property) {
1089 if (property.offset) {
1090 _offset = getValue<NormalizedType>(*property.offset);
1091 if (!_offset) {
1092 // The value was specified but something went wrong.
1094 return;
1095 }
1096 }
1097
1098 if (property.scale) {
1099 _scale = getValue<NormalizedType>(*property.scale);
1100 if (!_scale) {
1101 // The value was specified but something went wrong.
1102 _status = PropertyViewStatus::ErrorInvalidScale;
1103 return;
1104 }
1105 }
1106
1107 if (property.max) {
1108 _max = getValue<NormalizedType>(*property.max);
1109 if (!_scale) {
1110 // The value was specified but something went wrong.
1111 _status = PropertyViewStatus::ErrorInvalidMax;
1112 return;
1113 }
1114 }
1115
1116 if (property.min) {
1117 _min = getValue<NormalizedType>(*property.min);
1118 if (!_scale) {
1119 // The value was specified but something went wrong.
1120 _status = PropertyViewStatus::ErrorInvalidMin;
1121 return;
1122 }
1123 }
1124 },
1125 inProperty);
1126 }
1127};
1128
1133template <> class PropertyView<bool> {
1134public:
1139 : _status(PropertyViewStatus::ErrorNonexistentProperty),
1140 _name(std::nullopt),
1141 _semantic(std::nullopt),
1142 _description(std::nullopt),
1143 _required(false),
1144 _defaultValue(std::nullopt) {}
1145
1149 PropertyView(const ClassProperty& classProperty)
1150 : _status(validatePropertyType<bool>(classProperty)),
1151 _name(classProperty.name),
1152 _semantic(classProperty.semantic),
1153 _description(classProperty.description),
1154 _required(classProperty.required),
1155 _defaultValue(std::nullopt) {
1157 return;
1158 }
1159
1160 if (classProperty.defaultProperty) {
1161 if (!_required) {
1162 _defaultValue = getBooleanValue(*classProperty.defaultProperty);
1163 }
1164
1165 if (!_defaultValue) {
1166 // The value was specified but something went wrong.
1168 return;
1169 }
1170 }
1171 }
1172
1173protected:
1181 : _status(status),
1182 _name(std::nullopt),
1183 _semantic(std::nullopt),
1184 _description(std::nullopt),
1185 _required(false),
1186 _defaultValue(std::nullopt) {}
1187
1193 const ClassProperty& classProperty,
1194 const PropertyTableProperty& /*property*/,
1195 const CesiumGltf::Enum* /*pEnumDefinition*/)
1196 : PropertyView(classProperty) {}
1197
1198public:
1202 PropertyViewStatusType status() const noexcept { return _status; }
1203
1207 const std::optional<std::string>& name() const noexcept { return _name; }
1208
1212 const std::optional<std::string>& semantic() const noexcept {
1213 return _semantic;
1214 }
1215
1219 const std::optional<std::string>& description() const noexcept {
1220 return _description;
1221 }
1222
1226 int64_t arrayCount() const noexcept { return 0; }
1227
1231 bool normalized() const noexcept { return false; }
1232
1236 std::optional<bool> offset() const noexcept { return std::nullopt; }
1237
1241 std::optional<bool> scale() const noexcept { return std::nullopt; }
1242
1246 std::optional<bool> max() const noexcept { return std::nullopt; }
1247
1251 std::optional<bool> min() const noexcept { return std::nullopt; }
1252
1256 bool required() const noexcept { return _required; }
1257
1261 std::optional<bool> noData() const noexcept { return std::nullopt; }
1262
1266 std::optional<bool> defaultValue() const noexcept { return _defaultValue; }
1267
1273
1274protected:
1277
1278private:
1279 std::optional<std::string> _name;
1280 std::optional<std::string> _semantic;
1281 std::optional<std::string> _description;
1282
1283 bool _required;
1284 std::optional<bool> _defaultValue;
1285
1286 static std::optional<bool>
1287 getBooleanValue(const CesiumUtility::JsonValue& value) {
1288 if (!value.isBool()) {
1289 return std::nullopt;
1290 }
1291
1292 return value.getBool();
1293 }
1294};
1295
1300template <> class PropertyView<std::string_view> {
1301public:
1306 : _status(PropertyViewStatus::ErrorNonexistentProperty),
1307 _name(std::nullopt),
1308 _semantic(std::nullopt),
1309 _description(std::nullopt),
1310 _required(false),
1311 _noData(std::nullopt),
1312 _defaultValue(std::nullopt) {}
1313
1317 PropertyView(const ClassProperty& classProperty)
1318 : _status(validatePropertyType<std::string_view>(classProperty)),
1319 _name(classProperty.name),
1320 _semantic(classProperty.semantic),
1321 _description(classProperty.description),
1322 _required(classProperty.required),
1323 _noData(std::nullopt),
1324 _defaultValue(std::nullopt) {
1326 return;
1327 }
1328
1329 if (classProperty.noData) {
1330 if (!_required) {
1331 _noData = getStringValue(*classProperty.noData);
1332 }
1333
1334 if (!_noData) {
1335 // The value was specified but something went wrong.
1337 return;
1338 }
1339 }
1340
1341 if (classProperty.defaultProperty) {
1342 if (!_required) {
1343 _defaultValue = getStringValue(*classProperty.defaultProperty);
1344 }
1345
1346 if (!_defaultValue) {
1347 // The value was specified but something went wrong.
1349 return;
1350 }
1351 }
1352 }
1353
1354protected:
1362 : _status(status),
1363 _name(std::nullopt),
1364 _semantic(std::nullopt),
1365 _description(std::nullopt),
1366 _required(false),
1367 _noData(std::nullopt),
1368 _defaultValue(std::nullopt) {}
1369
1375 const ClassProperty& classProperty,
1376 const PropertyTableProperty& /*property*/,
1377 const CesiumGltf::Enum* /*pEnumDefinition*/)
1378 : PropertyView(classProperty) {}
1379
1380public:
1384 PropertyViewStatusType status() const noexcept { return _status; }
1385
1389 const std::optional<std::string>& name() const noexcept { return _name; }
1390
1394 const std::optional<std::string>& semantic() const noexcept {
1395 return _semantic;
1396 }
1397
1401 const std::optional<std::string>& description() const noexcept {
1402 return _description;
1403 }
1404
1408 int64_t arrayCount() const noexcept { return 0; }
1409
1413 bool normalized() const noexcept { return false; }
1414
1418 std::optional<std::string_view> offset() const noexcept {
1419 return std::nullopt;
1420 }
1421
1425 std::optional<std::string_view> scale() const noexcept {
1426 return std::nullopt;
1427 }
1428
1432 std::optional<std::string_view> max() const noexcept { return std::nullopt; }
1433
1437 std::optional<std::string_view> min() const noexcept { return std::nullopt; }
1438
1442 bool required() const noexcept { return _required; }
1443
1447 std::optional<std::string_view> noData() const noexcept {
1448 if (_noData)
1449 return std::string_view(*_noData);
1450
1451 return std::nullopt;
1452 }
1453
1457 std::optional<std::string_view> defaultValue() const noexcept {
1458 if (_defaultValue)
1459 return std::string_view(*_defaultValue);
1460
1461 return std::nullopt;
1462 }
1463
1469
1470protected:
1473
1474private:
1475 std::optional<std::string> _name;
1476 std::optional<std::string> _semantic;
1477 std::optional<std::string> _description;
1478
1479 bool _required;
1480 std::optional<std::string> _noData;
1481 std::optional<std::string> _defaultValue;
1482
1483 static std::optional<std::string>
1484 getStringValue(const CesiumUtility::JsonValue& value) {
1485 if (!value.isString()) {
1486 return std::nullopt;
1487 }
1488
1489 return std::string(value.getString().c_str());
1490 }
1491};
1492
1506template <typename ElementType>
1507class PropertyView<PropertyArrayView<ElementType>, false> {
1508public:
1513 : _status(PropertyViewStatus::ErrorNonexistentProperty),
1514 _name(std::nullopt),
1515 _semantic(std::nullopt),
1516 _description(std::nullopt),
1517 _count(0),
1518 _offset(),
1519 _scale(),
1520 _max(),
1521 _min(),
1522 _required(false),
1523 _noData(),
1524 _defaultValue(),
1525 _propertyType(PropertyType::Invalid) {}
1526
1530 PropertyView(const ClassProperty& classProperty)
1531 : PropertyView(classProperty, nullptr) {}
1532
1538 const ClassProperty& classProperty,
1539 const CesiumGltf::Enum* pEnumDefinition)
1541 classProperty,
1542 pEnumDefinition)),
1543 _name(classProperty.name),
1544 _semantic(classProperty.semantic),
1545 _description(classProperty.description),
1546 _count(classProperty.count ? *classProperty.count : 0),
1547 _offset(),
1548 _scale(),
1549 _max(),
1550 _min(),
1551 _required(classProperty.required),
1552 _noData(),
1553 _defaultValue(),
1554 _propertyType(convertStringToPropertyType(classProperty.type)) {
1556 return;
1557 }
1558
1559 if (classProperty.normalized) {
1560 _status = PropertyViewStatus::ErrorNormalizationMismatch;
1561 return;
1562 }
1563
1564 if (classProperty.type != ClassProperty::Type::ENUM) {
1565 getNumericPropertyValues(classProperty);
1566 }
1567
1569 return;
1570 }
1571
1572 if (classProperty.noData) {
1573 if (!this->_required && this->_propertyType == PropertyType::Enum) {
1574 CESIUM_ASSERT(pEnumDefinition != nullptr);
1575 if constexpr (IsMetadataInteger<ElementType>::value) {
1576 this->_noData =
1577 getEnumArrayValue(*classProperty.noData, *pEnumDefinition);
1578 }
1579 } else if (!this->_required) {
1580 this->_noData = getArrayValue(*classProperty.noData);
1581 }
1582
1583 if (this->_noData.size() == 0) {
1584 // The value was specified but something went wrong.
1585 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
1586 return;
1587 }
1588 }
1589
1590 if (classProperty.defaultProperty) {
1591 if (!this->_required && this->_propertyType == PropertyType::Enum) {
1592 CESIUM_ASSERT(pEnumDefinition != nullptr);
1593 if constexpr (IsMetadataInteger<ElementType>::value) {
1594 this->_defaultValue = getEnumArrayValue(
1595 *classProperty.defaultProperty,
1596 *pEnumDefinition);
1597 }
1598 } else if (!this->_required) {
1599 this->_defaultValue = getArrayValue(*classProperty.defaultProperty);
1600 }
1601
1602 if (this->_defaultValue.size() == 0) {
1603 // The value was specified but something went wrong.
1604 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
1605 return;
1606 }
1607 }
1608 }
1609
1610protected:
1618 : _status(status),
1619 _name(std::nullopt),
1620 _semantic(std::nullopt),
1621 _description(std::nullopt),
1622 _count(0),
1623 _offset(),
1624 _scale(),
1625 _max(),
1626 _min(),
1627 _required(false),
1628 _noData(),
1629 _defaultValue(),
1630 _propertyType(PropertyType::Invalid) {}
1631
1637 const ClassProperty& classProperty,
1638 const PropertyTableProperty& property,
1639 const CesiumGltf::Enum* pEnumDefinition = nullptr)
1640 : PropertyView(classProperty, pEnumDefinition) {
1642 return;
1643 }
1644
1645 // If the property has its own values, override the class-provided values.
1646 if (classProperty.type != ClassProperty::Type::ENUM) {
1647 getNumericPropertyValues(property);
1648 }
1649 }
1650
1656 const ClassProperty& classProperty,
1657 const PropertyTextureProperty& property,
1658 const CesiumGltf::Enum* pEnumDefinition = nullptr)
1659 : PropertyView(classProperty, pEnumDefinition) {
1661 return;
1662 }
1663
1664 // If the property has its own values, override the class-provided values.
1665 if (classProperty.type != ClassProperty::Type::ENUM) {
1666 getNumericPropertyValues(property);
1667 }
1668 }
1669
1670public:
1674 PropertyViewStatusType status() const noexcept { return _status; }
1675
1679 const std::optional<std::string>& name() const noexcept { return _name; }
1680
1684 const std::optional<std::string>& semantic() const noexcept {
1685 return _semantic;
1686 }
1687
1691 const std::optional<std::string>& description() const noexcept {
1692 return _description;
1693 }
1694
1698 int64_t arrayCount() const noexcept { return _count; }
1699
1703 bool normalized() const noexcept { return false; }
1704
1708 std::optional<PropertyArrayView<ElementType>> offset() const noexcept {
1709 return this->_offset.size() > 0 ? std::make_optional(this->_offset.view())
1710 : std::nullopt;
1711 }
1712
1716 std::optional<PropertyArrayView<ElementType>> scale() const noexcept {
1717 return this->_scale.size() > 0 ? std::make_optional(this->_scale.view())
1718 : std::nullopt;
1719 }
1720
1724 std::optional<PropertyArrayView<ElementType>> max() const noexcept {
1725 return this->_max.size() > 0 ? std::make_optional(this->_max.view())
1726 : std::nullopt;
1727 }
1728
1732 std::optional<PropertyArrayView<ElementType>> min() const noexcept {
1733 return this->_min.size() > 0 ? std::make_optional(this->_min.view())
1734 : std::nullopt;
1735 }
1736
1740 bool required() const noexcept { return _required; }
1741
1745 std::optional<PropertyArrayView<ElementType>> noData() const noexcept {
1746 return this->_noData.size() > 0 ? std::make_optional(this->_noData.view())
1747 : std::nullopt;
1748 }
1749
1753 std::optional<PropertyArrayView<ElementType>> defaultValue() const noexcept {
1754 return this->_defaultValue.size() > 0
1755 ? std::make_optional(this->_defaultValue.view())
1756 : std::nullopt;
1757 }
1758
1763 PropertyType propertyType() const noexcept { return _propertyType; }
1764
1765protected:
1768
1769private:
1770 std::optional<std::string> _name;
1771 std::optional<std::string> _semantic;
1772 std::optional<std::string> _description;
1773
1774 int64_t _count;
1775
1780
1781 bool _required;
1783 PropertyArrayCopy<ElementType> _defaultValue;
1784 PropertyType _propertyType;
1785
1786 using PropertyDefinitionType = std::
1787 variant<ClassProperty, PropertyTableProperty, PropertyTextureProperty>;
1788 void getNumericPropertyValues(const PropertyDefinitionType& inProperty) {
1789 std::visit(
1790 [this](auto property) {
1791 bool isFixedSizeArray = this->_count > 0;
1792
1793 if (property.offset) {
1794 // Only floating point types can specify an offset.
1798 if (isFixedSizeArray) {
1799 this->_offset = getArrayValue(*property.offset);
1800 if (this->_offset.size() == this->_count) {
1801 break;
1802 }
1803 }
1804 // If it does not break here, something went wrong.
1805 [[fallthrough]];
1806 default:
1808 return;
1809 }
1810 }
1811
1812 if (property.scale) {
1813 // Only floating point types can specify a scale.
1817 if (isFixedSizeArray) {
1818 this->_scale = getArrayValue(*property.scale);
1819 if (this->_scale.size() == this->_count) {
1820 break;
1821 }
1822 }
1823 // If it does not break here, something went wrong.
1824 [[fallthrough]];
1825 default:
1827 return;
1828 }
1829 }
1830
1831 if (property.max) {
1832 if (isFixedSizeArray) {
1833 this->_max = getArrayValue(*property.max);
1834 }
1835 if (!isFixedSizeArray || this->_max.size() != this->_count) {
1836 // The value was specified but something went wrong.
1838 return;
1839 }
1840 }
1841
1842 if (property.min) {
1843 if (isFixedSizeArray) {
1844 this->_min = getArrayValue(*property.min);
1845 }
1846 if (!isFixedSizeArray || this->_min.size() != this->_count) {
1847 // The value was specified but something went wrong.
1849 return;
1850 }
1851 }
1852 },
1853 inProperty);
1854 }
1855
1857 getArrayValue(const CesiumUtility::JsonValue& jsonValue) {
1858 if (!jsonValue.isArray()) {
1860 }
1861
1862 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
1863 std::vector<ElementType> values(array.size());
1864
1865 if constexpr (IsMetadataScalar<ElementType>::value) {
1866 for (size_t i = 0; i < array.size(); i++) {
1867 std::optional<ElementType> maybeValue =
1868 getScalar<ElementType>(array[i]);
1869 if (!maybeValue.has_value()) {
1870 return PropertyArrayCopy<ElementType>();
1871 }
1872
1873 values[i] = *maybeValue;
1874 }
1875 }
1876 if constexpr (IsMetadataVecN<ElementType>::value) {
1877 for (size_t i = 0; i < array.size(); i++) {
1878 std::optional<ElementType> maybeValue = getVecN<ElementType>(array[i]);
1879 if (!maybeValue.has_value()) {
1880 return PropertyArrayCopy<ElementType>();
1881 }
1882
1883 values[i] = *maybeValue;
1884 }
1885 }
1886
1887 if constexpr (IsMetadataMatN<ElementType>::value) {
1888 for (size_t i = 0; i < array.size(); i++) {
1889 std::optional<ElementType> maybeValue = getMatN<ElementType>(array[i]);
1890 if (!maybeValue.has_value()) {
1891 return PropertyArrayCopy<ElementType>();
1892 }
1893
1894 values[i] = *maybeValue;
1895 }
1896 }
1897
1898 return PropertyArrayCopy<ElementType>(values);
1899 }
1900
1901 static PropertyArrayCopy<ElementType> getEnumArrayValue(
1902 const CesiumUtility::JsonValue& jsonValue,
1903 const CesiumGltf::Enum& enumDefinition) {
1904 if (!jsonValue.isArray()) {
1905 return PropertyArrayCopy<ElementType>();
1906 }
1907
1908 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
1909 std::vector<ElementType> values(array.size());
1910
1911 for (size_t i = 0; i < array.size(); i++) {
1912 if (!array[i].isString()) {
1913 return PropertyArrayCopy<ElementType>();
1914 }
1915
1916 // default and noData values for enums contain the name of the enum as a
1917 // string
1918 CesiumUtility::JsonValue::String str = array[i].getString();
1919 auto foundValue = std::find_if(
1920 enumDefinition.values.begin(),
1921 enumDefinition.values.end(),
1922 [&str](const CesiumGltf::EnumValue& enumValue) {
1923 return enumValue.name == str;
1924 });
1925
1926 if (foundValue == enumDefinition.values.end()) {
1927 return PropertyArrayCopy<ElementType>();
1928 }
1929
1930 values[i] = static_cast<ElementType>(foundValue->value);
1931 }
1932
1933 return PropertyArrayCopy<ElementType>(values);
1934 }
1935};
1936
1950template <typename ElementType>
1951class PropertyView<PropertyArrayView<ElementType>, true> {
1952private:
1953 using NormalizedType = typename TypeToNormalizedType<ElementType>::type;
1954
1955public:
1960 : _status(PropertyViewStatus::ErrorNonexistentProperty),
1961 _name(std::nullopt),
1962 _semantic(std::nullopt),
1963 _description(std::nullopt),
1964 _count(0),
1965 _offset(),
1966 _scale(),
1967 _max(),
1968 _min(),
1969 _required(false),
1970 _noData(),
1971 _defaultValue(),
1972 _propertyType(PropertyType::Invalid) {}
1973
1977 PropertyView(const ClassProperty& classProperty)
1979 classProperty)),
1980 _name(classProperty.name),
1981 _semantic(classProperty.semantic),
1982 _description(classProperty.description),
1983 _count(classProperty.count ? *classProperty.count : 0),
1984 _offset(),
1985 _scale(),
1986 _max(),
1987 _min(),
1988 _required(classProperty.required),
1989 _noData(),
1990 _defaultValue(),
1991 _propertyType(convertStringToPropertyType(classProperty.type)) {
1993 return;
1994 }
1995
1996 if (!classProperty.normalized) {
1997 _status = PropertyViewStatus::ErrorNormalizationMismatch;
1998 return;
1999 }
2000
2001 getNumericPropertyValues(classProperty);
2003 return;
2004 }
2005
2006 if (classProperty.noData) {
2007 if (!this->_required) {
2008 this->_noData = getArrayValue<ElementType>(*classProperty.noData);
2009 }
2010
2011 if (this->_noData.size() == 0) {
2012 // The value was specified but something went wrong.
2013 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
2014 return;
2015 }
2016 }
2017
2018 if (classProperty.defaultProperty) {
2019 if (!this->_required) {
2020 this->_defaultValue =
2021 getArrayValue<NormalizedType>(*classProperty.defaultProperty);
2022 }
2023
2024 if (this->_defaultValue.size() == 0) {
2025 // The value was specified but something went wrong.
2026 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2027 return;
2028 }
2029 }
2030 }
2031
2032protected:
2040 : _status(status),
2041 _name(std::nullopt),
2042 _semantic(std::nullopt),
2043 _description(std::nullopt),
2044 _count(0),
2045 _offset(),
2046 _scale(),
2047 _max(),
2048 _min(),
2049 _required(false),
2050 _noData(),
2051 _defaultValue(),
2052 _propertyType(PropertyType::Invalid) {}
2053
2059 const ClassProperty& classProperty,
2060 const PropertyTableProperty& property)
2061 : PropertyView(classProperty) {
2063 return;
2064 }
2065
2066 // If the property has its own values, override the class-provided values.
2067 getNumericPropertyValues(property);
2068 }
2069
2075 const ClassProperty& classProperty,
2076 const PropertyTextureProperty& property)
2077 : PropertyView(classProperty) {
2079 return;
2080 }
2081
2082 // If the property has its own values, override the class-provided values.
2083 getNumericPropertyValues(property);
2084 }
2085
2086public:
2090 PropertyViewStatusType status() const noexcept { return _status; }
2091
2095 const std::optional<std::string>& name() const noexcept { return _name; }
2096
2100 const std::optional<std::string>& semantic() const noexcept {
2101 return _semantic;
2102 }
2103
2107 const std::optional<std::string>& description() const noexcept {
2108 return _description;
2109 }
2110
2114 int64_t arrayCount() const noexcept { return _count; }
2115
2119 bool normalized() const noexcept { return true; }
2120
2124 std::optional<PropertyArrayView<NormalizedType>> offset() const noexcept {
2125 return this->_offset.size() > 0 ? std::make_optional(this->_offset.view())
2126 : std::nullopt;
2127 }
2128
2132 std::optional<PropertyArrayView<NormalizedType>> scale() const noexcept {
2133 return this->_scale.size() > 0 ? std::make_optional(this->_scale.view())
2134 : std::nullopt;
2135 }
2136
2140 std::optional<PropertyArrayView<NormalizedType>> max() const noexcept {
2141 return this->_max.size() > 0 ? std::make_optional(this->_max.view())
2142 : std::nullopt;
2143 }
2144
2148 std::optional<PropertyArrayView<NormalizedType>> min() const noexcept {
2149 return this->_min.size() > 0 ? std::make_optional(this->_min.view())
2150 : std::nullopt;
2151 }
2152
2156 bool required() const noexcept { return _required; }
2157
2161 std::optional<PropertyArrayView<ElementType>> noData() const noexcept {
2162 return this->_noData.size() > 0 ? std::make_optional(this->_noData.view())
2163 : std::nullopt;
2164 }
2165
2169 std::optional<PropertyArrayView<NormalizedType>>
2170 defaultValue() const noexcept {
2171 return this->_defaultValue.size() > 0
2172 ? std::make_optional(this->_defaultValue.view())
2173 : std::nullopt;
2174 }
2175
2180 PropertyType propertyType() const noexcept { return _propertyType; }
2181
2182protected:
2185
2186private:
2187 std::optional<std::string> _name;
2188 std::optional<std::string> _semantic;
2189 std::optional<std::string> _description;
2190
2191 int64_t _count;
2192
2197
2198 bool _required;
2201 PropertyType _propertyType;
2202
2203 using PropertyDefinitionType = std::
2204 variant<ClassProperty, PropertyTableProperty, PropertyTextureProperty>;
2205 void getNumericPropertyValues(const PropertyDefinitionType& inProperty) {
2206 std::visit(
2207 [this](auto property) {
2208 bool isFixedSizeArray = this->_count > 0;
2209 if (property.offset) {
2210 if (isFixedSizeArray) {
2211 this->_offset = getArrayValue<NormalizedType>(*property.offset);
2212 }
2213 if (!isFixedSizeArray || this->_offset.size() != this->_count) {
2214 // The value was specified but something went wrong.
2216 return;
2217 }
2218 }
2219
2220 if (property.scale) {
2221 if (isFixedSizeArray) {
2222 this->_scale = getArrayValue<NormalizedType>(*property.scale);
2223 }
2224 if (!isFixedSizeArray || this->_scale.size() != this->_count) {
2225 // The value was specified but something went wrong.
2227 return;
2228 }
2229 }
2230
2231 if (property.max) {
2232 if (isFixedSizeArray) {
2233 this->_max = getArrayValue<NormalizedType>(*property.max);
2234 }
2235 if (!isFixedSizeArray || this->_max.size() != this->_count) {
2236 // The value was specified but something went wrong.
2238 return;
2239 }
2240 }
2241
2242 if (property.min) {
2243 if (isFixedSizeArray) {
2244 this->_min = getArrayValue<NormalizedType>(*property.min);
2245 }
2246 if (!isFixedSizeArray || this->_min.size() != this->_count) {
2247 // The value was specified but something went wrong.
2249 return;
2250 }
2251 }
2252 },
2253 inProperty);
2254 }
2255
2256 template <typename T>
2258 getArrayValue(const CesiumUtility::JsonValue& jsonValue) {
2259 if (!jsonValue.isArray()) {
2260 return PropertyArrayCopy<T>();
2261 }
2262
2263 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
2264 std::vector<T> values(array.size());
2265
2266 if constexpr (IsMetadataScalar<T>::value) {
2267 for (size_t i = 0; i < array.size(); i++) {
2268 std::optional<T> maybeElement = getScalar<T>(array[i]);
2269 if (!maybeElement.has_value()) {
2270 return PropertyArrayCopy<T>();
2271 }
2272 values[i] = *maybeElement;
2273 }
2274 }
2275
2276 if constexpr (IsMetadataVecN<T>::value) {
2277 for (size_t i = 0; i < array.size(); i++) {
2278 std::optional<T> maybeElement = getVecN<T>(array[i]);
2279 if (!maybeElement.has_value()) {
2280 return PropertyArrayCopy<T>();
2281 }
2282 values[i] = *maybeElement;
2283 }
2284 }
2285
2286 if constexpr (IsMetadataMatN<T>::value) {
2287 for (size_t i = 0; i < array.size(); i++) {
2288 std::optional<T> maybeElement = getMatN<T>(array[i]);
2289 if (!maybeElement.has_value()) {
2290 return PropertyArrayCopy<T>();
2291 }
2292 values[i] = *maybeElement;
2293 }
2294 }
2295
2296 return PropertyArrayCopy<T>(values);
2297 }
2298};
2299
2304template <> class PropertyView<PropertyArrayView<bool>> {
2305public:
2310 : _status(PropertyViewStatus::ErrorNonexistentProperty),
2311 _name(std::nullopt),
2312 _semantic(std::nullopt),
2313 _description(std::nullopt),
2314 _count(0),
2315 _required(false),
2316 _defaultValue() {}
2317
2321 PropertyView(const ClassProperty& classProperty)
2322 : _status(
2323 validateArrayPropertyType<PropertyArrayView<bool>>(classProperty)),
2324 _name(classProperty.name),
2325 _semantic(classProperty.semantic),
2326 _description(classProperty.description),
2327 _count(classProperty.count ? *classProperty.count : 0),
2328 _required(classProperty.required),
2329 _defaultValue() {
2331 return;
2332 }
2333
2334 if (classProperty.defaultProperty) {
2335 if (!this->_required) {
2336 this->_defaultValue =
2337 getBooleanArrayValue(*classProperty.defaultProperty);
2338 }
2339
2340 if (this->_defaultValue.size() == 0 ||
2341 (this->_count > 0 && this->_defaultValue.size() != this->_count)) {
2342 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2343 return;
2344 }
2345 }
2346 }
2347
2348protected:
2356 : _status(status),
2357 _name(std::nullopt),
2358 _semantic(std::nullopt),
2359 _description(std::nullopt),
2360 _count(0),
2361 _required(false),
2362 _defaultValue() {}
2363
2369 const ClassProperty& classProperty,
2370 const PropertyTableProperty& /*property*/,
2371 const CesiumGltf::Enum* /*pEnumDefinition*/)
2372 : PropertyView(classProperty) {}
2373
2374public:
2378 PropertyViewStatusType status() const noexcept { return _status; }
2379
2383 const std::optional<std::string>& name() const noexcept { return _name; }
2384
2388 const std::optional<std::string>& semantic() const noexcept {
2389 return _semantic;
2390 }
2391
2395 const std::optional<std::string>& description() const noexcept {
2396 return _description;
2397 }
2398
2402 int64_t arrayCount() const noexcept { return _count; }
2403
2407 bool normalized() const noexcept { return false; }
2408
2412 std::optional<PropertyArrayView<bool>> offset() const noexcept {
2413 return std::nullopt;
2414 }
2415
2419 std::optional<PropertyArrayView<bool>> scale() const noexcept {
2420 return std::nullopt;
2421 }
2422
2426 std::optional<PropertyArrayView<bool>> max() const noexcept {
2427 return std::nullopt;
2428 }
2429
2433 std::optional<PropertyArrayView<bool>> min() const noexcept {
2434 return std::nullopt;
2435 }
2436
2440 bool required() const noexcept { return _required; }
2441
2445 std::optional<PropertyArrayView<bool>> noData() const noexcept {
2446 return std::nullopt;
2447 }
2448
2452 std::optional<PropertyArrayView<bool>> defaultValue() const noexcept {
2453 return this->_defaultValue.size() > 0
2454 ? std::make_optional(this->_defaultValue.view())
2455 : std::nullopt;
2456 }
2457
2463
2464protected:
2467
2468private:
2469 std::optional<std::string> _name;
2470 std::optional<std::string> _semantic;
2471 std::optional<std::string> _description;
2472
2473 int64_t _count;
2474 bool _required;
2475
2476 PropertyArrayCopy<bool> _defaultValue;
2477
2479 getBooleanArrayValue(const CesiumUtility::JsonValue& jsonValue) {
2480 if (!jsonValue.isArray()) {
2481 return PropertyArrayCopy<bool>();
2482 }
2483 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
2484
2485 std::vector<bool> values(array.size());
2486 for (size_t i = 0; i < array.size(); i++) {
2487 if (!array[i].isBool()) {
2488 // The entire array is invalidated; return.
2489 return PropertyArrayCopy<bool>();
2490 }
2491 values[i] = array[i].getBool();
2492 }
2493 return values;
2494 }
2495};
2496
2501template <> class PropertyView<PropertyArrayView<std::string_view>> {
2502public:
2507 : _status(PropertyViewStatus::ErrorNonexistentProperty),
2508 _name(std::nullopt),
2509 _semantic(std::nullopt),
2510 _description(std::nullopt),
2511 _count(0),
2512 _required(false),
2513 _noData(),
2514 _defaultValue() {}
2515
2519 PropertyView(const ClassProperty& classProperty)
2521 classProperty)),
2522 _name(classProperty.name),
2523 _semantic(classProperty.semantic),
2524 _description(classProperty.description),
2525 _count(classProperty.count ? *classProperty.count : 0),
2526 _required(classProperty.required),
2527 _noData(),
2528 _defaultValue() {
2530 return;
2531 }
2532
2533 if (classProperty.noData) {
2534 if (!this->_required) {
2535 this->_noData = getStringArrayValue(*classProperty.noData);
2536 }
2537
2538 if (this->_noData.size() == 0 ||
2539 (this->_count > 0 && this->_noData.size() != this->_count)) {
2540 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
2541 return;
2542 }
2543 }
2544
2545 if (classProperty.defaultProperty) {
2546 if (!this->_required) {
2547 this->_defaultValue =
2548 getStringArrayValue(*classProperty.defaultProperty);
2549 }
2550
2551 if (this->_defaultValue.size() == 0 ||
2552 (this->_count > 0 && this->_defaultValue.size() != this->_count)) {
2553 // The value was specified but something went wrong.
2554 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2555 return;
2556 }
2557 }
2558 }
2559
2560protected:
2568 : _status(status),
2569 _name(std::nullopt),
2570 _semantic(std::nullopt),
2571 _description(std::nullopt),
2572 _count(0),
2573 _required(false),
2574 _noData(),
2575 _defaultValue() {}
2576
2582 const ClassProperty& classProperty,
2583 const PropertyTableProperty& /*property*/,
2584 const CesiumGltf::Enum* /*pEnumDefinition*/)
2585 : PropertyView(classProperty) {}
2586
2587public:
2591 PropertyViewStatusType status() const noexcept { return _status; }
2592
2596 const std::optional<std::string>& name() const noexcept { return _name; }
2597
2601 const std::optional<std::string>& semantic() const noexcept {
2602 return _semantic;
2603 }
2604
2608 const std::optional<std::string>& description() const noexcept {
2609 return _description;
2610 }
2611
2615 int64_t arrayCount() const noexcept { return _count; }
2616
2620 bool normalized() const noexcept { return false; }
2621
2625 std::optional<PropertyArrayView<std::string_view>> offset() const noexcept {
2626 return std::nullopt;
2627 }
2628
2632 std::optional<PropertyArrayView<std::string_view>> scale() const noexcept {
2633 return std::nullopt;
2634 }
2635
2639 std::optional<PropertyArrayView<std::string_view>> max() const noexcept {
2640 return std::nullopt;
2641 }
2642
2646 std::optional<PropertyArrayView<std::string_view>> min() const noexcept {
2647 return std::nullopt;
2648 }
2649
2653 bool required() const noexcept { return _required; }
2654
2658 std::optional<PropertyArrayView<std::string_view>> noData() const noexcept {
2659 return this->_noData.size() > 0 ? std::make_optional(this->_noData.view())
2660 : std::nullopt;
2661 }
2662
2666 std::optional<PropertyArrayView<std::string_view>>
2667 defaultValue() const noexcept {
2668 return this->_defaultValue.size() > 0
2669 ? std::make_optional(this->_defaultValue.view())
2670 : std::nullopt;
2671 }
2672
2678
2679protected:
2682
2683private:
2684 std::optional<std::string> _name;
2685 std::optional<std::string> _semantic;
2686 std::optional<std::string> _description;
2687
2688 int64_t _count;
2689 bool _required;
2690
2693
2695 getStringArrayValue(const CesiumUtility::JsonValue& jsonValue) {
2696 if (!jsonValue.isArray()) {
2698 }
2699
2700 const CesiumUtility::JsonValue::Array& array = jsonValue.getArray();
2701 std::vector<std::string> strings(array.size());
2702
2703 for (size_t i = 0; i < array.size(); i++) {
2704 if (!array[i].isString()) {
2705 // The entire array is invalidated; return.
2707 }
2708 strings[i] = array[i].getString();
2709 }
2710
2712 }
2713};
2714
2715} // 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.