Repository: AnalyticalGraphicsInc/3d-tiles-tools Branch: main Commit: 7fa62c5f7920 Files: 1189 Total size: 3.9 MB Directory structure: gitextract_nrezpdnq/ ├── .eslintignore ├── .eslintrc.json ├── .github/ │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .npmignore ├── .nycrc ├── .prettierignore ├── .prettierrc.json ├── CHANGES.md ├── IMPLEMENTATION.md ├── LICENSE.md ├── README.md ├── ThirdParty.json ├── api-extractor.jsonc ├── bin/ │ ├── README.md │ └── main ├── demos/ │ ├── README.md │ ├── validationOptionsDemo.ts │ └── validationResultDemos.ts ├── etc/ │ └── 3d-tiles-validator.api.md ├── generateThirdParty.js ├── package.json ├── specs/ │ ├── BasicValidatorSpec.ts │ ├── BinaryBufferStructureSpec.ts │ ├── ExternalTilesetExtensionsValidationSpec.ts │ ├── MetadataSchemaValidationSpec.ts │ ├── SubtreeValidationSpec.ts │ ├── TilesetPackageValidationSpec.ts │ ├── TilesetValidationSpec.ts │ ├── data/ │ │ ├── Samples/ │ │ │ ├── ImplicitTileMetadata/ │ │ │ │ ├── content/ │ │ │ │ │ ├── 0/ │ │ │ │ │ │ └── 0/ │ │ │ │ │ │ └── 0.b3dm │ │ │ │ │ └── 1/ │ │ │ │ │ ├── 0/ │ │ │ │ │ │ ├── 0.b3dm │ │ │ │ │ │ └── 1.b3dm │ │ │ │ │ └── 1/ │ │ │ │ │ └── 1.b3dm │ │ │ │ ├── subtrees/ │ │ │ │ │ └── 1.1/ │ │ │ │ │ └── 0.0.0.json │ │ │ │ └── tileset_1.1.json │ │ │ ├── PaddingIssues/ │ │ │ │ ├── README.md │ │ │ │ ├── llA.b3dm │ │ │ │ ├── llB.b3dm │ │ │ │ ├── llC.b3dm │ │ │ │ ├── llD.b3dm │ │ │ │ ├── llE.b3dm │ │ │ │ ├── tilesetA.json │ │ │ │ ├── tilesetB.json │ │ │ │ ├── tilesetC.json │ │ │ │ ├── tilesetD.json │ │ │ │ └── tilesetE.json │ │ │ ├── README.md │ │ │ ├── SparseImplicitQuadtree/ │ │ │ │ ├── content/ │ │ │ │ │ ├── content_5__0_21.glb │ │ │ │ │ ├── content_5__10_31.glb │ │ │ │ │ ├── content_5__11_30.glb │ │ │ │ │ ├── content_5__12_25.glb │ │ │ │ │ ├── content_5__13_24.glb │ │ │ │ │ ├── content_5__14_27.glb │ │ │ │ │ ├── content_5__15_26.glb │ │ │ │ │ ├── content_5__16_5.glb │ │ │ │ │ ├── content_5__17_4.glb │ │ │ │ │ ├── content_5__18_7.glb │ │ │ │ │ ├── content_5__19_6.glb │ │ │ │ │ ├── content_5__1_20.glb │ │ │ │ │ ├── content_5__20_1.glb │ │ │ │ │ ├── content_5__21_0.glb │ │ │ │ │ ├── content_5__22_3.glb │ │ │ │ │ ├── content_5__23_2.glb │ │ │ │ │ ├── content_5__24_13.glb │ │ │ │ │ ├── content_5__25_12.glb │ │ │ │ │ ├── content_5__26_15.glb │ │ │ │ │ ├── content_5__27_14.glb │ │ │ │ │ ├── content_5__28_9.glb │ │ │ │ │ ├── content_5__29_8.glb │ │ │ │ │ ├── content_5__2_23.glb │ │ │ │ │ ├── content_5__30_11.glb │ │ │ │ │ ├── content_5__31_10.glb │ │ │ │ │ ├── content_5__3_22.glb │ │ │ │ │ ├── content_5__4_17.glb │ │ │ │ │ ├── content_5__5_16.glb │ │ │ │ │ ├── content_5__6_19.glb │ │ │ │ │ ├── content_5__7_18.glb │ │ │ │ │ ├── content_5__8_29.glb │ │ │ │ │ └── content_5__9_28.glb │ │ │ │ ├── subtrees/ │ │ │ │ │ ├── 0.0.0.subtree │ │ │ │ │ ├── 3.0.5.subtree │ │ │ │ │ ├── 3.1.4.subtree │ │ │ │ │ ├── 3.2.7.subtree │ │ │ │ │ ├── 3.3.6.subtree │ │ │ │ │ ├── 3.4.1.subtree │ │ │ │ │ ├── 3.5.0.subtree │ │ │ │ │ ├── 3.6.3.subtree │ │ │ │ │ └── 3.7.2.subtree │ │ │ │ └── tileset.json │ │ │ ├── TilesetGzipped/ │ │ │ │ ├── ll.b3dm │ │ │ │ ├── lr.b3dm │ │ │ │ ├── parent.b3dm │ │ │ │ ├── tileset.json │ │ │ │ ├── ul.b3dm │ │ │ │ └── ur.b3dm │ │ │ ├── TilesetOfTilesets/ │ │ │ │ ├── lr.b3dm │ │ │ │ ├── parent.b3dm │ │ │ │ ├── tileset.json │ │ │ │ ├── tileset2.json │ │ │ │ ├── tileset3/ │ │ │ │ │ ├── ll.b3dm │ │ │ │ │ └── tileset3.json │ │ │ │ ├── ul.b3dm │ │ │ │ └── ur.b3dm │ │ │ ├── TilesetOfTilesetsWithError/ │ │ │ │ ├── lr.b3dm │ │ │ │ ├── parent.b3dm │ │ │ │ ├── tileset.json │ │ │ │ ├── tileset2.json │ │ │ │ ├── tileset3/ │ │ │ │ │ ├── ll.b3dm │ │ │ │ │ └── tileset3.json │ │ │ │ ├── ul.b3dm │ │ │ │ └── ur.b3dm │ │ │ └── TilesetWithFullMetadata/ │ │ │ └── tileset.json │ │ ├── buffers/ │ │ │ ├── bufferViewsElementBufferInvalidType.json │ │ │ ├── bufferViewsElementBufferInvalidValueA.json │ │ │ ├── bufferViewsElementBufferInvalidValueB.json │ │ │ ├── bufferViewsElementBufferInvalidValueC.json │ │ │ ├── bufferViewsElementByteLengthInvalidType.json │ │ │ ├── bufferViewsElementByteLengthInvalidValueA.json │ │ │ ├── bufferViewsElementByteLengthInvalidValueB.json │ │ │ ├── bufferViewsElementByteOffsetInvalidType.json │ │ │ ├── bufferViewsElementByteOffsetInvalidValueA.json │ │ │ ├── bufferViewsElementByteOffsetInvalidValueB.json │ │ │ ├── bufferViewsElementExceedsBufferLength.json │ │ │ ├── bufferViewsElementInvalidType.json │ │ │ ├── bufferViewsInvalidLength.json │ │ │ ├── bufferViewsInvalidType.json │ │ │ ├── buffersElementByteLengthInvalidType.json │ │ │ ├── buffersElementByteLengthInvalidValueA.json │ │ │ ├── buffersElementByteLengthInvalidValueB.json │ │ │ ├── buffersElementByteLengthMissing.json │ │ │ ├── buffersElementInvalidType.json │ │ │ ├── buffersElementNameInvalidLength.json │ │ │ ├── buffersElementNameInvalidType.json │ │ │ ├── buffersElementUriInvalidType.json │ │ │ ├── buffersElementUriMissing.json │ │ │ ├── buffersInvalidLength.json │ │ │ └── buffersInvalidType.json │ │ ├── extensions/ │ │ │ ├── boundingVolumeS2/ │ │ │ │ ├── s2AndInvalidBox.json │ │ │ │ ├── s2MaximumHeightInvalidType.json │ │ │ │ ├── s2MinimumHeightGreaterThanMaximumHeight.json │ │ │ │ ├── s2MinimumHeightInvalidType.json │ │ │ │ ├── s2TokenInvalidType.json │ │ │ │ ├── s2TokenInvalidValue.json │ │ │ │ ├── s2TokenMissing.json │ │ │ │ └── validTilesetWithS2.json │ │ │ ├── contentGltf/ │ │ │ │ ├── contentGltfExtensionRequiredButNotUsed.json │ │ │ │ ├── contentGltfExtensionsRequiredDuplicateElement.json │ │ │ │ ├── contentGltfExtensionsRequiredInvalidArrayLength.json │ │ │ │ ├── contentGltfExtensionsRequiredInvalidElementType.json │ │ │ │ ├── contentGltfExtensionsRequiredInvalidType.json │ │ │ │ ├── contentGltfExtensionsUsedDuplicateElement.json │ │ │ │ ├── contentGltfExtensionsUsedInvalidArrayLength.json │ │ │ │ ├── contentGltfExtensionsUsedInvalidElementType.json │ │ │ │ ├── contentGltfExtensionsUsedInvalidType.json │ │ │ │ ├── tileset_1_0_withContentGltfRequiredButNotUsed.json │ │ │ │ ├── tileset_1_0_withContentGltfUsedButNotFound.json │ │ │ │ ├── tileset_1_0_withContentGltfUsedButNotRequired.json │ │ │ │ ├── tileset_1_1_withContentGltfUsedButNotFound.json │ │ │ │ ├── validTileset_1_0_withExtensionObject.json │ │ │ │ ├── validTileset_1_0_withGltf.json │ │ │ │ ├── validTileset_1_1_withContentGltfUsedAndFound.json │ │ │ │ └── validTileset_1_1_withGltf.json │ │ │ ├── gpm/ │ │ │ │ ├── anchorPointMetadataContentIndexInvalidType.json │ │ │ │ ├── anchorPointMetadataContentIndexInvalidValue.json │ │ │ │ ├── anchorPointMetadataContentIndexMissing.json │ │ │ │ ├── anchorPointMetadataPlacementTypeInvalidValue.json │ │ │ │ ├── anchorPointMetadataPlacementTypeMeshContentWithContentIndex.json │ │ │ │ ├── anchorPointMetadataPlacementTypeMissing.json │ │ │ │ ├── collectionRecordCollectionIdInvalidType.json │ │ │ │ ├── collectionRecordCollectionIdMissing.json │ │ │ │ ├── collectionRecordPlatformIdInvalidType.json │ │ │ │ ├── collectionRecordPlatformIdMissing.json │ │ │ │ ├── collectionRecordSensorRecordsElementInvalidType.json │ │ │ │ ├── collectionRecordSensorRecordsInvalidLength.json │ │ │ │ ├── collectionRecordSensorRecordsInvalidType.json │ │ │ │ ├── collectionRecordSensorRecordsMissing.json │ │ │ │ ├── collectionUnitRecordCollectionUnitIdInvalidType.json │ │ │ │ ├── collectionUnitRecordCollectionUnitIdMissing.json │ │ │ │ ├── collectionUnitRecordExtentInformationInvalidType.json │ │ │ │ ├── collectionUnitRecordExtentInformationMissing.json │ │ │ │ ├── collectionUnitRecordPointSourceIdInvalidType.json │ │ │ │ ├── collectionUnitRecordPointSourceIdInvalidValue.json │ │ │ │ ├── collectionUnitRecordPointSourceIdMissing.json │ │ │ │ ├── collectionUnitRecordReferenceDateTimeInvalidType.json │ │ │ │ ├── collectionUnitRecordReferenceDateTimeMissing.json │ │ │ │ ├── correlationGroupGroupFlagsElementInvalidType.json │ │ │ │ ├── correlationGroupGroupFlagsInvalidLengthA.json │ │ │ │ ├── correlationGroupGroupFlagsInvalidLengthB.json │ │ │ │ ├── correlationGroupGroupFlagsMissing.json │ │ │ │ ├── correlationGroupGroupsGroupFlagsInvalidType.json │ │ │ │ ├── correlationGroupGroupsParamsInvalidType.json │ │ │ │ ├── correlationGroupGroupsParamsMissing.json │ │ │ │ ├── correlationGroupParamsElementInvalidType.json │ │ │ │ ├── correlationGroupParamsInvalidLengthA.json │ │ │ │ ├── correlationGroupParamsInvalidLengthB.json │ │ │ │ ├── correlationGroupRotationThetasInvalidType.json │ │ │ │ ├── correlationGroupRotationThetasMissing.json │ │ │ │ ├── covarUpperTriangleElementInvalidType.json │ │ │ │ ├── covarUpperTriangleInvalidLengthA.json │ │ │ │ ├── covarUpperTriangleInvalidLengthB.json │ │ │ │ ├── extentInformationLsrAxisUnitVectorsElementInvalidType.json │ │ │ │ ├── extentInformationLsrAxisUnitVectorsInvalidLengthA.json │ │ │ │ ├── extentInformationLsrAxisUnitVectorsInvalidLengthB.json │ │ │ │ ├── extentInformationLsrAxisUnitVectorsInvalidType.json │ │ │ │ ├── extentInformationLsrAxisUnitVectorsMissing.json │ │ │ │ ├── extentInformationLsrLengthsElementInvalidType.json │ │ │ │ ├── extentInformationLsrLengthsInvalidLengthA.json │ │ │ │ ├── extentInformationLsrLengthsInvalidLengthB.json │ │ │ │ ├── extentInformationLsrLengthsInvalidType.json │ │ │ │ ├── extentInformationLsrLengthsMissing.json │ │ │ │ ├── extentInformationOriginInvalidType.json │ │ │ │ ├── extentInformationOriginMissing.json │ │ │ │ ├── idInformationDatasetIdInvalidType.json │ │ │ │ ├── idInformationDatasetIdMissing.json │ │ │ │ ├── idInformationReferenceDateTimeInvalidType.json │ │ │ │ ├── idInformationReferenceDateTimeMissing.json │ │ │ │ ├── interpolationParamsDampeningParamInvalidType.json │ │ │ │ ├── interpolationParamsDampeningParamMissing.json │ │ │ │ ├── interpolationParamsInterpNumPostsInvalidType.json │ │ │ │ ├── interpolationParamsInterpNumPostsInvalidValueA.json │ │ │ │ ├── interpolationParamsInterpNumPostsInvalidValueB.json │ │ │ │ ├── interpolationParamsInterpNumPostsMissing.json │ │ │ │ ├── interpolationParamsInterpolationModeInvalidType.json │ │ │ │ ├── interpolationParamsInterpolationModeInvalidValue.json │ │ │ │ ├── interpolationParamsInterpolationModeMissing.json │ │ │ │ ├── interpolationParamsInterpolationModeNearestNeighborWithDampeningParam.json │ │ │ │ ├── interpolationParamsInterpolationModeNearestNeighborWithInterpNumPoints.json │ │ │ │ ├── lsrAxisUnitVectorsNotOrthogonalA.json │ │ │ │ ├── lsrAxisUnitVectorsNotOrthogonalB.json │ │ │ │ ├── lsrAxisUnitVectorsNotOrthogonalC.json │ │ │ │ ├── masterRecordCollectionRecordListElementInvalidType.json │ │ │ │ ├── masterRecordCollectionRecordListInvalidLength.json │ │ │ │ ├── masterRecordCollectionRecordListInvalidType.json │ │ │ │ ├── masterRecordDatasetExtentInformationInvalidType.json │ │ │ │ ├── masterRecordIdInformationInvalidType.json │ │ │ │ ├── masterRecordIdInformationMissing.json │ │ │ │ ├── masterRecordImplementationInvalidType.json │ │ │ │ ├── masterRecordImplementationMissing.json │ │ │ │ ├── masterRecordModelCoordSystemInvalidType.json │ │ │ │ ├── masterRecordModelCoordSystemMissing.json │ │ │ │ ├── masterRecordVersionInvalidType.json │ │ │ │ ├── masterRecordVersionMissing.json │ │ │ │ ├── modelCoordSystemCrsEcefInvalidType.json │ │ │ │ ├── modelCoordSystemCrsEcefMissing.json │ │ │ │ ├── modelCoordSystemMcsTypeEcefCrsEcefInvalidType.json │ │ │ │ ├── modelCoordSystemMcsTypeEcefCrsEcefMissing.json │ │ │ │ ├── modelCoordSystemMcsTypeEcefWithAxisUnitVectors.json │ │ │ │ ├── modelCoordSystemMcsTypeEcefWithCrsHorizontalUtm.json │ │ │ │ ├── modelCoordSystemMcsTypeEcefWithCrsVertical.json │ │ │ │ ├── modelCoordSystemMcsTypeEcefWithOrigin.json │ │ │ │ ├── modelCoordSystemMcsTypeInvalidType.json │ │ │ │ ├── modelCoordSystemMcsTypeInvalidValue.json │ │ │ │ ├── modelCoordSystemMcsTypeLsrAxisUnitVectorsInvalidType.json │ │ │ │ ├── modelCoordSystemMcsTypeLsrAxisUnitVectorsMissing.json │ │ │ │ ├── modelCoordSystemMcsTypeLsrOriginInvalidType.json │ │ │ │ ├── modelCoordSystemMcsTypeLsrOriginMissing.json │ │ │ │ ├── modelCoordSystemMcsTypeLsrWithCrsEcef.json │ │ │ │ ├── modelCoordSystemMcsTypeLsrWithCrsHorizontalUtm.json │ │ │ │ ├── modelCoordSystemMcsTypeLsrWithCrsVertical.json │ │ │ │ ├── modelCoordSystemMcsTypeMissing.json │ │ │ │ ├── modelCoordSystemMcsTypeUtmCrsHorizontalUtmInvalidType.json │ │ │ │ ├── modelCoordSystemMcsTypeUtmCrsHorizontalUtmMissing.json │ │ │ │ ├── modelCoordSystemMcsTypeUtmCrsVerticalInvalidType.json │ │ │ │ ├── modelCoordSystemMcsTypeUtmCrsVerticalMissing.json │ │ │ │ ├── modelCoordSystemMcsTypeUtmWithAxisUnitVectors.json │ │ │ │ ├── modelCoordSystemMcsTypeUtmWithCrsEcef.json │ │ │ │ ├── modelCoordSystemMcsTypeUtmWithOrigin.json │ │ │ │ ├── ngaGpmAnchorPointMetadataInvalidType.json │ │ │ │ ├── ngaGpmInterTileCorrelationGroupsElementInvalidType.json │ │ │ │ ├── ngaGpmInterTileCorrelationGroupsInvalidLength.json │ │ │ │ ├── ngaGpmInterTileCorrelationGroupsInvalidType.json │ │ │ │ ├── ngaGpmInterTileCorrelationGroupsMissing.json │ │ │ │ ├── ngaGpmInterpolationParamsInvalidType.json │ │ │ │ ├── ngaGpmInterpolationParamsMissing.json │ │ │ │ ├── ngaGpmInvalidType.json │ │ │ │ ├── ngaGpmMasterRecordInvalidType.json │ │ │ │ ├── ngaGpmMasterRecordMissing.json │ │ │ │ ├── ngaGpmPpeManifestInvalidType.json │ │ │ │ ├── ngaGpmThreeDimConformalParamsInvalidType.json │ │ │ │ ├── ngaGpmUnmodeledErrorRecordInvalidType.json │ │ │ │ ├── ngaGpmUnmodeledErrorRecordMissing.json │ │ │ │ ├── organizationSystemIdPairOrganizationInvalidType.json │ │ │ │ ├── organizationSystemIdPairOrganizationMissing.json │ │ │ │ ├── organizationSystemIdPairSystemIdInvalidType.json │ │ │ │ ├── organizationSystemIdPairSystemIdMissing.json │ │ │ │ ├── point3dElementInvalidType.json │ │ │ │ ├── point3dInvalidLengthA.json │ │ │ │ ├── point3dInvalidLengthB.json │ │ │ │ ├── ppeManifestElementInvalidType.json │ │ │ │ ├── ppeManifestInvalidLengthA.json │ │ │ │ ├── ppeManifestInvalidLengthB.json │ │ │ │ ├── ppeMetadataMaxInvalidType.json │ │ │ │ ├── ppeMetadataMinInvalidType.json │ │ │ │ ├── ppeMetadataSourceInvalidType.json │ │ │ │ ├── ppeMetadataSourceMissing.json │ │ │ │ ├── ppeMetadataSourceValuesNotUnique.json │ │ │ │ ├── referenceDateTimeNotIso8601A.json │ │ │ │ ├── referenceDateTimeNotIso8601B.json │ │ │ │ ├── referenceDateTimeNotIso8601C.json │ │ │ │ ├── referenceDateTimeNotIso8601D.json │ │ │ │ ├── referenceSystemDefinitionMissing.json │ │ │ │ ├── referenceSystemDescriptionInvalidType.json │ │ │ │ ├── referenceSystemEpochInvalidType.json │ │ │ │ ├── referenceSystemEpochMissing.json │ │ │ │ ├── referenceSystemNameInvalidType.json │ │ │ │ ├── referenceSystemNameMissing.json │ │ │ │ ├── referenceSystemOrgWithIdInvalidType.json │ │ │ │ ├── referenceSystemOrgWithIdMissing.json │ │ │ │ ├── referenceSystemWithDefinitionAndEpoch.json │ │ │ │ ├── referenceSystemWithDefinitionAndOrgWithId.json │ │ │ │ ├── rotationThetasElementInvalidType.json │ │ │ │ ├── rotationThetasInvalidLengthA.json │ │ │ │ ├── rotationThetasInvalidLengthB.json │ │ │ │ ├── sensorRecordCollectionUnitRecordsElementInvalidType.json │ │ │ │ ├── sensorRecordCollectionUnitRecordsInvalidLength.json │ │ │ │ ├── sensorRecordCollectionUnitRecordsInvalidType.json │ │ │ │ ├── sensorRecordCollectionUnitRecordsMissing.json │ │ │ │ ├── sensorRecordSensorIdInvalidType.json │ │ │ │ ├── sensorRecordSensorIdMissing.json │ │ │ │ ├── sensorRecordSensorModeInvalidType.json │ │ │ │ ├── sensorRecordSensorModeMissing.json │ │ │ │ ├── sensorRecordSensorTypeInvalidType.json │ │ │ │ ├── sensorRecordSensorTypeMissing.json │ │ │ │ ├── sensorRecordsSensorModeMissing.json │ │ │ │ ├── sensorRecordsSensorTypeInvalidType.json │ │ │ │ ├── sensorRecordsSensorTypeMissing.json │ │ │ │ ├── spdcfAInvalidType.json │ │ │ │ ├── spdcfAInvalidValueA.json │ │ │ │ ├── spdcfAInvalidValueB.json │ │ │ │ ├── spdcfAMissing.json │ │ │ │ ├── spdcfAlphaInvalidType.json │ │ │ │ ├── spdcfAlphaInvalidValueA.json │ │ │ │ ├── spdcfAlphaInvalidValueB.json │ │ │ │ ├── spdcfAlphaMissing.json │ │ │ │ ├── spdcfBetaInvalidType.json │ │ │ │ ├── spdcfBetaInvalidValueA.json │ │ │ │ ├── spdcfBetaInvalidValueB.json │ │ │ │ ├── spdcfBetaMissing.json │ │ │ │ ├── spdcfTInvalidType.json │ │ │ │ ├── spdcfTInvalidValue.json │ │ │ │ ├── spdcfTMissing.json │ │ │ │ ├── threeDimConformalParamsCovarianceElementInvalidType.json │ │ │ │ ├── threeDimConformalParamsCovarianceInvalidLengthFor4A.json │ │ │ │ ├── threeDimConformalParamsCovarianceInvalidLengthFor4B.json │ │ │ │ ├── threeDimConformalParamsCovarianceInvalidType.json │ │ │ │ ├── threeDimConformalParamsCovarianceMissing.json │ │ │ │ ├── threeDimConformalParamsFlagsElementInvalidType.json │ │ │ │ ├── threeDimConformalParamsFlagsInvalidLengthA.json │ │ │ │ ├── threeDimConformalParamsFlagsInvalidLengthB.json │ │ │ │ ├── threeDimConformalParamsFlagsInvalidType.json │ │ │ │ ├── threeDimConformalParamsFlagsInvalidValues.json │ │ │ │ ├── threeDimConformalParamsFlagsMissing.json │ │ │ │ ├── threeDimConformalParamsNormalizingScaleFactorInvalidType.json │ │ │ │ ├── threeDimConformalParamsNormalizingScaleFactorMissing.json │ │ │ │ ├── threeDimConformalParamsParametersElementInvalidType.json │ │ │ │ ├── threeDimConformalParamsParametersInvalidLengthFor4A.json │ │ │ │ ├── threeDimConformalParamsParametersInvalidLengthFor4B.json │ │ │ │ ├── threeDimConformalParamsParametersInvalidType.json │ │ │ │ ├── threeDimConformalParamsParametersMissing.json │ │ │ │ ├── threeDimConformalParamsRecenteringElementInvalidType.json │ │ │ │ ├── threeDimConformalParamsRecenteringInvalidLengthA.json │ │ │ │ ├── threeDimConformalParamsRecenteringInvalidLengthB.json │ │ │ │ ├── threeDimConformalParamsRecenteringInvalidType.json │ │ │ │ ├── threeDimConformalParamsRecenteringMissing.json │ │ │ │ ├── unitVectorInvalidElementValueA.json │ │ │ │ ├── unitVectorInvalidElementValueB.json │ │ │ │ ├── unitVectorInvalidLength.json │ │ │ │ ├── unitVectorNotUnitLengthA.json │ │ │ │ ├── unitVectorNotUnitLengthB.json │ │ │ │ ├── unmodeledErrorCorrParamsInvalidElementType.json │ │ │ │ ├── unmodeledErrorCorrParamsInvalidLengthA.json │ │ │ │ ├── unmodeledErrorCorrParamsInvalidLengthB.json │ │ │ │ ├── unmodeledErrorCorrParamsInvalidType.json │ │ │ │ ├── unmodeledErrorCorrParamsMissing.json │ │ │ │ ├── unmodeledErrorCorrRotationThetasInvalidType.json │ │ │ │ ├── unmodeledErrorCorrRotationThetasMissing.json │ │ │ │ ├── unmodeledErrorPostCovarianceInvalidType.json │ │ │ │ ├── unmodeledErrorPostCovarianceMissing.json │ │ │ │ ├── unmodeledErrorPostPositionInvalidType.json │ │ │ │ ├── unmodeledErrorPostPositionMissing.json │ │ │ │ ├── unmodeledErrorPostsElementInvalidType.json │ │ │ │ ├── unmodeledErrorPostsInvalidType.json │ │ │ │ ├── unmodeledErrorPostsMissing.json │ │ │ │ ├── unmodeledErrorUniqueIdInvalidType.json │ │ │ │ ├── unmodeledErrorUniqueIdMissing.json │ │ │ │ └── validTileset.json │ │ │ ├── maxarContentGeojson/ │ │ │ │ ├── bareGeometryTileset.json │ │ │ │ ├── bare_geometry.geojson │ │ │ │ ├── content_schema.json │ │ │ │ ├── duplicatePropertyIdsTileset.json │ │ │ │ ├── duplicate_property_ids_schema.json │ │ │ │ ├── extensionsUsedButNotRequiredTileset.json │ │ │ │ ├── geometryCollection.geojson │ │ │ │ ├── geometryCollectionTileset.json │ │ │ │ ├── invalid.geojson │ │ │ │ ├── invalidDefaultTypesTileset.json │ │ │ │ ├── invalidExtensionObject.json │ │ │ │ ├── invalidGeojsonTileset.json │ │ │ │ ├── invalidMinMaxOnNonNumericType.json │ │ │ │ ├── invalidMinMaxTileset.json │ │ │ │ ├── invalidPropertiesSchemaUri.json │ │ │ │ ├── invalidRequiredWithDefaultTileset.json │ │ │ │ ├── invalidSchemaContent.json │ │ │ │ ├── invalidTilesetWithGeojson.json │ │ │ │ ├── invalidUriFormat.json │ │ │ │ ├── invalid_content_schema.json │ │ │ │ ├── invalid_default_types_schema.json │ │ │ │ ├── invalid_min_max_schema.json │ │ │ │ ├── invalid_minmax_schema.json │ │ │ │ ├── invalid_required_with_default_schema.json │ │ │ │ ├── lineString.geojson │ │ │ │ ├── nonExistentSchema.json │ │ │ │ ├── test_schema.json │ │ │ │ ├── validOptionalWithoutDefaultsTileset.json │ │ │ │ ├── validTilesetWithMaxarContentGeojson.json │ │ │ │ ├── validWithPropertiesSchemaUri.json │ │ │ │ ├── valid_optional_without_defaults_schema.json │ │ │ │ └── vegetation_schema.json │ │ │ ├── maxarExtent/ │ │ │ │ ├── collinearOverlap.geojson │ │ │ │ ├── collinearOverlapTileset.json │ │ │ │ ├── extent.geojson │ │ │ │ ├── extentOverflowingTileTileset.json │ │ │ │ ├── extent_overflowing_tile.geojson │ │ │ │ ├── insufficientCoordinates.geojson │ │ │ │ ├── insufficientCoordinatesTileset.json │ │ │ │ ├── internalTouchRing.geojson │ │ │ │ ├── internalTouchRingTileset.json │ │ │ │ ├── invalidEmptyUri.json │ │ │ │ ├── invalidGeojsonContent.json │ │ │ │ ├── invalidGeometryTypes.geojson │ │ │ │ ├── invalidGeometryTypesTileset.json │ │ │ │ ├── invalidMissingUri.json │ │ │ │ ├── invalidNonResolvableUri.json │ │ │ │ ├── invalidSpatialExtent.json │ │ │ │ ├── invalidUriType.json │ │ │ │ ├── invalid_extent.geojson │ │ │ │ ├── large_extent.geojson │ │ │ │ ├── nearMiss.geojson │ │ │ │ ├── nearMissTileset.json │ │ │ │ ├── nearVertexOnOtherSideFail.geojson │ │ │ │ ├── nearVertexOnOtherSideFailTileset.json │ │ │ │ ├── nearVertexOnOtherSideOk.geojson │ │ │ │ ├── nearVertexOnOtherSideOkTileset.json │ │ │ │ ├── overlappingRings.geojson │ │ │ │ ├── overlappingRingsTileset.json │ │ │ │ ├── selfIntersecting.geojson │ │ │ │ ├── selfIntersectingTileset.json │ │ │ │ ├── small_extent.geojson │ │ │ │ ├── trueCrossing.geojson │ │ │ │ ├── trueCrossingTileset.json │ │ │ │ ├── validPolygonsOnly.geojson │ │ │ │ ├── validPolygonsOnlyTileset.json │ │ │ │ ├── validTilesetWithMaxarExtent.json │ │ │ │ └── validTilesetWithSpatialExtent.json │ │ │ ├── maxarGrid/ │ │ │ │ ├── invalidBoundingBoxLength.json │ │ │ │ ├── invalidBoundingBoxSemantics.json │ │ │ │ ├── invalidCenterLength.json │ │ │ │ ├── invalidCoordinateSystemType.json │ │ │ │ ├── invalidCoordinateSystemValue.json │ │ │ │ ├── invalidElevation.json │ │ │ │ ├── invalidGridType.json │ │ │ │ ├── invalidIndexLength.json │ │ │ │ ├── invalidS2GridWithCenter.json │ │ │ │ ├── invalidS2GridWithSize.json │ │ │ │ ├── invalidS2GridWithSrs.json │ │ │ │ ├── invalidSizeLength.json │ │ │ │ ├── invalidSrsReferenceSystem.json │ │ │ │ ├── invalidTileLevel.json │ │ │ │ ├── validS2Grid.json │ │ │ │ ├── validTilesetWithMaxarGrid.json │ │ │ │ └── validTilesetWithVriconGrid.json │ │ │ └── vriconClass/ │ │ │ └── validTilesetWithVriconClass.json │ │ ├── gltfExtensions/ │ │ │ ├── FeatureIdAttributeAndPropertyTableFeatureIdNotInRange.gltf │ │ │ ├── FeatureIdAttributeAndPropertyTableWithValueNotInRange.gltf │ │ │ ├── FeatureIdAttributePropertyTableInvalidValue.gltf │ │ │ ├── FeatureIdAttributePropertyTableWithoutPropertyTables.gltf │ │ │ ├── FeatureIdAttributePropertyTableWithoutStructuralMetadata.gltf │ │ │ ├── FeatureIdTextureAndPropertyTableFeatureIdNotInRange.gltf │ │ │ ├── ValidFeatureIdAttributeAndPropertyTable.gltf │ │ │ ├── ValidFeatureIdTextureAndPropertyTable.gltf │ │ │ ├── gpmLocal/ │ │ │ │ ├── ValidGltfGpmLocal.gltf │ │ │ │ ├── ValidMeshPrimitiveGpmLocal.gltf │ │ │ │ ├── anchorPointDirectAdjustmentParamsInvalidElementType.gltf │ │ │ │ ├── anchorPointDirectAdjustmentParamsInvalidLength.gltf │ │ │ │ ├── anchorPointDirectAdjustmentParamsInvalidType.gltf │ │ │ │ ├── anchorPointDirectAdjustmentParamsMissing.gltf │ │ │ │ ├── anchorPointDirectPositionInvalidLength.gltf │ │ │ │ ├── anchorPointDirectPositionInvalidType.gltf │ │ │ │ ├── anchorPointDirectPositionMissing.gltf │ │ │ │ ├── anchorPointIndirectAdjustmentParamsInvalidElementType.gltf │ │ │ │ ├── anchorPointIndirectAdjustmentParamsInvalidLength.gltf │ │ │ │ ├── anchorPointIndirectAdjustmentParamsInvalidType.gltf │ │ │ │ ├── anchorPointIndirectAdjustmentParamsMissing.gltf │ │ │ │ ├── anchorPointIndirectCovarianceInvalidLength.gltf │ │ │ │ ├── anchorPointIndirectCovarianceMatrixInvalidElementType.gltf │ │ │ │ ├── anchorPointIndirectCovarianceMatrixInvalidType.gltf │ │ │ │ ├── anchorPointIndirectCovarianceMatrixMissing.gltf │ │ │ │ ├── anchorPointIndirectPositionInvalidElementType.gltf │ │ │ │ ├── anchorPointIndirectPositionInvalidLength.gltf │ │ │ │ ├── anchorPointIndirectPositionInvalidType.gltf │ │ │ │ ├── anchorPointIndirectPositionMissing.gltf │ │ │ │ ├── anchorPointsDirectInvalidElementType.gltf │ │ │ │ ├── anchorPointsDirectInvalidLength.gltf │ │ │ │ ├── anchorPointsDirectInvalidType.gltf │ │ │ │ ├── anchorPointsIndirectInvalidElementType.gltf │ │ │ │ ├── anchorPointsIndirectInvalidLength.gltf │ │ │ │ ├── anchorPointsIndirectInvalidType.gltf │ │ │ │ ├── correlationGroupGroupFlagsElementInvalidType.gltf │ │ │ │ ├── correlationGroupGroupFlagsInvalidLength.gltf │ │ │ │ ├── correlationGroupGroupFlagsInvalidType.gltf │ │ │ │ ├── correlationGroupGroupFlagsMissing.gltf │ │ │ │ ├── correlationGroupParamsInvalidElementType.gltf │ │ │ │ ├── correlationGroupParamsInvalidLength.gltf │ │ │ │ ├── correlationGroupParamsInvalidType.gltf │ │ │ │ ├── correlationGroupParamsMissing.gltf │ │ │ │ ├── correlationGroupRotationThetasInvalidElementType.gltf │ │ │ │ ├── correlationGroupRotationThetasInvalidLength.gltf │ │ │ │ ├── correlationGroupRotationThetasInvalidType.gltf │ │ │ │ ├── correlationGroupRotationThetasMissing.gltf │ │ │ │ ├── covarianceDirectUpperTriangleElementInvalidType.gltf │ │ │ │ ├── covarianceDirectUpperTriangleInconsistentLength.gltf │ │ │ │ ├── covarianceDirectUpperTriangleInvalidLength.gltf │ │ │ │ ├── directAnchorPointsDirectMissing.gltf │ │ │ │ ├── directCovarianceDirectUpperTriangleMissing.gltf │ │ │ │ ├── directWithAnchorPointsIndirect.gltf │ │ │ │ ├── directWithIntraTileCorrelationGroups.gltf │ │ │ │ ├── indirectAnchorPointsIndirectMissing.gltf │ │ │ │ ├── indirectIntraTileCorrelationGroupsMissing.gltf │ │ │ │ ├── indirectWithAnchorPointsDirect.gltf │ │ │ │ ├── indirectWithCovarianceDirectUpperTriangle.gltf │ │ │ │ ├── intraTileCorrelationGroupsInvalidElementType.gltf │ │ │ │ ├── intraTileCorrelationGroupsInvalidLength.gltf │ │ │ │ ├── intraTileCorrelationGroupsInvalidType.gltf │ │ │ │ ├── ppeMetadataMaxInvalidType.gltf │ │ │ │ ├── ppeMetadataMinInvalidType.gltf │ │ │ │ ├── ppeMetadataSourceInvalidType.gltf │ │ │ │ ├── ppeMetadataSourceInvalidValue.gltf │ │ │ │ ├── ppeTextureIndexInvalidType.gltf │ │ │ │ ├── ppeTextureIndexInvalidValue.gltf │ │ │ │ ├── ppeTextureNoDataInvalidType.gltf │ │ │ │ ├── ppeTextureNoDataInvalidValue.gltf │ │ │ │ ├── ppeTextureOffsetInvalidType.gltf │ │ │ │ ├── ppeTextureScaleInvalidType.gltf │ │ │ │ ├── ppeTextureTexCoordInvalidType.gltf │ │ │ │ ├── ppeTextureTexCoordInvalidValue.gltf │ │ │ │ ├── ppeTextureTraitsInvalidType.gltf │ │ │ │ ├── ppeTextureTraitsMissing.gltf │ │ │ │ ├── ppeTexturesInvalidElementType.gltf │ │ │ │ ├── ppeTexturesInvalidLength.gltf │ │ │ │ ├── ppeTexturesInvalidType.gltf │ │ │ │ ├── spdcfAInvalidType.gltf │ │ │ │ ├── spdcfAInvalidValueA.gltf │ │ │ │ ├── spdcfAInvalidValueB.gltf │ │ │ │ ├── spdcfAMissing.gltf │ │ │ │ ├── spdcfAlphaInvalidType.gltf │ │ │ │ ├── spdcfAlphaInvalidValueA.gltf │ │ │ │ ├── spdcfAlphaInvalidValueB.gltf │ │ │ │ ├── spdcfAlphaMissing.gltf │ │ │ │ ├── spdcfBetaInvalidType.gltf │ │ │ │ ├── spdcfBetaInvalidValueA.gltf │ │ │ │ ├── spdcfBetaInvalidValueB.gltf │ │ │ │ ├── spdcfBetaMissing.gltf │ │ │ │ ├── spdcfTInvalidType.gltf │ │ │ │ ├── spdcfTInvalidValue.gltf │ │ │ │ ├── spdcfTMissing.gltf │ │ │ │ ├── storageTypeInvalidValue.gltf │ │ │ │ └── storageTypeMissing.gltf │ │ │ ├── instanceFeatures/ │ │ │ │ ├── InstanceFeaturesFeatureIdAttributeInvalidValue.gltf │ │ │ │ ├── InstanceFeaturesWithoutMeshGpuInstancing.gltf │ │ │ │ └── ValidInstanceFeatures.gltf │ │ │ ├── khrLightsPunctual/ │ │ │ │ ├── maxarTemporalLightTraits/ │ │ │ │ │ ├── invalidDutyWithSineWaveform.gltf │ │ │ │ │ ├── invalidDutyWithTriangleWaveform.gltf │ │ │ │ │ ├── invalidMissingWaveform.gltf │ │ │ │ │ ├── invalidUndeclaredExtension.gltf │ │ │ │ │ ├── invalidWaveform.gltf │ │ │ │ │ ├── validDutyWithSquareWaveform.gltf │ │ │ │ │ └── validTemporalLightTraits.gltf │ │ │ │ ├── validKhrLightsPunctual.gltf │ │ │ │ ├── validTilesetWithInvalidKhrLightsPunctual.json │ │ │ │ └── validTilesetWithKhrLightsPunctual.json │ │ │ ├── maxarImageOrtho/ │ │ │ │ ├── invalidCoordinateSystem.gltf │ │ │ │ ├── invalidMissingSrs.gltf │ │ │ │ ├── invalidTransformLength.gltf │ │ │ │ └── validMaxarImageOrtho.gltf │ │ │ ├── maxarNonvisualGeometry/ │ │ │ │ ├── NodeExtensionMeshInvalidType.gltf │ │ │ │ ├── NodeExtensionMeshInvalidValue.gltf │ │ │ │ ├── NodeExtensionMeshMissing.gltf │ │ │ │ ├── NodeExtensionMeshNotFound.gltf │ │ │ │ ├── PrimitiveExtensionShapeInvalidType.gltf │ │ │ │ ├── PrimitiveExtensionShapeInvalidValue.gltf │ │ │ │ ├── PrimitiveExtensionShapeMissing.gltf │ │ │ │ ├── PrimitiveExtensionTypeEmpty.gltf │ │ │ │ ├── PrimitiveExtensionTypeInvalidType.gltf │ │ │ │ ├── PrimitiveExtensionTypeMissing.gltf │ │ │ │ ├── ShapePathIncompatibleMode.gltf │ │ │ │ ├── ShapePointsIncompatibleMode.gltf │ │ │ │ ├── ShapeSurfaceIncompatibleMode.gltf │ │ │ │ ├── ShapeVolumeIncompatibleMode.gltf │ │ │ │ ├── ValidComplexExample.gltf │ │ │ │ ├── ValidNodeExtension.gltf │ │ │ │ ├── ValidPrimitiveExtensionPath.gltf │ │ │ │ ├── ValidPrimitiveExtensionPoints.gltf │ │ │ │ ├── ValidPrimitiveExtensionSurface.gltf │ │ │ │ └── ValidPrimitiveExtensionVolume.gltf │ │ │ ├── meshFeatures/ │ │ │ │ ├── FeatureIdAttributeAccessorNormalized.gltf │ │ │ │ ├── FeatureIdAttributeAccessorNotScalar.gltf │ │ │ │ ├── FeatureIdAttributeAttributeInvalidType.gltf │ │ │ │ ├── FeatureIdAttributeAttributeInvalidValue.gltf │ │ │ │ ├── FeatureIdAttributeFeatureCountInvalidType.gltf │ │ │ │ ├── FeatureIdAttributeFeatureCountInvalidValue.gltf │ │ │ │ ├── FeatureIdAttributeFeatureCountMismatch.gltf │ │ │ │ ├── FeatureIdAttributeFeatureCountMismatchForNullFeatureId.gltf │ │ │ │ ├── FeatureIdAttributeFeatureCountMissing.gltf │ │ │ │ ├── FeatureIdAttributeLabelInvalidType.gltf │ │ │ │ ├── FeatureIdAttributeLabelInvalidValue.gltf │ │ │ │ ├── FeatureIdAttributeNullFeatureIdInvalidType.gltf │ │ │ │ ├── FeatureIdAttributeNullFeatureIdInvalidValue.gltf │ │ │ │ ├── FeatureIdTextureFeatureCountMismatch.gltf │ │ │ │ ├── FeatureIdTextureSamplerInvalidFilterMode.gltf │ │ │ │ ├── FeatureIdTextureTextureChannelsInvalidElementType.gltf │ │ │ │ ├── FeatureIdTextureTextureChannelsInvalidType.gltf │ │ │ │ ├── FeatureIdTextureTextureChannelsTooManyChannels.gltf │ │ │ │ ├── FeatureIdTextureTextureChannelsTooManyElements.gltf │ │ │ │ ├── FeatureIdTextureTextureImageDataInvalid.gltf │ │ │ │ ├── FeatureIdTextureTextureIndexInvalidType.gltf │ │ │ │ ├── FeatureIdTextureTextureIndexInvalidValue.gltf │ │ │ │ ├── FeatureIdTextureTextureInvalidType.gltf │ │ │ │ ├── FeatureIdTextureTextureTexCoordInvalidType.gltf │ │ │ │ ├── FeatureIdTextureTextureTexCoordInvalidValue.gltf │ │ │ │ ├── README.md │ │ │ │ ├── ValidFeatureIdAttribute.gltf │ │ │ │ ├── ValidFeatureIdAttributeDefault/ │ │ │ │ │ └── ValidFeatureIdAttributeDefault.gltf │ │ │ │ ├── ValidFeatureIdAttributeWithByteStride.glb │ │ │ │ ├── ValidFeatureIdAttributeWithLargerFeatureCount.gltf │ │ │ │ ├── ValidFeatureIdAttributeWithNullFeatureId.gltf │ │ │ │ ├── ValidFeatureIdTexture.glb │ │ │ │ ├── ValidFeatureIdTexture.gltf │ │ │ │ └── ValidFeatureIdTextureUsingDefaultChannels.gltf │ │ │ └── structuralMetadata/ │ │ │ ├── ExtensionInMeshPrimitiveWithoutTopLevelObject.gltf │ │ │ ├── PropertyAttributesClassPropertyArray.gltf │ │ │ ├── PropertyAttributesClassPropertyInvalidComponentType.gltf │ │ │ ├── PropertyAttributesClassPropertyInvalidEnumValueType.gltf │ │ │ ├── PropertyAttributesClassPropertyMaxNotInRange.gltf │ │ │ ├── PropertyAttributesClassPropertyMinNotInRange.gltf │ │ │ ├── PropertyAttributesClassPropertyString.gltf │ │ │ ├── PropertyAttributesMeshPrimitivePropertyAttributesInvalidElementType.gltf │ │ │ ├── PropertyAttributesMeshPrimitivePropertyAttributesInvalidElementValue.gltf │ │ │ ├── PropertyAttributesMeshPrimitivePropertyAttributesInvalidLength.gltf │ │ │ ├── PropertyAttributesMeshPrimitivePropertyAttributesInvalidType.gltf │ │ │ ├── PropertyAttributesPropertyAttributePropertyInvalidAttribute.gltf │ │ │ ├── PropertyAttributesPropertyAttributePropertyMaxMismatch.gltf │ │ │ ├── PropertyAttributesPropertyAttributePropertyMaxNotInRange.gltf │ │ │ ├── PropertyAttributesPropertyAttributePropertyMinMismatch.gltf │ │ │ ├── PropertyAttributesPropertyAttributePropertyMinNotInRange.gltf │ │ │ ├── PropertyTextureClassPropertyMaxNotInRange.gltf │ │ │ ├── PropertyTextureClassPropertyMinNotInRange.gltf │ │ │ ├── PropertyTextureClassPropertyWithOffsetScaleMinNotInRange.gltf │ │ │ ├── PropertyTextureEnumsInvalidEnumValue.gltf │ │ │ ├── PropertyTextureInvalidPropertyTypeA.gltf │ │ │ ├── PropertyTextureInvalidPropertyTypeB.gltf │ │ │ ├── PropertyTextureMeshPrimitivePropertyTextureTexCoordInvalidValue.gltf │ │ │ ├── PropertyTextureMeshPrimitivePropertyTexturesInvalidElementType.gltf │ │ │ ├── PropertyTextureMeshPrimitivePropertyTexturesInvalidElementValue.gltf │ │ │ ├── PropertyTextureMeshPrimitivePropertyTexturesInvalidLength.gltf │ │ │ ├── PropertyTextureMeshPrimitivePropertyTexturesInvalidType.gltf │ │ │ ├── PropertyTexturePropertyChannelsSizeMismatch.gltf │ │ │ ├── PropertyTexturePropertyIndexInvalidType.gltf │ │ │ ├── PropertyTexturePropertyIndexInvalidValue.gltf │ │ │ ├── PropertyTexturePropertyTexCoordDefault.gltf │ │ │ ├── PropertyTexturePropertyTexCoordInvalidValue.gltf │ │ │ ├── PropertyTexturePropertyTexturePropertyMaxMismatch.gltf │ │ │ ├── PropertyTexturePropertyTexturePropertyMaxNotInRange.gltf │ │ │ ├── PropertyTexturePropertyTexturePropertyMinMismatch.gltf │ │ │ ├── PropertyTexturePropertyTexturePropertyMinNotInRange.gltf │ │ │ ├── README.md │ │ │ ├── StructuralMetadataMissingSchema.gltf │ │ │ ├── StructuralMetadataSchemaAndSchemaUri.gltf │ │ │ ├── ValidMultipleClasses.gltf │ │ │ ├── ValidPropertyAttributes.gltf │ │ │ ├── ValidPropertyTexture.gltf │ │ │ └── ValidPropertyTextureEnums.gltf │ │ ├── propertyTables/ │ │ │ ├── propertiesInvalidType.json │ │ │ ├── propertiesMinPropertiesMismatch.json │ │ │ ├── propertyArrayOffsetTypeInvalidType.json │ │ │ ├── propertyArrayOffsetTypeInvalidValue.json │ │ │ ├── propertyArrayOffsetsInvalidType.json │ │ │ ├── propertyArrayOffsetsInvalidValue.json │ │ │ ├── propertyClassInvalidType.json │ │ │ ├── propertyClassInvalidValue.json │ │ │ ├── propertyCountInvalidType.json │ │ │ ├── propertyCountInvalidValue.json │ │ │ ├── propertyIdInvalid.json │ │ │ ├── propertyStringOffsetTypeInvalidType.json │ │ │ ├── propertyStringOffsetTypeInvalidValue.json │ │ │ ├── propertyStringOffsetsInvalidType.json │ │ │ ├── propertyStringOffsetsInvalidValue.json │ │ │ ├── propertyStringWithoutStringOffsets.json │ │ │ ├── propertyValueMissing.json │ │ │ ├── propertyValuesInvalidType.json │ │ │ ├── propertyVariableLengthArrayWithMin.json │ │ │ ├── propertyVariableLengthArrayWithOffset.json │ │ │ └── propertyVariableLengthArrayWithoutArrayOffsets.json │ │ ├── schemas/ │ │ │ ├── FullMetadataSchema.json │ │ │ ├── metadataClassDescriptionInvalidType.json │ │ │ ├── metadataClassNameInvalidType.json │ │ │ ├── metadataClassPropertiesDuplicateSemantics.json │ │ │ ├── metadataClassPropertiesEmpty.json │ │ │ ├── metadataClassPropertiesNameInvalid.json │ │ │ ├── metadataClassPropertyArrayInvalidType.json │ │ │ ├── metadataClassPropertyComponentTypeForTypeWithoutComponents.json │ │ │ ├── metadataClassPropertyComponentTypeInvalidType.json │ │ │ ├── metadataClassPropertyComponentTypeInvalidValue.json │ │ │ ├── metadataClassPropertyComponentTypeMissing.json │ │ │ ├── metadataClassPropertyCountInvalidType.json │ │ │ ├── metadataClassPropertyCountInvalidValue.json │ │ │ ├── metadataClassPropertyCountWithoutArray.json │ │ │ ├── metadataClassPropertyDefaultWithRequired.json │ │ │ ├── metadataClassPropertyDescriptionInvalidType.json │ │ │ ├── metadataClassPropertyEnumTypeForNonEnumType.json │ │ │ ├── metadataClassPropertyEnumTypeInvalidType.json │ │ │ ├── metadataClassPropertyEnumTypeMissingForEnumType.json │ │ │ ├── metadataClassPropertyEnumTypeNotFound.json │ │ │ ├── metadataClassPropertyEnumTypeWithoutEnums.json │ │ │ ├── metadataClassPropertyMaxForNonNumericType.json │ │ │ ├── metadataClassPropertyMinForNonNumericType.json │ │ │ ├── metadataClassPropertyMinForVariableLengthArray.json │ │ │ ├── metadataClassPropertyNameInvalidType.json │ │ │ ├── metadataClassPropertyNoDataForBoolean.json │ │ │ ├── metadataClassPropertyNoDataInvalidEnumValueName.json │ │ │ ├── metadataClassPropertyNoDataInvalidEnumValueNames.json │ │ │ ├── metadataClassPropertyNoDataTypeMismatchA.json │ │ │ ├── metadataClassPropertyNoDataTypeMismatchB.json │ │ │ ├── metadataClassPropertyNoDataTypeMismatchC.json │ │ │ ├── metadataClassPropertyNoDataWithRequired.json │ │ │ ├── metadataClassPropertyNormalizedForNonIntegerComponentType.json │ │ │ ├── metadataClassPropertyNormalizedForUnnormalizableType.json │ │ │ ├── metadataClassPropertyNormalizedInvalidType.json │ │ │ ├── metadataClassPropertyOffsetForNonFloatingPointTypeA.json │ │ │ ├── metadataClassPropertyOffsetForNonFloatingPointTypeB.json │ │ │ ├── metadataClassPropertyOffsetForVariableLengthArray.json │ │ │ ├── metadataClassPropertyOffsetTypeMismatchA.json │ │ │ ├── metadataClassPropertyOffsetTypeMismatchB.json │ │ │ ├── metadataClassPropertyOffsetTypeMismatchC.json │ │ │ ├── metadataClassPropertyOffsetTypeMismatchD.json │ │ │ ├── metadataClassPropertyOffsetTypeMismatchE.json │ │ │ ├── metadataClassPropertyOffsetTypeMismatchF.json │ │ │ ├── metadataClassPropertyOffsetTypeMismatchG.json │ │ │ ├── metadataClassPropertyRequiredInvalidType.json │ │ │ ├── metadataClassPropertyScaleForNonFloatingPointType.json │ │ │ ├── metadataClassPropertyScaleForNonFloatingPointTypeB.json │ │ │ ├── metadataClassPropertySemanticArrayMismatchA.json │ │ │ ├── metadataClassPropertySemanticArrayMismatchB.json │ │ │ ├── metadataClassPropertySemanticComponentTypeMismatchA.json │ │ │ ├── metadataClassPropertySemanticComponentTypeMismatchB.json │ │ │ ├── metadataClassPropertySemanticCountMismatch.json │ │ │ ├── metadataClassPropertySemanticGeneric.json │ │ │ ├── metadataClassPropertySemanticInvalidType.json │ │ │ ├── metadataClassPropertySemanticNormalizedMismatch.json │ │ │ ├── metadataClassPropertySemanticTypeMismatch.json │ │ │ ├── metadataClassPropertySemanticUnknown.json │ │ │ ├── metadataClassPropertyTypeInvalidType.json │ │ │ ├── metadataClassPropertyTypeInvalidValue.json │ │ │ ├── metadataClassPropertyTypeMissing.json │ │ │ ├── metadataClassesInvalidType.json │ │ │ ├── metadataClassesNameInvalid.json │ │ │ ├── metadataEnumDescriptionInvalidType.json │ │ │ ├── metadataEnumNameInvalidType.json │ │ │ ├── metadataEnumValueDescriptionInvalidType.json │ │ │ ├── metadataEnumValueNameInvalidType.json │ │ │ ├── metadataEnumValueNotInDefaultValueTypeRange.json │ │ │ ├── metadataEnumValueNotInValueTypeRange.json │ │ │ ├── metadataEnumValueTypeInvalid.json │ │ │ ├── metadataEnumValueTypeInvalidType.json │ │ │ ├── metadataEnumValueTypeInvalidValue.json │ │ │ ├── metadataEnumValueValueInvalidType.json │ │ │ ├── metadataEnumValuesDuplicateName.json │ │ │ ├── metadataEnumValuesDuplicateValue.json │ │ │ ├── metadataEnumValuesEmpty.json │ │ │ ├── metadataEnumValuesMissing.json │ │ │ ├── metadataEnumsInvalidName.json │ │ │ ├── metadataEnumsInvalidType.json │ │ │ ├── schemaIdInvalidType.json │ │ │ ├── schemaIdInvalidValue.json │ │ │ ├── schemaIdMissing.json │ │ │ ├── validSchema.json │ │ │ └── validSchemaWithMinMax.json │ │ ├── subtrees/ │ │ │ ├── binarySubtreeComputedLengthInvalid.subtree │ │ │ ├── binarySubtreeInvalidBinaryByteLengthAlignment.subtree │ │ │ ├── binarySubtreeInvalidJsonByteLengthAlignment.subtree │ │ │ ├── binarySubtreeInvalidMagic.subtree │ │ │ ├── binarySubtreeInvalidVersion.subtree │ │ │ ├── binarySubtreeJsonInvalid.subtree │ │ │ ├── binarySubtreeValid.subtree │ │ │ ├── subtreeBufferViewsWithoutBuffers.json │ │ │ ├── subtreeChildSubtreeAvailabilityInvalidType.json │ │ │ ├── subtreeChildSubtreeAvailabilityMissing.json │ │ │ ├── subtreeContentAvailabilityInvalidLength.json │ │ │ ├── subtreeContentAvailabilityInvalidType.json │ │ │ ├── subtreeContentMetadataArrayElementInvalidType.json │ │ │ ├── subtreeContentMetadataArrayElementInvalidValueA.json │ │ │ ├── subtreeContentMetadataArrayElementInvalidValueB.json │ │ │ ├── subtreeContentMetadataInvalidLength.json │ │ │ ├── subtreeContentMetadataInvalidType.json │ │ │ ├── subtreeContentMetadataWithoutPropertyTables.json │ │ │ ├── subtreePropertyTablesElementInvalidType.json │ │ │ ├── subtreePropertyTablesInvalidLength.json │ │ │ ├── subtreePropertyTablesInvalidType.json │ │ │ ├── subtreeTileAvailabilityAvailableCountInvalid.json │ │ │ ├── subtreeTileAvailabilityAvailableCountMismatch.json │ │ │ ├── subtreeTileAvailabilityBitstreamAndConstant.json │ │ │ ├── subtreeTileAvailabilityBitstreamInvalidType.json │ │ │ ├── subtreeTileAvailabilityBitstreamInvalidValueA.json │ │ │ ├── subtreeTileAvailabilityBitstreamInvalidValueB.json │ │ │ ├── subtreeTileAvailabilityBitstreamInvalidValueC.json │ │ │ ├── subtreeTileAvailabilityBitstreamLengthTooLarge.json │ │ │ ├── subtreeTileAvailabilityBitstreamLengthTooSmall.json │ │ │ ├── subtreeTileAvailabilityConstantInvalidType.json │ │ │ ├── subtreeTileAvailabilityConstantInvalidValue.json │ │ │ ├── subtreeTileAvailabilityForParentMissingForAvailableTile.json │ │ │ ├── subtreeTileAvailabilityInvalidType.json │ │ │ ├── subtreeTileAvailabilityMissing.json │ │ │ ├── subtreeTileAvailabilityMissingForAvailableContent.json │ │ │ ├── subtreeTileAvailabilityNeitherBitstreamNorConstant.json │ │ │ ├── subtreeTileMetadataInvalidType.json │ │ │ ├── subtreeTileMetadataInvalidValueA.json │ │ │ ├── subtreeTileMetadataInvalidValueB.json │ │ │ ├── validSubtree-0-0-0.json │ │ │ ├── validSubtree.json │ │ │ ├── validSubtreeBuffersWithoutBufferViews.json │ │ │ ├── validSubtreeImplicitTiling.json.input │ │ │ └── validSubtreeNoBuffers.json │ │ └── tilesets/ │ │ ├── assetTilesetVersionInvalidType.json │ │ ├── assetVersionInvalidType.json │ │ ├── assetVersionMissing.json │ │ ├── assetVersionUnknown.json │ │ ├── boundingVolumeBoxArrayInvalidElementType.json │ │ ├── boundingVolumeBoxInvalidArrayLength.json │ │ ├── boundingVolumeMissingProperty.json │ │ ├── boundingVolumeRegionArrayElementsOutOfRange.json │ │ ├── boundingVolumeRegionArrayInvalidElementType.json │ │ ├── boundingVolumeRegionInvalidArrayLength.json │ │ ├── boundingVolumeSphereArrayElementOutOfRange.json │ │ ├── boundingVolumeSphereArrayInvalidElementType.json │ │ ├── boundingVolumeSphereInvalidArrayLength.json │ │ ├── customSemanticsSchema.json │ │ ├── extensionFoundButNotUsed.json │ │ ├── extensionNotDeclaredAsRequired.json │ │ ├── extensionNotDeclared_1_0_glTF.json │ │ ├── extensionNotNecessary_1_1_glTF.json │ │ ├── extensionRequiredButNotUsed.json │ │ ├── extensionUsedButNotFound.json │ │ ├── extensionsInvalidType.json │ │ ├── extensionsRequiredDuplicateElement.json │ │ ├── extensionsRequiredInvalidArrayLength.json │ │ ├── extensionsRequiredInvalidType.json │ │ ├── extensionsUsedDuplicateElement.json │ │ ├── extensionsUsedInvalidArrayLength.json │ │ ├── extensionsUsedInvalidType.json │ │ ├── extensionsValueInvalidType.json │ │ ├── externalTilesetExtensions/ │ │ │ ├── README.md │ │ │ ├── declaredInBothContainedInExternal/ │ │ │ │ ├── external.json │ │ │ │ └── tileset.json │ │ │ ├── declaredInBothContainedInTileset/ │ │ │ │ ├── external.json │ │ │ │ └── tileset.json │ │ │ ├── declaredInExternalContainedInExternal/ │ │ │ │ ├── external.json │ │ │ │ └── tileset.json │ │ │ ├── declaredInExternalContainedInTileset/ │ │ │ │ ├── external.json │ │ │ │ └── tileset.json │ │ │ ├── declaredInNoneContainedInExternal/ │ │ │ │ ├── external.json │ │ │ │ └── tileset.json │ │ │ ├── declaredInTilesetContainedInExternal/ │ │ │ │ ├── external.json │ │ │ │ └── tileset.json │ │ │ └── declaredInTilesetContainedInTileset/ │ │ │ ├── external.json │ │ │ └── tileset.json │ │ ├── extrasUnexpectedType.json │ │ ├── groupClassIdInvalid.json │ │ ├── groupClassIdInvalidType.json │ │ ├── groupWithoutSchema.json │ │ ├── implicitTilingAvailableLevelsInvalidType.json │ │ ├── implicitTilingAvailableLevelsInvalidValue.json │ │ ├── implicitTilingContentUriTemplateVariableInvalid.json │ │ ├── implicitTilingContentsUriTemplateVariableInvalid.json │ │ ├── implicitTilingInvalidType.json │ │ ├── implicitTilingRootWithChildren.json │ │ ├── implicitTilingRootWithContentBoundingVolume.json │ │ ├── implicitTilingRootWithMetadata.json │ │ ├── implicitTilingSubdivisionSchemeInvalidType.json │ │ ├── implicitTilingSubdivisionSchemeInvalidValue.json │ │ ├── implicitTilingSubtreeLevelsInvalidType.json │ │ ├── implicitTilingSubtreeLevelsInvalidValue.json │ │ ├── implicitTilingSubtreesInvalidType.json │ │ ├── implicitTilingSubtreesUriInvalidType.json │ │ ├── implicitTilingSubtreesUriMissing.json │ │ ├── implicitTilingSubtreesUriTemplateVariableInvalid.json │ │ ├── implicitTilingSubtreesUriTemplateVariableMissing.json │ │ ├── implicitTilingValid.json │ │ ├── implicitTilingWithBoundingSphere.json │ │ ├── invalidJson.json │ │ ├── packages/ │ │ │ ├── tilesetPackageWithWarnings/ │ │ │ │ ├── TriangleWithWarnings/ │ │ │ │ │ └── TriangleWithWarnings.gltf │ │ │ │ └── tileset.json │ │ │ ├── tilesetPackageWithWarnings.3dtiles │ │ │ ├── tilesetPackageWithWarnings.3tz │ │ │ ├── validTilesetPackage/ │ │ │ │ ├── Triangle/ │ │ │ │ │ └── Triangle.gltf │ │ │ │ └── tileset.json │ │ │ ├── validTilesetPackage.3dtiles │ │ │ ├── validTilesetPackage.3tz │ │ │ ├── validTilesetPackageZipped.3dtiles │ │ │ └── validTilesetPackageZipped.3tz │ │ ├── propertiesInvalidType.json │ │ ├── propertiesMaximumInvalidType.json │ │ ├── propertiesMaximumMissing.json │ │ ├── propertiesMinimumInvalidType.json │ │ ├── propertiesMinimumLargerThanMaximum.json │ │ ├── propertiesMinimumMissing.json │ │ ├── statisticsClassesIdInvalid.json │ │ ├── statisticsClassesInvalidType.json │ │ ├── statisticsClassesMinPropertiesMismatch.json │ │ ├── statisticsClassesPropertiesMinPropertiesMismatch.json │ │ ├── statisticsClassesPropertiesPropertyNameInvalid.json │ │ ├── statisticsClassesValueInvalidType.json │ │ ├── statisticsClassesWithoutSchema.json │ │ ├── tileChildrenEmptyArray.json │ │ ├── tileContentBoundingVolumeInvalidType.json │ │ ├── tileContentBoundingVolumeNotInTileBoundingVolume.json │ │ ├── tileContentBoundingVolumeWithRotationTransform.json │ │ ├── tileContentBoundingVolumeWithTransform.json │ │ ├── tileContentGroupInvalidIndex.json │ │ ├── tileContentGroupInvalidType.json │ │ ├── tileContentGroupNegativeIndex.json │ │ ├── tileContentGroupWithoutTilesetGroups.json │ │ ├── tileContentInvalidType.json │ │ ├── tileContentsInvalidType.json │ │ ├── tileGeometricErrorMissing.json │ │ ├── tileGeometricErrorNegative.json │ │ ├── tileGeometricErrorNotSmallerThanParentGeometricError.json │ │ ├── tileInvalidType.json │ │ ├── tileMetadataClassInvalid.json │ │ ├── tileMetadataClassInvalidType.json │ │ ├── tileMetadataClassMissing.json │ │ ├── tileMetadataGeometricErrorInconsistent.json │ │ ├── tileMetadataRequiredPropertyMissing.json │ │ ├── tileMetadataRequiredPropertyNull.json │ │ ├── tileMetadataScalarValueNotInRange.json │ │ ├── tileMetadataVec3ArrayElementValueNotInRange.json │ │ ├── tileMetadataVec3ElementValueNotInRange.json │ │ ├── tileMetadataWithoutSchema.json │ │ ├── tileRefineInvalidValue.json │ │ ├── tileRefineMissingInRoot.json │ │ ├── tileRefineMissingInRootOfExternal.json │ │ ├── tileRefineMissingInRootOfExternalA.json │ │ ├── tileRefineWrongCase.json │ │ ├── tileRefineWrongType.json │ │ ├── tileTransformInvalidArrayElementType.json │ │ ├── tileTransformInvalidArrayLength.json │ │ ├── tileTransformInvalidType.json │ │ ├── tileTransformNonInvertible.json │ │ ├── tileTransformNotAffine.json │ │ ├── tileWithContentAndContents.json │ │ ├── tiles/ │ │ │ ├── 3tz/ │ │ │ │ ├── invalid.3tz │ │ │ │ ├── simple.3tz │ │ │ │ └── withError.3tz │ │ │ ├── Notes.txt │ │ │ ├── b3dm/ │ │ │ │ ├── invalid.b3dm │ │ │ │ ├── invalidAlignment.b3dm │ │ │ │ ├── invalidDueToWrongAlignmentWithGlbWithInfos.b3dm │ │ │ │ ├── valid.b3dm │ │ │ │ └── validWithInvalidGlb.b3dm │ │ │ ├── cmpt/ │ │ │ │ └── validWithGlbInfo.cmpt │ │ │ ├── geojson/ │ │ │ │ └── lineString.geojson │ │ │ ├── geom/ │ │ │ │ └── content.geom │ │ │ ├── glTF/ │ │ │ │ ├── Triangle/ │ │ │ │ │ └── Triangle.gltf │ │ │ │ ├── TriangleGlbWithErrors/ │ │ │ │ │ └── TriangleGlbWithInvalidLength.glb │ │ │ │ ├── TriangleWithErrors/ │ │ │ │ │ └── TriangleWithErrors.gltf │ │ │ │ └── TriangleWithWarnings/ │ │ │ │ └── TriangleWithWarnings.gltf │ │ │ ├── i3dm/ │ │ │ │ ├── i3dmWithUri/ │ │ │ │ │ ├── Box.glb │ │ │ │ │ ├── README.md │ │ │ │ │ ├── i3dmWithUri.i3dm │ │ │ │ │ └── tileset.json │ │ │ │ └── invalid.i3dm │ │ │ ├── pnts/ │ │ │ │ └── invalid.pnts │ │ │ └── vctr/ │ │ │ └── parent.vctr │ │ ├── tilesetAssetMissing.json │ │ ├── tilesetGeometricErrorMissing.json │ │ ├── tilesetGeometricErrorNegative.json │ │ ├── tilesetMetadataEntityPropertyEnumInvalidValue.json │ │ ├── tilesetMetadataEntityPropertyMaxNotInRange.json │ │ ├── tilesetMetadataEntityPropertyMaxWithNormalizedNotInRange.json │ │ ├── tilesetMetadataEntityPropertyMaxWithOffsetNotInRange.json │ │ ├── tilesetMetadataEntityPropertyMaxWithScaleNotInRange.json │ │ ├── tilesetMetadataEntityPropertyMinNotInRange.json │ │ ├── tilesetMetadataEntityPropertyMinWithNormalizedNotInRange.json │ │ ├── tilesetMetadataEntityPropertyMinWithOffsetNotInRange.json │ │ ├── tilesetMetadataEntityPropertyMinWithScaleNotInRange.json │ │ ├── tilesetSchemaUriInvalidType.json │ │ ├── tilesetWithCycleA.json │ │ ├── tilesetWithCycleB.json │ │ ├── tilesetWithCycleC.json │ │ ├── tilesetWithMultipleExternal.json │ │ ├── tilesetWithMultipleExternalA.json │ │ ├── tilesetWithMultipleExternalA0.json │ │ ├── tilesetWithMultipleExternalA1.json │ │ ├── tilesetWithMultipleExternalB.json │ │ ├── tilesetWithSchemaAndSchemaUri.json │ │ ├── tilesetWithUnicodeBOM.json │ │ ├── validTileset.json │ │ ├── validTilesetWith3tzWithError.json │ │ ├── validTilesetWithCustomSemantics.json │ │ ├── validTilesetWithCustomSemanticsWithInvalidType.json │ │ ├── validTilesetWithExternalValidTilesetWithValidB3dmWithInvalidGlb.json │ │ ├── validTilesetWithGlbWithErrors.json │ │ ├── validTilesetWithGltfWithErrors.json │ │ ├── validTilesetWithGltfWithWarnings.json │ │ ├── validTilesetWithIB3dmWithInvalidAlignment.json │ │ ├── validTilesetWithInvalid3tz.json │ │ ├── validTilesetWithInvalidB3dm.json │ │ ├── validTilesetWithInvalidB3dmWithGlbWithInfos.json │ │ ├── validTilesetWithInvalidI3dm.json │ │ ├── validTilesetWithInvalidPnts.json │ │ ├── validTilesetWithInvalidSchemaFromUri.json │ │ ├── validTilesetWithSchema.json │ │ ├── validTilesetWithTileMetadata.json │ │ ├── validTilesetWithUnresolvableSchemaUri.json │ │ ├── validTilesetWithValid3tz.json │ │ ├── validTilesetWithValidB3dm.json │ │ ├── validTilesetWithValidB3dmWithInvalidGlb.json │ │ ├── validTilesetWithValidCmptWithGlbInfo.json │ │ ├── validTilesetWithValidGltf.json │ │ └── validTilesetWithValidSchemaFromUri.json │ ├── extensions/ │ │ ├── BoundingVolumeS2ValidationSpec.ts │ │ ├── ContentGltfValidationSpec.ts │ │ ├── MaxarContentGeojonValidationSpec.ts │ │ ├── MaxarExtentValidatorSpec.ts │ │ ├── MaxarGridValidationSpec.ts │ │ ├── MaxarGridValidatorSpec.ts │ │ ├── NgaGpmValidatorSpec.ts │ │ └── VriconClassValidationSpec.ts │ ├── gltfExtensions/ │ │ ├── ExtInstanceFeaturesValidationSpec.ts │ │ ├── ExtMeshFeaturesValidationSpec.ts │ │ ├── ExtStructuralMetadataValidationSpec.ts │ │ ├── ExtValidationSpec.ts │ │ ├── KhrLightsPunctualValidationSpec.ts │ │ ├── MaxarImageOrthoValidationSpec.ts │ │ ├── MaxarNonvisualGeometryValidationSpec.ts │ │ ├── MaxarTemporalLightTraits/ │ │ │ └── MaxarTemporalLightTraitsValidationSpec.ts │ │ ├── NgaGpmLocalValidationSpec.ts │ │ └── validateGltf.ts │ ├── jasmine.json │ └── metadata/ │ ├── BinaryPropertyTableValidationSpec.ts │ ├── BinaryPropertyTableValuesValidationSpec.ts │ ├── PropertyTableTestUtilities.ts │ └── PropertyTableValidationSpec.ts ├── src/ │ ├── ValidatorMain.ts │ ├── archives/ │ │ └── ArchiveValidation3tz.ts │ ├── base/ │ │ ├── ResourceError.ts │ │ ├── globMatcher.ts │ │ ├── readJsonUnchecked.ts │ │ └── writeUnchecked.ts │ ├── index.ts │ ├── issues/ │ │ ├── BinaryValidationIssues.ts │ │ ├── ContentValidationIssues.ts │ │ ├── GltfExtensionValidationIssues.ts │ │ ├── IoValidationIssue.ts │ │ ├── JsonValidationIssues.ts │ │ ├── MetadataValidationIssues.ts │ │ ├── SemanticValidationIssues.ts │ │ ├── StructureValidationIssues.ts │ │ ├── ValidationIssueUtils.ts │ │ └── ValidationIssues.ts │ ├── main.ts │ ├── tileFormats/ │ │ ├── B3dmValidator.ts │ │ ├── CmptValidator.ts │ │ ├── GeojsonValidator.ts │ │ ├── GltfValidator.ts │ │ ├── I3dmValidator.ts │ │ ├── PntsValidator.ts │ │ ├── TileFormatValidator.ts │ │ └── legacy/ │ │ ├── utility.ts │ │ ├── validateBatchTable.ts │ │ └── validateFeatureTable.ts │ └── validation/ │ ├── AssetValidator.ts │ ├── BasicValidator.ts │ ├── BinaryBufferStructureValidator.ts │ ├── BinaryValidator.ts │ ├── BoundingVolumeValidator.ts │ ├── ContentDataValidator.ts │ ├── ContentDataValidators.ts │ ├── ContentValidator.ts │ ├── ExtendedObjectsValidators.ts │ ├── ExtensionsDeclarationsValidator.ts │ ├── ImplicitTilingValidator.ts │ ├── NumberValidator.ts │ ├── PropertiesValidator.ts │ ├── RootPropertyValidator.ts │ ├── StatisticsClassValidator.ts │ ├── StatisticsValidator.ts │ ├── StringValidator.ts │ ├── StructureValidator.ts │ ├── SubtreeConsistencyValidator.ts │ ├── SubtreeInfoValidator.ts │ ├── SubtreeValidator.ts │ ├── TemplateUriValidator.ts │ ├── TileContentValidator.ts │ ├── TileValidator.ts │ ├── TilesetPackageValidator.ts │ ├── TilesetTraversingValidator.ts │ ├── TilesetValidator.ts │ ├── TransformValidator.ts │ ├── ValidatedElement.ts │ ├── ValidationContext.ts │ ├── ValidationContexts.ts │ ├── ValidationIssue.ts │ ├── ValidationIssueFilter.ts │ ├── ValidationIssueFilters.ts │ ├── ValidationIssueSeverity.ts │ ├── ValidationOptionChecks.ts │ ├── ValidationOptions.ts │ ├── ValidationResult.ts │ ├── ValidationResults.ts │ ├── ValidationState.ts │ ├── Validator.ts │ ├── Validators.ts │ ├── extensions/ │ │ ├── BoundingVolumeS2ValidationIssues.ts │ │ ├── BoundingVolumeS2Validator.ts │ │ ├── ContentGltfValidator.ts │ │ ├── MaxarContentGeojsonValidator.ts │ │ ├── MaxarExtentValidator.ts │ │ ├── MaxarGridValidator.ts │ │ ├── NgaGpmValidator.ts │ │ ├── gpm/ │ │ │ ├── NgaGpmValidationIssues.ts │ │ │ └── NgaGpmValidatorCommon.ts │ │ └── maxar/ │ │ └── MaxarValidatorCommon.ts │ ├── gltf/ │ │ ├── Accessors.ts │ │ ├── GltfData.ts │ │ ├── GltfDataReader.ts │ │ ├── GltfExtensionValidators.ts │ │ ├── ImageData.ts │ │ ├── ImageDataReader.ts │ │ ├── SamplerValidator.ts │ │ ├── TextureValidator.ts │ │ ├── gpmLocal/ │ │ │ └── NgaGpmLocalValidator.ts │ │ ├── imageOrtho/ │ │ │ └── MaxarImageOrthoValidator.ts │ │ ├── instanceFeatures/ │ │ │ └── ExtInstanceFeaturesValidator.ts │ │ ├── lightsPunctual/ │ │ │ ├── KhrLightsPunctualValidator.ts │ │ │ └── MaxarTemporalLightTraits/ │ │ │ └── MaxarTemporalLightTraitsValidator.ts │ │ ├── meshFeatures/ │ │ │ ├── ExtMeshFeaturesValidator.ts │ │ │ ├── FeatureIdAccessorValidator.ts │ │ │ └── FeatureIdValidator.ts │ │ ├── nonvisualGeometry/ │ │ │ └── MaxarNonvisualGeometryValidator.ts │ │ └── structuralMetadata/ │ │ ├── ExtStructuralMetadataValidator.ts │ │ ├── PropertyAttributePropertyModel.ts │ │ ├── PropertyAttributePropertyValidator.ts │ │ ├── PropertyAttributeValidator.ts │ │ ├── PropertyAttributeValuesValidator.ts │ │ ├── PropertyAttributesDefinitionValidator.ts │ │ ├── PropertyTableDefinitionValidator.ts │ │ ├── PropertyTextureBooleanMetadataPropertyModel.ts │ │ ├── PropertyTextureEnumMetadataPropertyModel.ts │ │ ├── PropertyTextureMetadataPropertyModels.ts │ │ ├── PropertyTextureNumericMetadataPropertyModel.ts │ │ ├── PropertyTexturePropertyValidator.ts │ │ ├── PropertyTextureValidator.ts │ │ ├── PropertyTextureValuesValidator.ts │ │ └── PropertyTexturesDefinitionValidator.ts │ ├── legacy/ │ │ └── BoundingVolumeChecks.ts │ └── metadata/ │ ├── BinaryPropertyTableDefaultMetadataPropertyModel.ts │ ├── BinaryPropertyTableEnumMetadataPropertyModel.ts │ ├── BinaryPropertyTableValidator.ts │ ├── BinaryPropertyTableValuesValidator.ts │ ├── ClassPropertySemanticsValidator.ts │ ├── ClassPropertyValidator.ts │ ├── ClassPropertyValueValidator.ts │ ├── MetadataClassValidator.ts │ ├── MetadataEntityValidator.ts │ ├── MetadataEnumValidator.ts │ ├── MetadataPropertyModel.ts │ ├── MetadataPropertyValidator.ts │ ├── MetadataPropertyValuesValidator.ts │ ├── MetadataStructureValidator.ts │ ├── MetadataValidationUtilities.ts │ ├── MetadataValueValidationMessages.ts │ ├── MetadataValueValidator.ts │ ├── PropertyTablePropertyValidator.ts │ ├── PropertyTableValidator.ts │ ├── PropertyTablesDefinitionValidator.ts │ ├── RangeIterables.ts │ ├── SchemaDefinitionValidator.ts │ └── SchemaValidator.ts ├── tools/ │ └── README.md └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .eslintignore ================================================ /build /dist /etc generateThirdParty.js ================================================ FILE: .eslintrc.json ================================================ { "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": 2020 }, "plugins": ["@typescript-eslint", "eslint-plugin-tsdoc"], "root": true, "rules": { "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-explicit-any": "off", "tsdoc/syntax": "warn" } } ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: [push, pull_request] env: CI: true jobs: build: runs-on: ubuntu-latest steps: - name: Check out repository uses: actions/checkout@v2 - name: Run npm install run: | npm install - name: Run linting run: | npm run eslint - name: Run formatting checks run: | npm run prettier-check - name: Run tests run: | npm run test - name: Run coverage run: | npm run coverage ================================================ FILE: .gitignore ================================================ /node_modules /build /dist /coverage /.nyc_output /.vscode tsdoc-metadata.json package-lock.json .eslintcache *.tgz ================================================ FILE: .npmignore ================================================ /specs /demos /tools /node_modules /dist /etc /coverage /.nyc_output /.github /.vscode /bin .eslintcache .eslintignore .eslintrc.json .gitignore .npmignore .nycrc .prettierrc.json .prettierignore tsconfig.json generateThirdParty.js ThirdParty.json api-extractor.jsonc *.tgz ================================================ FILE: .nycrc ================================================ { "exclude": [ "specs/**/*.ts" ], "include": [ "**/*.ts" ], "reporter": [ "html", "text", "text-summary" ] } ================================================ FILE: .prettierignore ================================================ * !src/**/ !specs/**/ !**/*.js !**/*.ts !**/*.json specs/data/**/ tsconfig.json .prettierrc.json ThirdParty.json ================================================ FILE: .prettierrc.json ================================================ {} ================================================ FILE: CHANGES.md ================================================ Version 0.6.1 - 2026-01-25 - Added validation for the `3DTILES_content_gltf` extension [#336](https://github.com/CesiumGS/3d-tiles-validator/pull/336) - Added validation for the `MAXAR_grid` extension [#337](https://github.com/CesiumGS/3d-tiles-validator/pull/337) - Added validation for the `MAXAR_extent` extension [#338](https://github.com/CesiumGS/3d-tiles-validator/pull/338), [#347](https://github.com/CesiumGS/3d-tiles-validator/pull/347), [#351](https://github.com/CesiumGS/3d-tiles-validator/pull/351) - Added validation for the `MAXAR_content_geojson` extension [#339](https://github.com/CesiumGS/3d-tiles-validator/pull/339) - Changed the validation issue type for string lengths that are invalid according to the `minLength/maxLength` definitions of the JSON schema from `ARRAY_LENGTH_MISMATCH` to `STRING_LENGTH_MISMATCH` [#340](https://github.com/CesiumGS/3d-tiles-validator/pull/340) - Added validation for the `MAXAR_image_ortho` glTF extension [#341](https://github.com/CesiumGS/3d-tiles-validator/pull/341) - Added validation for the `MAXAR_temporal_light_traits` glTF extension [#342](https://github.com/CesiumGS/3d-tiles-validator/pull/342) - Added validation for the `MAXAR_nonvisual_geometry` glTF extension [#343](https://github.com/CesiumGS/3d-tiles-validator/pull/343) - Fixed a case where a missing `extensionsRequired` declaration was not detected [#346](https://github.com/CesiumGS/3d-tiles-validator/pull/346) - Changed the mechanism for resolving semantic schema files to resolve them relative to the options file that defines them [#350](https://github.com/CesiumGS/3d-tiles-validator/pull/350) - Fixed MAXAR spatial reference system validation of S2 faces [#352](https://github.com/CesiumGS/3d-tiles-validator/pull/352) - Fixed a case where a validation issue was erroneously generated when a non-scalar class property defined valid `min/max` properties [#356](https://github.com/CesiumGS/3d-tiles-validator/pull/356) - Added validation of the values in binary property tables in glTF against the value ranges that have been defined in the schema [#357](https://github.com/CesiumGS/3d-tiles-validator/pull/357) - Build process: The CI will now fail when `eslint` generates warnings [#344](https://github.com/CesiumGS/3d-tiles-validator/pull/344) Version 0.6.0 - 2025-02-24 - Fixed a bug where a `BOUNDING_VOLUMES_INCONSISTENT` error was reported when a tile defined a `transform` [#328](https://github.com/CesiumGS/3d-tiles-validator/pull/328) - Allow users to provide schema files for validating custom metadata semantics [#329](https://github.com/CesiumGS/3d-tiles-validator/pull/329) - Do not emit warnings when encountering `MAXAR_content_geojson`, `VRICON_class`, or `VRICON_grid` extensions [#330](https://github.com/CesiumGS/3d-tiles-validator/pull/330) - Fixes for 3TZ validation [#331](https://github.com/CesiumGS/3d-tiles-validator/pull/331) - Fixed a bug where a 3TZ file could not be referred to with a relative path - Handled the case where completely invalid 3TZ files caused an `INTERNAL_ERROR` - Updated `3d-tiles-tools` version to `0.5.0` - Minor updates for the new `async` API that was introduced via [`3d-tiles-tools/pull/167`](https://github.com/CesiumGS/3d-tiles-tools/pull/167) - Includes a bugfix from [`3d-tiles-tools/pull/173](https://github.com/CesiumGS/3d-tiles-tools/pull/173) where 3TZ files that contained certain local ZIP file headers caused an internal error in the validator - Changed the severity of issues that have been generated for content types that are known but not validated (like `VCTR`, `GEOM`, and `GEOJSON`) from `WARNING` to `INFO` [#332](https://github.com/CesiumGS/3d-tiles-validator/pull/332) Version 0.5.1 - 2024-12-05 - The maximum number of issues that are reported for a single glTF asset is now limited ([#291](https://github.com/CesiumGS/3d-tiles-validator/pull/291)). - When the number of bytes that are required for a certain property texture property did not match the number of `channels`, then the validator reported this as an `ERROR`, with the type `TEXTURE_CHANNELS_OUT_OF_RANGE`. This could cause errors to be reported for the case of 16-bit channels in textures, where these numbers do not have to match. Now, these cases are only reported as a `WARNING`, of the type `TEXTURE_CHANNELS_SIZE_MISMATCH` ([#293](https://github.com/CesiumGS/3d-tiles-validator/pull/293)). - The `refine` property for tiles is optional in general, but _required_ for the root tile. The validator did not check this. Now, it reports a `TILE_REFINE_MISSING_IN_ROOT` error when the `refine` property is missing in a root tile ([#303](https://github.com/CesiumGS/3d-tiles-validator/pull/303)). - When encountering an invalid alignment in the binary data of legacy tile content files, the validator stopped the validation of these files, and only reported a `BINARY_INVALID_ALIGNMENT` error. Now, it will try to process the data despite the invalid alignment, and perform further validation steps, for example, of the binary glTF data ([#304](https://github.com/CesiumGS/3d-tiles-validator/pull/304)). - Fixed a bug where the validator erroneously reported validation error when external tilesets did not use extensions that had been declared in the `extensionsUsed` of the containing tileset ([#305](https://github.com/CesiumGS/3d-tiles-validator/pull/305)). - Added a convenience function to the `ValidationResult` class, to easily deserialize and post-process validation reports ([#307](https://github.com/CesiumGS/3d-tiles-validator/pull/307)). - Fixed a bug where the default value for `texCoord` properties of property texture was not handled properly ([#309](https://github.com/CesiumGS/3d-tiles-validator/pull/309)). - Added the option to define a severity threshold for content validation issues. Setting the `contentValidationIssueSeverity` in the validation config file will omit all content validation issues that are below this severity threshold ([#310](https://github.com/CesiumGS/3d-tiles-validator/pull/310)). - Fixed a bug where the validator reported an error for binary `.subtree` files that did not contain any buffers ([#313](https://github.com/CesiumGS/3d-tiles-validator/pull/313)). - Added support for the validation of the `NGA_gpm_local` glTF extension ([#316](https://github.com/CesiumGS/3d-tiles-validator/pull/316)). - Added support for the validation of the `NGA_gpm` 3D Tiles extension ([#319](https://github.com/CesiumGS/3d-tiles-validator/pull/319)). - Fixed a bug where the validator erroneously reported a `BOUNDING_VOLUMES_INCONSISTENT` error when a tile with a `transform` contained a `content` with a `boundingVolume` ([#322](https://github.com/CesiumGS/3d-tiles-validator/pull/322)). - Updated the underlying `3d-tiles-tools` dependency to include a fix for a bug where the validator reported an `INTERNAL_ERROR` when trying to validate a tileset that contains glTF that use the `EXT_meshopt_compression` extension ([#323](https://github.com/CesiumGS/3d-tiles-validator/issues/323)). - Fixed a bug where the semantics that are referred to as 'General Semantics' in the 3D Metadata Semantic Reference had been reported to be unknown with a `METADATA_SEMANTIC_UNKNOWN` message ([#325](https://github.com/CesiumGS/3d-tiles-validator/pull/325)). Version 0.5.0 - 2023-10-24 - Added validation of glTF extensions via [#280](https://github.com/CesiumGS/3d-tiles-validator/pull/280) and [#284](https://github.com/CesiumGS/3d-tiles-validator/pull/284). In addition to the basic validation of glTF tile content that is performed with the glTF validator, the 3D Tiles Validator now checks the validity of certain glTF extensions: - For `EXT_mesh_features`, it will check the validity of feature ID attributes and feature ID textures - For `EXT_instance_features`, it will check the validity of the feature ID attributes that refer to the `EXT_mesh_gpu_instancing` extension - For `EXT_structural_metadata`, it will check the validity of the metadata schema definition, property tables, property attributes, and property textures - Added a command line functionality for validating single tile content files (glTF/GLB, B3DM, I3DM, PNTS, and CMPT), via [#285](https://github.com/CesiumGS/3d-tiles-validator/pull/285) - When an I3DM refers to an external glTF asset with a URI, then the URI has to be padded with `0x20` (space) bytes if necessary to satisfy the alignment requirements. The validator only accepted `0x00` (zero) bytes as padding bytes. Now the validator properly handles trailing spaces, and reports the presence of zero-bytes with a validation warning ([#276](https://github.com/CesiumGS/3d-tiles-validator/issues/276)) - Changed the severity level of validation issues: - The case that the `geometricError` of a tile was larger than the `geometricError` of its parent was reported as an `ERROR`. The specification does not explicitly disallow this, so it is now only treated as a `WARNING` ([#286](https://github.com/CesiumGS/3d-tiles-validator/issues/286)) - An empty `children` array in a tile was treated as an `ERROR`, but is now treated as a `WARNING`, via [#288](https://github.com/CesiumGS/3d-tiles-validator/pull/288) Version 0.4.1 - 2023-05-02 - Moved most of the internal implementation into the `3d-tiles-tools`, and replaced it with a dependency to `3d-tiles-tools` - Detect cycles in external tilesets ([#269](https://github.com/CesiumGS/3d-tiles-validator/issues/269)) - Handle 3D Tiles packages that contain entries that are individually compressed with GZIP Version 0.4.0 - 2023-01-31 - Padding bytes in B3DM that had only be inserted to align its length to 8 bytes had not been handled properly, and caused unwanted validation warnings. This case is now handled by restricting the glTF validation to the GLB _without_ padding bytes ([#256](https://github.com/CesiumGS/3d-tiles-validator/issues/256)) - When a tileset referred to glTF (JSON) data that could not be resolved, then this was ignored. Now, it creates an error saying that the data could not be resolved. The treatment of non-resolvable data might be configured with validation options in the future (see https://github.com/CesiumGS/3d-tiles-validator/issues/224) - When the glTF validator generated messages with the "hint" severity, these had not been shown in the tileset validation report. Now, they show up as issues with the `INFO` severity level. - The `tile.transform` matrices had been checked to be invertible. Now they are checked to be affine ([#262](https://github.com/CesiumGS/3d-tiles-validator/issues/262)). - Fixed a bug where the validation of PNTS caused wrong validation issues for the batch table length for batched point clouds. - Added experimental support for validating tileset package files. The `--tilesetFile` that is given at the command line can now also be a 3TZ or 3DTILES file. - When input JSON files contained a Unicode BOM (Byte Order Mark), the validator reported a `JSON_PARSE_ERROR` without information about the reason for the parsing error. Now it reports an `IO_ERROR` with a helpful error message. Version 0.3.0 - 2022-12-20 - Updated the packaging so that the validator can more easily be executed as a command line tool after installing - Updated the scripts in `package.json` to simplify the packaging process Version 0.2.0 - 2022-12-13 - Add support for validation options that allow to include/exclude certain content types for the validation. These options can either be given via the `--optionsFile` command line argument, or passed as an optional parameter to `Validators.validateTilesetFile`. - Fixed a bug where the content data was not validated when the validator was used as a library ([#248](https://github.com/CesiumGS/3d-tiles-validator/issues/248)) - Fixed a bug that caused validation errors for `statistics.class` properties - When a tileset input file did not exist, the validator generated a `JSON_PARSE_ERROR`. Now it generates an `IO_ERROR` (including the file path) instead. - Dependency updates: - Updated `better-sqlite3` from `7.5.3` to `8.0.1` (for compatibility with Node 19 - see [#245](https://github.com/CesiumGS/3d-tiles-validator/issues/245)) - Removed `jasmine-node` - Removed `tsconfig/node16` - Reduced `engines.node` version from `>=16.0.0` to `>=14.0.0` Version 0.1.0 - 2022-11-29 - Initial release ================================================ FILE: IMPLEMENTATION.md ================================================ # 3D Tiles Validator Implementation Notes Parts of the current implementation may still change. This page is only a short description of the overall structure. ## Directory structure: - `./src`: The entry point for the command line interface is in `main.ts` - `./src/validation`: The core classes for the 3D Tiles validation - `./src/issues`: Classes defining the categories of detected issues - `./src/tileFormats`: Classes for the validation of tile contents - `./src/archives`: Functions that are specific for the validation of 3TZ archives/packages - `./specs`: Jasmine specs - `./specs/data`: Test data ## Overview The classes in the `./src/validation` directory are the core classes for the 3D Tiles validation. The entry point for the tileset validation is the `TilesetValidator` class. This class is not publicly visible, but it is the main class that is used in the public `Validators.validateTilesetFile` method. The validation process, as it is implemented in the `TilesetValidator`, is: - It receives a tileset JSON string and parses it into a `Tileset` object from the `structure` package of the `3d-tiles-tools` - It traverses the `Tileset` structure, and performs the validation - For each object type, there is a validator, like `AssetValidator`, `ContentValidator`, `TileValidator`, `BoundingVolumeValidator` etc. For now, these are mainly classes with single static functions, but they might be refined for some objects. Each validation function receives a `ValidationContext` as the last parameter. The `ValidationContext` class: - Contains a `ValidationOptions` object that contains configuration options for the validation process (e.g. flags that determine whether tile content should be validated) - Maintains a `ResourceResolver` that reads a `Buffer` from a given URI (resolved in the respective context - the tileset, external tileset, or glTF) - Collects the `ValidationIssue` instances (errors and warnings) that are found during the traversal The `ValidationIssue` class and its types: - The `ValidationIssue` itself is a plain data structure with basic info about the issue (message, path, severity...) - Instances of this class are created with methods in the `issues*` classes, roughly categorized here: - `IoValidationIssues.ts`: Fundamental IO errors, like `JSON_PARSE_ERROR` - `JsonValidationIssues.ts`: Violations of the JSON schema, like `PROPERTY_MISSING` or `ARRAY_LENGTH_MISMATCH` - `StructureValidationIssues.ts`: General, inconsistent structures, like `IDENTIFIER_NOT_FOUND` - `SemanticValidationIssues.ts`: Inconsistent property values, like `TILE_GEOMETRIC_ERRORS_INCONSISTENT` - `MetadataValidationIssues.ts`: Invalid metadata schema and values - `BinaryValidationIssues.ts`: Invalid data layouts of binary tile content data - `ContentValidationIssues.ts`: Issues that are found in tile content or external tilesets - For validation issues that refer to the tile content, each `ValidationIssue` can have an array of `causes`. This can be filled, for example, with the information from the glTF validator that caused the validation to fail ## Future Work Certain functionalities are currently offered via the command line, but only intended for internal use: #### Validate a single metadata schema file: ``` npx ts-node src/main.ts --metadataSchemaFile specs/data/schemas/validSchema.json ``` #### Validate a single subtree file: **Note:** For the actual validation of standalone subtree files, there has to be a mechanism for passing in the information about the expected _structure_ of the subtree (namely, the information from the `implicitTiling` object). This example only refers to the files in the `specs` directory, which all assume the same subtree structure for now. ``` npx ts-node src/main.ts --subtreeFile specs/data/subtrees/binarySubtreeValid.subtree ``` #### Batch runs for the spec files The `specs/data` directory contains sample files that cause different validation issues. These files can be processed with ``` npx ts-node src/main.ts --tilesetSpecs npx ts-node src/main.ts --metadataSchemaSpecs npx ts-node src/main.ts --subtreeSpecs ``` ## API Definition The API definition is tracked with https://api-extractor.com After running `npm install`, the API documentation can be created with `npm run docs`. The API documentation will be written into the `build/docs` directory. The surface API information will be written into `etc/3d-tiles-validator.api.md`. This file captures the public API, and changes in the public API will cause a warning to be printed > Warning: You have changed the public API signature for this project. Updating etc/3d-tiles-validator.api.md This API definition file is tracked with Git, so changes in this file should be reviewed carefully. ## Release Process - Prepare the actual release: - Update `CHANGES.md` - Update the version number in `package.json` - Generate the tarball for the release: `npm run package` This will run the required scripts from the `package.json`: - Clean the build output folder - Prepare the package: - Perform linting - Check formatting - Build (compile TypeScript to JavaScript) - Run the unit tests - Generate the documentation - Update the third-party information - Package the build output folder into a TAR file - Verify the contents of the resulting TAR file. If there are unwanted files, add these files to `.npmignore` and re-generate the tarball - Create a git tag for the version and push it: `git tag -a v1.2.3 -m "Release of version 1.2.3"` `git push origin v1.2.3` - Publish the package: `npm publish` ### Build Scripts The build scripts that are used for the release process are documented with `about:`_``_ in the `package.json` file. Each of these comments indicates the goal and preconditions for running the respective step. The structure of these scripts is often organized hierarchically: - `docs` - `build` - `docs-generate` - `docs-prepare-directory` - `docs-extract-api`, - `docs-generate-markdown`, The intention is to make sure that each "top-level" (single-word) script can be executed without any preconditions (athough this pattern may not be applied for all steps). Intermediate steps can be executed manually or as part of other steps when it is ensured that the respective preconditions are met. The following `devDependencies` are *only* used for the implementation of the build process: - `mkdirp` - To generate the `etc` output directory for the API definition file (if it does not exist yet) - `del-cli` - To delete the contents of the `build` output folder - `copyfiles` - To copy the `bin/main` file to the build folder (see `bin/README.md` for details) ================================================ FILE: LICENSE.md ================================================ Copyright 2016-2022 CesiumGS, Inc. and Contributors Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2016-2020 Cesium GS, Inc. and Contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ # 3D Tiles Validator A validator for [3D Tiles](https://github.com/CesiumGS/3d-tiles). > **A note about the repository structure** > > This repository originally contained multiple projects. Now, these projects are maintained in separate repositories: > > - The `3d-tiles-tools` can be found in [the `3d-tiles-tools` repository](https://github.com/CesiumGS/3d-tiles-tools) > - The `3d-tiles-samples-generator` can be found in [the `3d-tiles-samples-generator` repository](https://github.com/CesiumGS/3d-tiles-samples-generator) > ## Overview The 3D Tiles validator can be used to validate 3D Tiles tilesets and their associated tile content data. It supports version 1.0 and version 1.1 of the 3D Tiles specification. The validator can be used as a command line tool, or as a library. **Note**: Some of the implementation and interfaces may still change. This refers to the source code as well as details of the command line interface and report format. ### Implemented Features - Validation of the JSON structure of the `tileset.json` file - Validation of the 3D Tiles [Tile Formats](https://github.com/CesiumGS/3d-tiles/tree/main/specification/TileFormats) - The supported tile formats are: Batched 3D Model (`b3dm`), Instanced 3D Model (`i3dm`), Point Cloud (`pnts`), Composite (`cmpt`) - glTF tile content is validated with the [glTF Validator](https://github.com/KhronosGroup/glTF-Validator) - Validation of implicit tilesets - Validation of 3D Tiles Metadata - This includes the validation of the JSON structure of the metadata, as well as the structure and ranges of metadata values, both for the JSON based representation and for the binary metadata that is stored in property tables - A basic validation of the [`3DTILES_bounding_volume_S2` extension](https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_bounding_volume_S2) - Validation of tilesets that are contained in 3D Tiles package files (3TZ and 3DTILES files) ## Installation In order to install the validator locally into a directory, run ``` npm install 3d-tiles-validator ``` (If you want to work directly with a clone of the Git repository, see [Developer Setup](#developer-setup)) ## Command Line Usage #### Validate a single tileset file ``` npx 3d-tiles-validator --tilesetFile specs/data/Samples/SparseImplicitQuadtree/tileset.json ``` The input file can either be a tileset JSON file, or one of the known tileset package files. The known package file formats are 3TZ (a package format based on ZIP), and 3DTILES (a package format based on SQLite). The type of the input is determined from the file extension, which may be `.3tz` or `.3dtiles` (case-insensitively). For example, to validate a 3TZ file: ``` npx 3d-tiles-validator --tilesetFile ./specs/data/tilesets/packages/validTilesetPackage.3tz ``` #### Validate a set of tileset files ``` npx 3d-tiles-validator --tilesetsDirectory specs/data/Samples/ ``` This will validate all tileset files in the given directory and all its subdirectories. The tileset files are identified by matching the file name against the glob pattern `**/*tileset*.json`. The pattern can be configured with the `tilesetGlobPattern` parameter. For example, in order to treat all .json files as tileset files: ``` npx 3d-tiles-validator --tilesetsDirectory specs/data/Samples/ --tilesetGlobPattern **/*.json ``` #### Validate a tile content file ``` npx 3d-tiles-validator --tileContentFile specs/data/gltfExtensions/FeatureIdAttributeAndPropertyTableFeatureIdNotInRange.gltf ``` The input file can be any of the content types that are supported by the validator. This includes B3DM, I3DM, PNTS, CMPT, and glTF/GLB files. The type of the file will be determined, and if it is not a known type, then a validation warning will be created. ### Report Files By default, validation reports are printed to the console. When validating a single file, then the `reportFile` argument can be used to specify the output file for the validation report. For example: ``` npx 3d-tiles-validator --tilesetFile specs/data/Samples/TilesetWithFullMetadata/tileset.json --reportFile MY_REPORT.json ``` Alternatively, or when validating multiple files, the `writeReports` argument can be used to write report files into the same directory as the input files. The name of the report file will be derived from the input file name. ``` npx 3d-tiles-validator --tilesetsDirectory specs/data/Samples/ --writeReports ``` ### Option Files Options for the validation process can be specified in a file that is given via the `--optionsFile` argument: ``` npx 3d-tiles-validator --optionsFile exampleOptions.json ``` The options represent the properties of the `ValidationOptions` class. For example, using the following `exampleOptions.json` file, then the validator will only validate the tileset JSON structure, but _no_ tile content data: ```JSON { "validateContentData": false } ``` The following options will cause the validator to _include_ B3DM- and GLB files in the validation process, but ignore all other content types: ```JSON { "includeContentTypes": [ "CONTENT_TYPE_B3DM", "CONTENT_TYPE_GLB" ] } ``` The following options will cause the validator to _exclude_ tileset files (i.e. external tilesets) during the validation: ```JSON { "excludeContentTypes": [ "CONTENT_TYPE_TILESET" ] } ``` The options can also be part of a configuration file, as described in the next section. ### Configuration Files The command line arguments for a validator run can be summarized in a configuration file that is given with the `--configFile` argument. For example, when running the validator with ``` npx 3d-tiles-validator --configFile exampleConfig.json ``` using the following `exampleConfig.json` file ```JSON { "tilesetsDirectory": "specs/data/tilesets", "tilesetGlobPattern": "**/*.json" } ``` then the validator will validate all files in the given directory that match the given glob pattern. The configuration can also contain an `options` object. This object summarizes the validation options, as described in the [Option Files](#option-files) section. For example: ```JSON { "tilesetsDirectory": "specs/data/tilesets", "tilesetGlobPattern": "**/*.json", "options": { "includeContentTypes": [ "CONTENT_TYPE_B3DM", "CONTENT_TYPE_GLB" ] } } ``` This will cause the validator to validate all JSON files in the specified directory, but only consider B3DM- and GLB tile content data during the validation. ### Custom Metadata Semantics The [3D Metadata Specification](https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata) allows for the definition of custom _semantics_ for metadata properties. The built-in semantics are described in the [3D Metadata Semantic Reference](https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata/Semantics). For other semantics, the validator will by default generate a `METADATA_SEMANTIC_UNKNOWN` issue. To avoid these warnings, clients can define their own semantics in a metadata schema file, so that they are taken into account during the validation process. Some details of this process might still change (see [`3d-tiles/issues/643`](https://github.com/CesiumGS/3d-tiles/issues/643) for a discussion). But the current state of the support of metadata semantics validation in the 3D Tiles Validator is described here. #### Metadata Semantics Schema A 'semantics schema' is a [3D Metadata Schema](https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata#schema) file that describes the _semantics_ that may appear in another metadata schema. In a semantics schema, the property names are just the names of the semantics. For example, when a client wants to define a semantic for a class like `ExampleClass`, and this semantic has the name `EXAMPLE_SEMANTIC`, then this structure can be represented in a semantics schema file as follows: **`exampleSemanticsSchema.json`:** ```json { "id": "Example-Semantics-0.0.0", "description": "A metadata schema where each class property has a name that represents one possible semantic of a metadata property, and that is used for validating semantics, by passing it in as one of the 'semanticSchemaFileNames' of the validation options", "classes": { "ExampleClassSemantics": { "description": "A class where each property is a semantic for a property of the 'ExampleClass'", "properties": { "EXAMPLE_SEMANTIC": { "name": "The 'EXAMPLE_SEMANTIC' structure", "description": "The structure that a property must have so that it can have the 'EXAMPLE_SEMANTIC'", "type": "SCALAR", "componentType": "FLOAT32" } } } } } ``` > Note: > > This schema file contains elaborate names and descriptions. These are optional on a technical level. An equivalent schema file is > ```json > { > "id": "Example-Semantics-0.0.0", > "classes": { > "ExampleClassSemantics": { > "properties": { > "EXAMPLE_SEMANTIC": { > "type": "SCALAR", > "componentType": "FLOAT32" > } > } > } > } > } > ``` > But adding names and descriptions is strongly recommended for documentation purposes. #### Metadata Semantics Schema Registration In order to include a 'semantics schema' in the validation process, the name of the schema file can be passed to the validator, as part of the validation options: **`exampleOptions.json`:** ```json { "semanticSchemaFileNames": ["exampleSemanticsSchema.json"] } ``` Note: Relative paths in the `semanticSchemaFileNames` array are resolved relative to the directory of the options file (`--optionsFile`) This options file can then be passed to the validator: ``` npx 3d-tiles-validator --optionsFile exampleOptions.json -t ./data/exampleTileset.json ``` The validator will then validate the semantics that are defined in the tileset JSON against the structure that was defined in the semantics schema. ## Developer Setup When the validator is not installed as a package from NPM, but supposed to be used directly in a cloned repository, then the command line usage is as follows: - Clone the repository into the current directory: ``` git clone https://github.com/CesiumGS/3d-tiles-validator ``` - Change into the directory of the cloned repository: ``` cd 3d-tiles-validator ``` - Install the validator and all its dependencies: ``` npm install ``` After this, `ts-node` can be used to directly execute the validator, using the same command line options as described above - for example, to validate a single tileset file: ``` npx ts-node src/main.ts --tilesetFile specs/data/Samples/SparseImplicitQuadtree/tileset.json ``` ## Library Usage The basic usage of the validator as a library is shown here: ```JavaScript const { Validators } = require("3d-tiles-validator"); const resultPromise = Validators.validateTilesetFile("example.json"); resultPromise.then((result) => { console.log(result.serialize()); }); ``` The `Validators.validateTilesetFile` receives a file name, and returns a promise to the `ValidationResult`, which can then be printed to the console. The second (optional) parameter is a `ValidationOptions` object that summarizes the options for the validation process (also see [Option Files](#option-files)). ### Validation Result Filtering Clients can perform basic filtering operations on a `ValidationResult`, in order to remove validation issues that are below a certain severity level, or warnings that are anticipated in a certain application context. For example, a given validation result can be filtered to - include validation issues that have the severity `ERROR` - exclude validation issues that have the type `EXTENSION_NOT_SUPPORTED` An example of applying such a filter to a given validation result is shown here: ```JavaScript const { Validators, ValidationIssueFilters, ValidationIssueSeverity } = require("3d-tiles-validator"); const resultPromise = Validators.validateTilesetFile("example.json"); resultPromise.then((result) => { const filteredResult = result .filter(ValidationIssueFilters.byIncludedSeverities(ValidationIssueSeverity.ERROR)) .filter(ValidationIssueFilters.byExcludedTypes("EXTENSION_NOT_SUPPORTED")); console.log(filteredResult.serialize()); }); ``` **Note**: The `type` strings that are used for describing and categorizing the validation issues are not part of the core API. These strings might change between minor- or patch releases. But changes will be pointed out in the change log. ## Implementation Notes See [`IMPLEMENTATION.md`](IMPLEMENTATION.md) for implementation notes. ================================================ FILE: ThirdParty.json ================================================ [ { "name": "3d-tiles-tools", "license": [ "Apache-2.0" ], "version": "0.5.0", "url": "https://www.npmjs.com/package/3d-tiles-tools" }, { "name": "@gltf-transform/core", "license": [ "MIT" ], "version": "3.10.1", "url": "https://www.npmjs.com/package/@gltf-transform/core" }, { "name": "@gltf-transform/extensions", "license": [ "MIT" ], "version": "3.10.1", "url": "https://www.npmjs.com/package/@gltf-transform/extensions" }, { "name": "@gltf-transform/functions", "license": [ "MIT" ], "version": "3.10.1", "url": "https://www.npmjs.com/package/@gltf-transform/functions" }, { "name": "cesium", "license": [ "Apache-2.0" ], "version": "1.124.0", "url": "https://www.npmjs.com/package/cesium" }, { "name": "gltf-validator", "license": [ "Apache-2.0" ], "version": "2.0.0-dev.3.10", "url": "https://www.npmjs.com/package/gltf-validator" }, { "name": "minimatch", "license": [ "ISC" ], "version": "5.1.6", "url": "https://www.npmjs.com/package/minimatch" }, { "name": "node-stream-zip", "license": [ "MIT" ], "version": "1.15.0", "url": "https://www.npmjs.com/package/node-stream-zip" }, { "name": "sharp", "license": [ "Apache-2.0" ], "version": "0.32.6", "url": "https://www.npmjs.com/package/sharp" }, { "name": "yargs", "license": [ "MIT" ], "version": "17.7.2", "url": "https://www.npmjs.com/package/yargs" } ] ================================================ FILE: api-extractor.jsonc ================================================ /** * Config file for API Extractor. For more info, please visit: https://api-extractor.com */ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", /** * (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor * analyzes the symbols exported by this module. * * The file extension must be ".d.ts" and not ".ts". * * The path is resolved relative to the folder of the config file that contains the setting; to change this, * prepend a folder token such as "". * * SUPPORTED TOKENS: , , */ "mainEntryPointFilePath": "build/index.d.ts", /** * Configures how the API report file (*.api.md) will be generated. */ "apiReport": { /** * (REQUIRED) Whether to generate an API report. */ "enabled": true, /** * Specifies the folder where the temporary report file is written. The file name portion is determined by * the "reportFileName" setting. * * After the temporary file is written to disk, it is compared with the file in the "reportFolder". * If they are different, a production build will fail. * * The path is resolved relative to the folder of the config file that contains the setting; to change this, * prepend a folder token such as "". * * SUPPORTED TOKENS: , , * DEFAULT VALUE: "/temp/" */ "reportTempFolder": "/build/api-extractor" }, /** * Configures how the doc model file (*.api.json) will be generated. */ "docModel": { /** * (REQUIRED) Whether to generate a doc model file. */ "enabled": true, /** * The output path for the doc model file. The file extension should be ".api.json". * * The path is resolved relative to the folder of the config file that contains the setting; to change this, * prepend a folder token such as "". * * SUPPORTED TOKENS: , , * DEFAULT VALUE: "/temp/.api.json" */ "apiJsonFilePath": "/build/api-extractor/.api.json" }, /** * Configures how the .d.ts rollup file will be generated. */ "dtsRollup": { /** * (REQUIRED) Whether to generate the .d.ts rollup file. */ "enabled": true }, } ================================================ FILE: bin/README.md ================================================ The `main` file in this directory is the entry point for the validator application when it is installed from an NPM package. It is defined as the entry point via the `bin` property of the main `package.json`. It only sets up the Node execution environment for the validator, as required as of https://docs.npmjs.com/cli/v9/configuring-npm/package-json#bin . Beyond that, it just includes `main.js`. It is copied to the `build` directory by the `package-copy` script of the `package.json`, before generating the release package (similar to https://github.com/microsoft/TypeScript/blob/main/bin ) ================================================ FILE: bin/main ================================================ #!/usr/bin/env node require('./main.js') ================================================ FILE: demos/README.md ================================================ ### Demos These are small command-line demos that show how to use various parts of the API. **Note that not everything that is shown in these demos is part of a _public_ API!** The demos that show the basic usage of the _public_ API are the following: - [`validationResultDemos.ts`](validationResultDemos.ts) : Shows how to perform filtering operations on a `ValidationResult` that is returned from `Validators.validateTilesetFile`. It creates a "dummy" `ValidationResult` instance and then filters it based on different criteria. - [`validationOptionsDemo.ts`](validationOptionsDemo.ts) : Shows the effect of the `ValidationOptions` that can be passed to `Validators.validateTilesetFile`. It shows how to include/exclude certain content types in the validation process. ================================================ FILE: demos/validationOptionsDemo.ts ================================================ import { ContentDataTypes } from "3d-tiles-tools"; import { Validators, ValidationOptions, } from "../src"; async function runWithIncluded() { // Options that list the included types, including B3DM: const options = ValidationOptions.fromJson({ validateContentData: true, // The default includeContentTypes: [ ContentDataTypes.CONTENT_TYPE_B3DM, // Explicitly included here ], excludeContentTypes: undefined, // The default }); const tilesetFile = "specs/data/tilesets/validTilesetWithInvalidB3dm.json"; const result = await Validators.validateTilesetFile(tilesetFile, options); console.log("Result of validating a tileset with an invalid B3DM, ") console.log("with the B3MD content type being INcluded:") console.log(result.serialize()); console.log("-".repeat(80)); } async function runWithoutIncluded() { // Options that list the included types, NOT including B3DM: const options = ValidationOptions.fromJson({ validateContentData: true, // The default includeContentTypes: [ //ContentDataTypes.CONTENT_TYPE_B3DM, // Not included here! ], excludeContentTypes: undefined, // The default }); const tilesetFile = "specs/data/tilesets/validTilesetWithInvalidB3dm.json"; const result = await Validators.validateTilesetFile(tilesetFile, options); console.log("Result of validating a tileset with an invalid B3DM, ") console.log("with the B3MD content type NOT being INcluded:") console.log(result.serialize()); console.log("-".repeat(80)); } async function runWithExcluded() { // Options that list the included types, EXcluding B3DM: const options = ValidationOptions.fromJson({ validateContentData: true, // The default includeContentTypes: undefined, // The default excludeContentTypes: [ ContentDataTypes.CONTENT_TYPE_B3DM // Explicitly excluded here ] }); const tilesetFile = "specs/data/tilesets/validTilesetWithInvalidB3dm.json"; const result = await Validators.validateTilesetFile(tilesetFile, options); console.log("Result of validating a tileset with an invalid B3DM, ") console.log("with the B3MD content type being EXcluded:") console.log(result.serialize()); console.log("-".repeat(80)); } async function runWithoutExcluded() { // Options that list the included types, NOT excluding B3DM: const options = ValidationOptions.fromJson({ validateContentData: true, // The default includeContentTypes: undefined, // The default excludeContentTypes: [ // ContentDataTypes.CONTENT_TYPE_B3DM // NOT Excluded here ] }); const tilesetFile = "specs/data/tilesets/validTilesetWithInvalidB3dm.json"; const result = await Validators.validateTilesetFile(tilesetFile, options); console.log("Result of validating a tileset with an invalid B3DM, ") console.log("the B3MD content type NOT being EXcluded:") console.log(result.serialize()); console.log("-".repeat(80)); } async function runDemo() { await runWithIncluded(); await runWithoutIncluded(); await runWithExcluded(); await runWithoutExcluded(); } runDemo(); ================================================ FILE: demos/validationResultDemos.ts ================================================ import { ValidationIssue } from "../src/validation/ValidationIssue"; import { ValidationIssueSeverity } from "../src/validation/ValidationIssueSeverity"; import { ValidationResult } from "../src/validation/ValidationResult"; import { ValidationIssueFilters } from "../src/validation/ValidationIssueFilters"; import { ValidationResults } from "../src/validation/ValidationResults"; // A function to create an unspecified `ValidationResult` // that contains dummy issues for demonstrating the // validation result filtering options function createDemoResult() { function createError(id: string) { const issue = new ValidationIssue( `EXAMPLE_ERROR_${id}`, "example", `Example Error ${id}`, ValidationIssueSeverity.ERROR ); return issue; } function createWarning(id: string) { const issue = new ValidationIssue( `EXAMPLE_WARNING_${id}`, "example", `Example Warning ${id}`, ValidationIssueSeverity.WARNING ); return issue; } function createInfo(id: string) { const issue = new ValidationIssue( `EXAMPLE_INFO_${id}`, "example", `Example Info ${id}`, ValidationIssueSeverity.INFO ); return issue; } function createContentWarning(id: string, childId: string) { const issue = new ValidationIssue( `EXAMPLE_CONTENT_WARNING_${id}`, "example/content/" + childId, `Example Content Warning ${id}`, ValidationIssueSeverity.WARNING ); issue.addCause(createWarning(id + childId)); issue.addCause(createInfo(id + childId)); return issue; } function createContentError(id: string, childId: string) { const issue = new ValidationIssue( `EXAMPLE_CONTENT_ERROR_${id}`, "example/content/" + childId, `Example Content Error ${id}`, ValidationIssueSeverity.ERROR ); issue.addCause(createError(id + childId)); issue.addCause(createWarning(id + childId)); issue.addCause(createInfo(id + childId)); return issue; } function createNestedContentError( id: string, childId: string, grandChildId: string ) { const issue = new ValidationIssue( `EXAMPLE_CONTENT_ERROR_${id}`, "example/content/" + childId, `Example Content Error ${id}`, ValidationIssueSeverity.ERROR ); issue.addCause(createContentError(id, childId + grandChildId)); issue.addCause(createContentWarning(id, childId + grandChildId)); issue.addCause(createError(id + childId)); issue.addCause(createWarning(id + childId)); issue.addCause(createInfo(id + childId)); return issue; } const result = ValidationResult.create(); result.add(createError("A")); result.add(createWarning("A")); result.add(createInfo("A")); result.add(createContentWarning("B", "0")); result.add(createContentWarning("B", "1")); result.add(createError("C")); result.add(createWarning("C")); result.add(createInfo("C")); result.add(createContentError("D", "0")); result.add(createContentError("D", "1")); result.add(createNestedContentError("E", "0", "x")); return result; } // A function that demonstrates the basic validation // result filtering functionality function validationResultFilterDemo() { const result = createDemoResult(); console.log("Initial:"); console.log(ValidationResults.createSimpleResultString(result)); // Create some shortcuts for this demo: const byIncludedSeverities = ValidationIssueFilters.byIncludedSeverities; const byExcludedTypes = ValidationIssueFilters.byExcludedTypes; const ERROR = ValidationIssueSeverity.ERROR; const INFO = ValidationIssueSeverity.INFO; // Demonstrate basic filtering: console.log("Filtered by severities and types"); console.log(" - include severities ERROR and INFO"); console.log(" - exclude types EXAMPLE_ERROR_A and EXAMPLE_INFO_C"); const filtered = result .filter(byIncludedSeverities(ERROR, INFO)) .filter(byExcludedTypes("EXAMPLE_ERROR_A", "EXAMPLE_INFO_C")); console.log(ValidationResults.createSimpleResultString(filtered)); // Demonstrate complex filtering: // Defines a filter that filters out all issues that are the causes // of issues with the type 'EXAMPLE_CONTENT...' (warning, info, or error) // and the actual issue is a 'EXAMPLE_WARNING...' console.log("Filtered by complex, custom filter:"); console.log("(This filter is omitting, for example, issues like"); console.log("[...] -> EXAMPLE_CONTENT_ERROR_E -> EXAMPLE_WARNING_E0x"); const complexFilter = (issuesStack: ValidationIssue[]) => { if (issuesStack.length > 1) { const issue0 = issuesStack[issuesStack.length - 2]; const issue1 = issuesStack[issuesStack.length - 1]; if ( issue0.type.startsWith("EXAMPLE_CONTENT") && issue1.type.startsWith("EXAMPLE_WARNING") ) { return false; } } return true; }; const filteredComplex = result.filter(complexFilter); console.log(ValidationResults.createSimpleResultString(filteredComplex)); } function validationResultSerializationDemo() { const result = createDemoResult(); const serializedJsonString = result.serialize(); console.log("Serialized into a JSON string:"); console.log(serializedJsonString); const deserializedResult = ValidationResult.deserialize(serializedJsonString); console.log("Deserialized from JSON string (simple representation):"); console.log(ValidationResults.createSimpleResultString(deserializedResult)); } validationResultFilterDemo(); validationResultSerializationDemo(); ================================================ FILE: etc/3d-tiles-validator.api.md ================================================ ## API Report File for "3d-tiles-validator" > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts /// import { ResourceResolver } from '3d-tiles-tools'; import { Schema } from '3d-tiles-tools'; import { TileImplicitTiling } from '3d-tiles-tools'; import { Tileset } from '3d-tiles-tools'; // @beta export class ValidationIssue { // @internal constructor(type: string, path: string, message: string, severity: ValidationIssueSeverity); // @internal addCause(cause: ValidationIssue): void; get causes(): readonly ValidationIssue[]; static deserialize(jsonString: string): ValidationIssue; static fromJson(object: any): ValidationIssue; get message(): string; get path(): string; // @internal serialize(): string; get severity(): ValidationIssueSeverity; // @internal toJson(): any; get type(): string; } // @beta export type ValidationIssueFilter = (issuesStack: ValidationIssue[]) => boolean; // @beta export class ValidationIssueFilters { static byExcludedTypes(...excludedTypes: string[]): ValidationIssueFilter; static byIncludedSeverities(...includedSeverities: ValidationIssueSeverity[]): ValidationIssueFilter; } // @beta export enum ValidationIssueSeverity { ERROR = "ERROR", INFO = "INFO", WARNING = "WARNING" } // @beta export class ValidationOptions { constructor(); get contentValidationIssueSeverity(): ValidationIssueSeverity; set contentValidationIssueSeverity(value: ValidationIssueSeverity); get excludeContentTypes(): string[] | undefined; set excludeContentTypes(value: string[] | undefined); static fromJson(json: any): ValidationOptions; get includeContentTypes(): string[] | undefined; set includeContentTypes(value: string[] | undefined); get semanticSchemaFileNames(): string[] | undefined; set semanticSchemaFileNames(value: string[] | undefined); get validateContentData(): boolean; set validateContentData(value: boolean); } // @beta export class ValidationResult { // @internal add(issue: ValidationIssue): void; // @internal static create(): ValidationResult; static deserialize(jsonString: string): ValidationResult; filter(includePredicate: ValidationIssueFilter): ValidationResult; static fromJson(object: any): ValidationResult; get(index: number): ValidationIssue; get issues(): readonly ValidationIssue[]; get length(): number; // @internal get numErrors(): number; // @internal get numInfos(): number; // @internal get numWarnings(): number; serialize(): string; // @internal toJson(): any; } // @beta export class Validators { // @internal static createContentValidationInfo(message: string): Validator; // Warning: (ae-forgotten-export) The symbol "SchemaValidator" needs to be exported by the entry point index.d.ts // // @internal static createDefaultSchemaValidator(): SchemaValidator; // Warning: (ae-forgotten-export) The symbol "ValidatedElement" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "SubtreeValidator" needs to be exported by the entry point index.d.ts // // @internal static createDefaultSubtreeValidator(uri: string, schemaState: ValidatedElement, implicitTiling: TileImplicitTiling | undefined): SubtreeValidator; // Warning: (ae-forgotten-export) The symbol "TilesetValidator" needs to be exported by the entry point index.d.ts // // @internal static createDefaultTilesetValidator(): TilesetValidator; // @internal static createEmptyValidator(): Validator; // Warning: (ae-forgotten-export) The symbol "Validator" needs to be exported by the entry point index.d.ts // // @internal static parseFromBuffer(delegate: Validator): Validator; // @internal static validateSchemaFile(filePath: string): Promise; // @internal static validateSubtreeFile(filePath: string, schemaState: ValidatedElement, implicitTiling: TileImplicitTiling | undefined): Promise; static validateTileContentFile(filePath: string, validationOptions?: ValidationOptions): Promise; static validateTilesetFile(filePath: string, validationOptions?: ValidationOptions): Promise; } // (No @packageDocumentation comment for this package) ``` ================================================ FILE: generateThirdParty.js ================================================ "use strict"; const fs = require("fs"); const path = require("path"); function defaultValue(a, b) { if (a !== undefined && a !== null) { return a; } return b; } function getLicenseDataFromPackage(packageName, override) { override = defaultValue(override, {}); const packagePath = path.join("node_modules", packageName, "package.json"); if (!fs.existsSync(packagePath)) { throw new Error(`Unable to find ${packageName} license information`); } const contents = fs.readFileSync(packagePath); const packageJson = JSON.parse(contents); let licenseField = override.license; if (!licenseField) { licenseField = [packageJson.license]; } if (!licenseField && packageJson.licenses) { licenseField = packageJson.licenses; } if (!licenseField) { console.log(`No license found for ${packageName}`); licenseField = ["NONE"]; } let version = packageJson.version; if (!packageJson.version) { console.log(`No version information found for ${packageName}`); version = "NONE"; } return { name: packageName, license: licenseField, version: version, url: `https://www.npmjs.com/package/${packageName}`, notes: override.notes, }; } function readThirdPartyExtraJson() { const path = "ThirdParty.extra.json"; if (fs.existsSync(path)) { const contents = fs.readFileSync(path); return JSON.parse(contents); } return []; } async function generateThirdParty() { const packageJson = JSON.parse(fs.readFileSync("package.json")); const thirdPartyExtraJson = readThirdPartyExtraJson(); const thirdPartyJson = []; const dependencies = packageJson.dependencies; for (const packageName in dependencies) { if (dependencies.hasOwnProperty(packageName)) { const override = thirdPartyExtraJson.find( (entry) => entry.name === packageName ); thirdPartyJson.push(getLicenseDataFromPackage(packageName, override)); } } thirdPartyJson.sort(function (a, b) { const nameA = a.name.toLowerCase(); const nameB = b.name.toLowerCase(); if (nameA < nameB) { return -1; } if (nameA > nameB) { return 1; } return 0; }); fs.writeFileSync("ThirdParty.json", JSON.stringify(thirdPartyJson, null, 2)); } generateThirdParty(); ================================================ FILE: package.json ================================================ { "name": "3d-tiles-validator", "version": "0.6.1", "license": "Apache-2.0", "description": "Tools for validating 3D Tiles tilesets.", "keywords": [ "3D Tiles" ], "homepage": "https://github.com/CesiumGS/3d-tiles-validator/", "repository": { "type": "git", "url": "https://github.com/CesiumGS/3d-tiles-validator.git" }, "bugs": { "url": "https://github.com/CesiumGS/3d-tiles-validator/issues" }, "engines": { "node": ">=18.0.0" }, "main": "./build/index.js", "types": "./build/index.d.ts", "bin": { "3d-tiles-validator": "./build/main" }, "dependencies": { "@gltf-transform/core": "^3.2.1", "@gltf-transform/extensions": "^3.2.1", "@gltf-transform/functions": "^3.2.1", "3d-tiles-tools": "0.5.0", "cesium": "^1.97.0", "gltf-validator": "^2.0.0-dev.3.9", "minimatch": "^5.1.0", "node-stream-zip": "^1.10.1", "sharp": "^0.32.1", "yargs": "^17.5.1" }, "devDependencies": { "@microsoft/api-documenter": "^7.19.24", "@microsoft/api-extractor": "^7.33.6", "@types/jasmine": "^4.0.3", "@types/minimatch": "^5.1.2", "@typescript-eslint/eslint-plugin": "^5.38.0", "@typescript-eslint/parser": "^5.38.0", "copyfiles": "^2.4.1", "del-cli": "^5.0.0", "eslint": "^8.23.1", "eslint-config-cesium": "^9.0.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-tsdoc": "^0.2.17", "jasmine": "^4.3.0", "mkdirp": "^1.0.4", "nyc": "^15.1.0", "prettier": "2.7.1", "ts-node": "^10.9.1", "typescript": "^4.8.3" }, "scripts": { "about:start": "echo 'Start the validator, as a TypeScript command line application'", "about:eslint": "echo 'Perform linting of the source code. This may modify the source files.'", "about:build": "echo 'Run the TypeScript compiler to generate the build output.'", "about:test": "echo 'Execute the unit tests'", "about:coverage": "echo 'Compute the test coverage'", "about:prettier-check": "echo 'Check the formatting of the source code (without fixing formatting errors).'", "about:prettier": "echo 'Ensure the right formatting of the source code, automatically fixing formatting errors.'", "about:generate-third-party": "echo 'Update the ThirdParty.json file with the most recent dependency versions'", "about:docs-prepare-directory": "echo 'Prepare the output directory for the API definition file'", "about:docs-extract-api": "echo 'Extract the API definition file from the current build output.'", "about:docs-generate-markdown": "echo 'Generate the API documentation based on the API definition file'", "about:docs-generate": "echo 'Generate the API documentation based on the current build output'", "about:docs": "echo 'Perform a build and generate the API documentation based on the build output'", "about:package-clean": "echo 'Delete the contents of the 'build' output folder'", "about:package-prepare": "echo 'Prepare a package: Linting, formatting, build, test, documentation, and third-party information updates'", "about:package-copy": "echo 'Copy the entry point for the application from the bin to the build directory'", "about:package": "echo 'Prepare a package that can then be published on NPM'", "start": "npx ts-node src/main.ts", "eslint": "eslint \"./**/*.ts\" --cache --max-warnings=0", "build": "npx tsc", "test": "ts-node node_modules/jasmine/bin/jasmine --config=specs/jasmine.json", "coverage": "nyc npm run test", "prettier-check": "prettier --check \"**/*\"", "prettier": "prettier --write \"**/*\"", "generate-third-party": "node generateThirdParty.js", "docs-prepare-directory": "mkdirp etc", "docs-extract-api": "api-extractor run --config api-extractor.jsonc --local --verbose", "docs-generate-markdown": "api-documenter markdown -i build/api-extractor -o build/docs", "docs-generate": "npm run docs-prepare-directory && npm run docs-extract-api && npm run docs-generate-markdown", "docs": "npm run build && npm run docs-generate", "package-clean": "del-cli ./build/**", "package-prepare": "npm run eslint && npm run prettier-check && npm run build && npm run test && npm run docs-generate && npm run generate-third-party", "package-copy": "npx copyfiles --flat bin/main build", "package": "npm run package-clean && npm run package-prepare && npm run package-copy && npm pack" } } ================================================ FILE: specs/BasicValidatorSpec.ts ================================================ import { BasicValidator } from "../src/validation/BasicValidator"; import { ValidationContext } from "../src/validation/ValidationContext"; import { ResourceResolvers } from "3d-tiles-tools"; function validateNumberRange( value: number, min: number | undefined, minInclusive: boolean, max: number | undefined, maxInclusive: boolean ): boolean { const resourceResolver = ResourceResolvers.createFileResourceResolver(""); const context = new ValidationContext(".", resourceResolver); const result = BasicValidator.validateNumberRange( "path", "name", value, min, minInclusive, max, maxInclusive, context ); //if (context.getResult().length > 0) { // console.log(context.getResult().get(0).message); //} return result; } describe("BasicValidator", function () { // Closed range, [] it("validateNumberRange detects that -5 is NOT in [0,10]", function () { const result = validateNumberRange(-5, 0, true, 10, true); expect(result).toBeFalse(); }); it("validateNumberRange detects that 0 is in [0,10]", function () { const result = validateNumberRange(0, 0, true, 10, true); expect(result).toBeTrue(); }); it("validateNumberRange detects that 5 is in [0,10]", function () { const result = validateNumberRange(5, 0, true, 10, true); expect(result).toBeTrue(); }); it("validateNumberRange detects that 10 is in [0,10]", function () { const result = validateNumberRange(10, 0, true, 10, true); expect(result).toBeTrue(); }); it("validateNumberRange detects that 15 is NOT in [0,10]", function () { const result = validateNumberRange(15, 0, true, 10, true); expect(result).toBeFalse(); }); // Closed range, (] it("validateNumberRange detects that -5 is NOT in (0,10]", function () { const result = validateNumberRange(-5, 0, false, 10, true); expect(result).toBeFalse(); }); it("validateNumberRange detects that 0 is NOT in (0,10]", function () { const result = validateNumberRange(0, 0, false, 10, true); expect(result).toBeFalse(); }); it("validateNumberRange detects that 5 is in (0,10]", function () { const result = validateNumberRange(5, 0, false, 10, true); expect(result).toBeTrue(); }); it("validateNumberRange detects that 10 is in (0,10]", function () { const result = validateNumberRange(10, 0, false, 10, true); expect(result).toBeTrue(); }); it("validateNumberRange detects that 15 is NOT in (0,10]", function () { const result = validateNumberRange(15, 0, false, 10, true); expect(result).toBeFalse(); }); // Closed range, [) it("validateNumberRange detects that -5 is NOT in [0,10)", function () { const result = validateNumberRange(-5, 0, true, 10, false); expect(result).toBeFalse(); }); it("validateNumberRange detects that 0 is in [0,10)", function () { const result = validateNumberRange(0, 0, true, 10, false); expect(result).toBeTrue(); }); it("validateNumberRange detects that 5 is in [0,10)", function () { const result = validateNumberRange(5, 0, true, 10, false); expect(result).toBeTrue(); }); it("validateNumberRange detects that 10 is NOT in [0,10)", function () { const result = validateNumberRange(10, 0, true, 10, false); expect(result).toBeFalse(); }); it("validateNumberRange detects that 15 is NOT in [0,10)", function () { const result = validateNumberRange(15, 0, true, 10, false); expect(result).toBeFalse(); }); // Closed range, () it("validateNumberRange detects that -5 is NOT in (0,10)", function () { const result = validateNumberRange(-5, 0, false, 10, false); expect(result).toBeFalse(); }); it("validateNumberRange detects that 0 is NOT in (0,10)", function () { const result = validateNumberRange(0, 0, false, 10, false); expect(result).toBeFalse(); }); it("validateNumberRange detects that 5 is in (0,10)", function () { const result = validateNumberRange(5, 0, false, 10, false); expect(result).toBeTrue(); }); it("validateNumberRange detects that 10 is NOT in (0,10)", function () { const result = validateNumberRange(10, 0, false, 10, false); expect(result).toBeFalse(); }); it("validateNumberRange detects that 15 is NOT in (0,10)", function () { const result = validateNumberRange(15, 0, false, 10, false); expect(result).toBeFalse(); }); // Lower bound [ it("validateNumberRange detects that -5 is NOT in [5,...", function () { const result = validateNumberRange(-5, 0, true, undefined, true); expect(result).toBeFalse(); }); it("validateNumberRange detects that 0 is in [0,...", function () { const result = validateNumberRange(0, 0, true, undefined, false); expect(result).toBeTrue(); }); it("validateNumberRange detects that 5 is in [0,...", function () { const result = validateNumberRange(5, 0, true, 10, false); expect(result).toBeTrue(); }); // Lower bound ( it("validateNumberRange detects that -5 is NOT in (5,...", function () { const result = validateNumberRange(-5, 0, false, undefined, true); expect(result).toBeFalse(); }); it("validateNumberRange detects that 0 is NOT in (0,...", function () { const result = validateNumberRange(0, 0, false, undefined, false); expect(result).toBeFalse(); }); it("validateNumberRange detects that 5 is in (0,...", function () { const result = validateNumberRange(5, 0, false, 10, false); expect(result).toBeTrue(); }); // Upper bound ] it("validateNumberRange detects that 5 is in ...,10]", function () { const result = validateNumberRange(5, undefined, true, 10, true); expect(result).toBeTrue(); }); it("validateNumberRange detects that 10 is in ...,10]", function () { const result = validateNumberRange(10, undefined, true, 10, true); expect(result).toBeTrue(); }); it("validateNumberRange detects that 15 is NOT in ...,10]", function () { const result = validateNumberRange(15, undefined, true, 10, true); expect(result).toBeFalse(); }); // Upper bound ) it("validateNumberRange detects that 5 is in ...,10)", function () { const result = validateNumberRange(5, undefined, true, 10, false); expect(result).toBeTrue(); }); it("validateNumberRange detects that 10 is NOT in ...,10)", function () { const result = validateNumberRange(10, undefined, true, 10, false); expect(result).toBeFalse(); }); it("validateNumberRange detects that 15 is NOT in ...,10)", function () { const result = validateNumberRange(15, undefined, true, 10, false); expect(result).toBeFalse(); }); }); ================================================ FILE: specs/BinaryBufferStructureSpec.ts ================================================ import fs from "fs"; import { ResourceResolvers } from "3d-tiles-tools"; import { BinaryBufferStructure } from "3d-tiles-tools"; import { BinaryBufferStructureValidator } from "../src/validation/BinaryBufferStructureValidator"; import { ValidationContext } from "../src/validation/ValidationContext"; /** * Only for internal use and basic tests: * * Reads a JSON file, parses it, and returns the result. * If the file cannot be read or parsed, then an error * message will be printed and `undefined` is returned. * * @param filePath - The path to the file * @returns A promise that resolves with the result or `undefined` */ async function readJsonUnchecked(filePath: string): Promise { try { const data = fs.readFileSync(filePath); if (!data) { console.error("Could not read " + filePath); return undefined; } const jsonString = data.toString(); const result = JSON.parse(jsonString); return result; } catch (error) { console.error("Could not parse JSON", error); return undefined; } } function performTestValidation( binaryBufferStructure: BinaryBufferStructure, context: ValidationContext ): void { const path = "test"; const firstBufferUriIsRequired = true; if ( BinaryBufferStructureValidator.validateBinaryBufferStructure( path, binaryBufferStructure.buffers, binaryBufferStructure.bufferViews, firstBufferUriIsRequired, context ) ) { BinaryBufferStructureValidator.validateBinaryBufferStructureConsistency( path, binaryBufferStructure, context ); } } describe("3d-tiles-tools", function () { let context: ValidationContext; beforeEach(async function () { const directory = "specs/data/buffers/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("detects issues in buffersElementByteLengthInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersElementByteLengthInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in buffersElementByteLengthInvalidValueA", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersElementByteLengthInvalidValueA.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in buffersElementByteLengthInvalidValueB", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersElementByteLengthInvalidValueB.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in buffersElementByteLengthMissing", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersElementByteLengthMissing.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in buffersElementInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersElementInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in buffersElementNameInvalidLength", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersElementNameInvalidLength.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_LENGTH_MISMATCH"); }); it("detects issues in buffersElementNameInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersElementNameInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in buffersElementUriInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersElementUriInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in buffersElementUriMissing", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersElementUriMissing.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in buffersInvalidLength", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersInvalidLength.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in buffersInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/buffersInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in bufferViewsElementBufferInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementBufferInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in bufferViewsElementBufferInvalidValueA", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementBufferInvalidValueA.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in bufferViewsElementBufferInvalidValueB", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementBufferInvalidValueB.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in bufferViewsElementBufferInvalidValueC", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementBufferInvalidValueC.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in bufferViewsElementByteLengthInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementByteLengthInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in bufferViewsElementByteLengthInvalidValueA", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementByteLengthInvalidValueA.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in bufferViewsElementByteLengthInvalidValueB", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementByteLengthInvalidValueB.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in bufferViewsElementByteOffsetInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementByteOffsetInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in bufferViewsElementByteOffsetInvalidValueA", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementByteOffsetInvalidValueA.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in bufferViewsElementByteOffsetInvalidValueB", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementByteOffsetInvalidValueB.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in bufferViewsElementExceedsBufferLength", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementExceedsBufferLength.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BUFFERS_INCONSISTENT"); }); it("detects issues in bufferViewsElementInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsElementInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in bufferViewsInvalidLength", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsInvalidLength.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in bufferViewsInvalidType", async function () { const binaryBufferStructure = await readJsonUnchecked( "specs/data/buffers/bufferViewsInvalidType.json" ); performTestValidation(binaryBufferStructure, context); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); }); ================================================ FILE: specs/ExternalTilesetExtensionsValidationSpec.ts ================================================ import { Validators } from "../src/validation/Validators"; // Note: These test cases use a dummy extension called // VENDOR_example_extension // So they will always create at least a WARNING about // this not being supported describe("External tileset extensions validation", function () { it("detects no errors in declaredInBothContainedInExternal", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/externalTilesetExtensions/declaredInBothContainedInExternal/tileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTERNAL_TILESET_VALIDATION_WARNING"); expect(result.get(0).causes[0].type).toEqual("EXTENSION_NOT_SUPPORTED"); }); it("detects no errors (but one warning) in declaredInBothContainedInTileset", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/externalTilesetExtensions/declaredInBothContainedInTileset/tileset.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(1).type).toEqual("EXTERNAL_TILESET_VALIDATION_WARNING"); expect(result.get(1).causes[0].type).toEqual( "EXTENSION_USED_BUT_NOT_FOUND" ); }); it("detects an error in declaredInExternalContainedInExternal", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/externalTilesetExtensions/declaredInExternalContainedInExternal/tileset.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("EXTERNAL_TILESET_VALIDATION_WARNING"); expect(result.get(0).causes[0].type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(1).type).toEqual("EXTENSION_FOUND_BUT_NOT_USED"); }); it("detects an error and a warning in declaredInExternalContainedInTileset", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/externalTilesetExtensions/declaredInExternalContainedInTileset/tileset.json" ); expect(result.length).toEqual(3); expect(result.get(0).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(1).type).toEqual("EXTERNAL_TILESET_VALIDATION_WARNING"); expect(result.get(1).causes[0].type).toEqual( "EXTENSION_USED_BUT_NOT_FOUND" ); expect(result.get(2).type).toEqual("EXTENSION_FOUND_BUT_NOT_USED"); }); it("detects two errors in declaredInNoneContainedInExternal", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/externalTilesetExtensions/declaredInNoneContainedInExternal/tileset.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("EXTERNAL_TILESET_VALIDATION_ERROR"); expect(result.get(1).type).toEqual("EXTENSION_FOUND_BUT_NOT_USED"); }); it("detects one error in declaredInTilesetContainedInExternal", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/externalTilesetExtensions/declaredInTilesetContainedInExternal/tileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTERNAL_TILESET_VALIDATION_ERROR"); expect(result.get(0).causes[1].type).toEqual( "EXTENSION_FOUND_BUT_NOT_USED" ); }); it("detects no errors in declaredInTilesetContainedInTileset", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/externalTilesetExtensions/declaredInTilesetContainedInTileset/tileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTENSION_NOT_SUPPORTED"); }); }); ================================================ FILE: specs/MetadataSchemaValidationSpec.ts ================================================ import { Validators } from "../src/validation/Validators"; describe("Metadata schema validation", function () { it("detects issues in metadataClassDescriptionInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassDescriptionInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassesInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassesInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassesNameInvalid", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassesNameInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_PATTERN_MISMATCH"); }); it("detects issues in metadataClassNameInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassNameInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertiesDuplicateSemantics", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertiesDuplicateSemantics.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CLASS_PROPERTIES_DUPLICATE_SEMANTIC"); }); it("detects issues in metadataClassPropertiesEmpty", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertiesEmpty.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("NUMBER_OF_PROPERTIES_MISMATCH"); }); it("detects issues in metadataClassPropertiesNameInvalid", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertiesNameInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_PATTERN_MISMATCH"); }); it("detects issues in metadataClassPropertyArrayInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyArrayInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyComponentTypeForTypeWithoutComponents", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyComponentTypeForTypeWithoutComponents.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "CLASS_PROPERTY_COMPONENT_TYPE_FOR_NON_NUMERIC_TYPE" ); }); it("detects issues in metadataClassPropertyComponentTypeMissing", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyComponentTypeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CLASS_PROPERTY_COMPONENT_TYPE_MISSING"); }); it("detects issues in metadataClassPropertyComponentTypeInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyComponentTypeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyComponentTypeInvalidValue", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyComponentTypeInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in metadataClassPropertyCountInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyCountInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyCountInvalidValue", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyCountInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in metadataClassPropertyCountWithoutArray", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyCountWithoutArray.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CLASS_PROPERTY_COUNT_FOR_NON_ARRAY"); }); it("detects issues in metadataClassPropertyDefaultWithRequired", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyDefaultWithRequired.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CLASS_PROPERTY_INCONSISTENT"); }); it("detects issues in metadataClassPropertyDescriptionInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyDescriptionInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyEnumTypeForNonEnumType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyEnumTypeForNonEnumType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "CLASS_PROPERTY_ENUMTYPE_WITH_NON_ENUM_TYPE" ); }); it("detects issues in metadataClassPropertyEnumTypeInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyEnumTypeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyEnumTypeMissingForEnumType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyEnumTypeMissingForEnumType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "CLASS_PROPERTY_ENUM_TYPE_WITHOUT_ENUMTYPE" ); }); it("detects issues in metadataClassPropertyEnumTypeNotFound", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyEnumTypeNotFound.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CLASS_PROPERTY_ENUMTYPE_NOT_FOUND"); }); it("detects issues in metadataClassPropertyEnumTypeWithoutEnums", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyEnumTypeWithoutEnums.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CLASS_PROPERTY_ENUMTYPE_NOT_FOUND"); }); it("detects issues in metadataClassPropertyMaxForNonNumericType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyMaxForNonNumericType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_MIN_MAX_FOR_NON_NUMERIC_TYPE"); }); it("detects issues in metadataClassPropertyMinForNonNumericType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyMinForNonNumericType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_MIN_MAX_FOR_NON_NUMERIC_TYPE"); }); it("detects issues in metadataClassPropertyMinForVariableLengthArray", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyMinForVariableLengthArray.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY" ); }); it("detects issues in metadataClassPropertyNameInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNameInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyNoDataForBoolean", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNoDataForBoolean.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CLASS_PROPERTY_INCONSISTENT"); }); it("detects issues in metadataClassPropertyNoDataInvalidEnumValueName", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNoDataInvalidEnumValueName.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "CLASS_PROPERTY_ENUM_VALUE_NAME_NOT_FOUND" ); }); it("detects issues in metadataClassPropertyNoDataInvalidEnumValueNames", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNoDataInvalidEnumValueNames.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "CLASS_PROPERTY_ENUM_VALUE_NAME_NOT_FOUND" ); }); it("detects issues in metadataClassPropertyNoDataTypeMismatchA", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNoDataTypeMismatchA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyNoDataTypeMismatchB", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNoDataTypeMismatchB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in metadataClassPropertyNoDataTypeMismatchC", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNoDataTypeMismatchC.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyNoDataWithRequired", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNoDataWithRequired.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CLASS_PROPERTY_INCONSISTENT"); }); it("detects issues in metadataClassPropertyNormalizedForNonIntegerComponentType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNormalizedForNonIntegerComponentType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "CLASS_PROPERTY_NORMALIZED_FOR_NON_NORMALIZABLE_TYPE" ); }); it("detects issues in metadataClassPropertyNormalizedForUnnormalizableType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNormalizedForUnnormalizableType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "CLASS_PROPERTY_NORMALIZED_FOR_NON_NORMALIZABLE_TYPE" ); }); it("detects issues in metadataClassPropertyNormalizedInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyNormalizedInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyOffsetForNonFloatingPointTypeA", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetForNonFloatingPointTypeA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "METADATA_OFFSET_SCALE_FOR_NON_FLOATING_POINT_TYPE" ); }); it("detects issues in metadataClassPropertyOffsetForNonFloatingPointTypeB", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetForNonFloatingPointTypeB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "METADATA_OFFSET_SCALE_FOR_NON_FLOATING_POINT_TYPE" ); }); it("detects issues in metadataClassPropertyOffsetForVariableLengthArray", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetForVariableLengthArray.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY" ); }); it("detects issues in metadataClassPropertyOffsetTypeMismatchA", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetTypeMismatchA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyOffsetTypeMismatchB", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetTypeMismatchB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyOffsetTypeMismatchC", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetTypeMismatchC.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in metadataClassPropertyOffsetTypeMismatchD", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetTypeMismatchD.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyOffsetTypeMismatchE", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetTypeMismatchE.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in metadataClassPropertyOffsetTypeMismatchF", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetTypeMismatchF.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in metadataClassPropertyOffsetTypeMismatchG", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyOffsetTypeMismatchG.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in metadataClassPropertyRequiredInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyRequiredInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyScaleForNonFloatingPointType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyScaleForNonFloatingPointType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "METADATA_OFFSET_SCALE_FOR_NON_FLOATING_POINT_TYPE" ); }); it("detects issues in metadataClassPropertyScaleForNonFloatingPointTypeB", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyScaleForNonFloatingPointTypeB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "METADATA_OFFSET_SCALE_FOR_NON_FLOATING_POINT_TYPE" ); }); it("detects issues in metadataClassPropertyTypeInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyTypeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataClassPropertyTypeInvalidValue", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyTypeInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in metadataClassPropertyTypeMissing", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertyTypeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in metadataEnumDescriptionInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumDescriptionInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataEnumNameInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumNameInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataEnumsInvalidName", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumsInvalidName.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_PATTERN_MISMATCH"); }); it("detects issues in metadataEnumsInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataEnumValueDescriptionInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValueDescriptionInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataEnumValueNameInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValueNameInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataEnumValuesDuplicateName", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValuesDuplicateName.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ENUM_VALUE_DUPLICATE_NAME"); }); it("detects issues in metadataEnumValuesDuplicateValue", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValuesDuplicateValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ENUM_VALUE_DUPLICATE_VALUE"); }); it("detects issues in metadataEnumValuesEmpty", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValuesEmpty.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in metadataEnumValuesMissing", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValuesMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in metadataEnumValueTypeInvalid", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValueTypeInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in metadataEnumValueTypeInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValueTypeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in metadataEnumValueTypeInvalidValue", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValueTypeInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in metadataEnumValueValueInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValueValueInvalidType.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); expect(result.get(1).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in schemaIdInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/schemaIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in schemaIdInvalidValue", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/schemaIdInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_PATTERN_MISMATCH"); }); it("detects issues in schemaIdMissing", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/schemaIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects no issues in validSchema", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/validSchema.json" ); expect(result.length).toEqual(0); }); it("detects no issues in validSchemaWithMinMax", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/validSchemaWithMinMax.json" ); expect(result.length).toEqual(0); }); it("detects issues in metadataClassPropertySemanticArrayMismatchA", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticArrayMismatchA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); }); it("detects issues in metadataClassPropertySemanticArrayMismatchB", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticArrayMismatchB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); }); it("detects issues in metadataClassPropertySemanticComponentTypeMismatchA", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); }); it("detects issues in metadataClassPropertySemanticComponentTypeMismatchB", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); }); it("detects issues in metadataClassPropertySemanticCountMismatch", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticCountMismatch.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); }); it("detects issues in metadataClassPropertySemanticInvalidType", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects no issues in metadataClassPropertySemanticGeneric", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticGeneric.json" ); expect(result.length).toEqual(0); }); it("detects issues in metadataClassPropertySemanticNormalizedMismatch", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticNormalizedMismatch.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); }); it("detects issues in metadataClassPropertySemanticTypeMismatch", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticTypeMismatch.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); }); it("detects issues in metadataClassPropertySemanticUnknown", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticUnknown.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_UNKNOWN"); }); it("detects issues in metadataEnumValueNotInValueTypeRange", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValueNotInValueTypeRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in metadataEnumValueNotInDefaultValueTypeRange", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataEnumValueNotInDefaultValueTypeRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); }); ================================================ FILE: specs/SubtreeValidationSpec.ts ================================================ import { Schema } from "3d-tiles-tools"; import { readJsonUnchecked } from "../src/base/readJsonUnchecked"; import { Validators } from "../src/validation/Validators"; import { ValidatedElement } from "../src/validation/ValidatedElement"; import { ValidationResult } from "../src/validation/ValidationResult"; /** * Validate the specified subtree file from the `specs/data/subtrees` * directory. * * Note that in order to validate a subtree file, the validator requires * additional data elements. Namely, the `TileImplicitTiling` that * defines the structure of the subtree, and a `Schema` (if the * subtree contains metadata). * * This function will load this data from the additional files in * the `specs/data/` directory that define the same structure for * all subtree spec files. * * @param fileName - The subtree file name * @returns A promise to the `ValidationResult` */ async function validateSpecSubtreeFile( fileName: string ): Promise { // The schema for the subtrees in the specs directory const specSchema: Schema = await readJsonUnchecked( "specs/data/schemas/validSchema.json" ); const specSchemaState: ValidatedElement = { wasPresent: true, validatedElement: specSchema, }; // The `TileImplicitTiling` object that defines the // structure of subtrees in the specs directory const specImplicitTiling = await readJsonUnchecked( "specs/data/subtrees/validSubtreeImplicitTiling.json.input" ); const validationResult = await Validators.validateSubtreeFile( fileName, specSchemaState, specImplicitTiling ); return validationResult; } describe("Subtree validation", function () { it("detects issues in binarySubtreeComputedLengthInvalid", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/binarySubtreeComputedLengthInvalid.subtree" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BINARY_INVALID_LENGTH"); }); it("detects issues in binarySubtreeInvalidBinaryByteLengthAlignment", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/binarySubtreeInvalidBinaryByteLengthAlignment.subtree" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BINARY_INVALID_ALIGNMENT"); }); it("detects issues in binarySubtreeInvalidJsonByteLengthAlignment", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/binarySubtreeInvalidJsonByteLengthAlignment.subtree" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BINARY_INVALID_ALIGNMENT"); }); it("detects issues in binarySubtreeInvalidMagic", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/binarySubtreeInvalidMagic.subtree" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IO_ERROR"); }); it("detects issues in binarySubtreeInvalidVersion", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/binarySubtreeInvalidVersion.subtree" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BINARY_INVALID_VALUE"); }); it("detects issues in binarySubtreeJsonInvalid", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/binarySubtreeJsonInvalid.subtree" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("JSON_PARSE_ERROR"); }); it("detects no issues in binarySubtreeValid", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/binarySubtreeValid.subtree" ); expect(result.length).toEqual(0); }); it("detects issues in subtreeBufferViewsWithoutBuffers", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeBufferViewsWithoutBuffers.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BUFFER_VIEWS_WITHOUT_BUFFERS"); }); it("detects issues in subtreeChildSubtreeAvailabilityInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeChildSubtreeAvailabilityInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeChildSubtreeAvailabilityMissing", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeChildSubtreeAvailabilityMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in subtreeContentAvailabilityInvalidLength", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeContentAvailabilityInvalidLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in subtreeContentAvailabilityInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeContentAvailabilityInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeContentMetadataArrayElementInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeContentMetadataArrayElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in subtreeContentMetadataArrayElementInvalidValueA", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeContentMetadataArrayElementInvalidValueA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeContentMetadataArrayElementInvalidValueB", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeContentMetadataArrayElementInvalidValueB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in subtreeContentMetadataInvalidLength", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeContentMetadataInvalidLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in subtreeContentMetadataInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeContentMetadataInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeContentMetadataWithoutPropertyTables", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeContentMetadataWithoutPropertyTables.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in subtreePropertyTablesElementInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreePropertyTablesElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in subtreePropertyTablesInvalidLength", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreePropertyTablesInvalidLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in subtreePropertyTablesInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreePropertyTablesInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeTileAvailabilityAvailableCountInvalid", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityAvailableCountInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("SUBTREE_AVAILABILITY_INCONSISTENT"); }); it("detects issues in subtreeTileAvailabilityAvailableCountMismatch", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityAvailableCountMismatch.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("SUBTREE_AVAILABILITY_INCONSISTENT"); }); it("detects issues in subtreeTileAvailabilityBitstreamAndConstant", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityBitstreamAndConstant.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ONE_OF_ERROR"); }); it("detects issues in subtreeTileAvailabilityBitstreamInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityBitstreamInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeTileAvailabilityBitstreamInvalidValueA", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityBitstreamInvalidValueA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeTileAvailabilityBitstreamInvalidValueB", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityBitstreamInvalidValueB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in subtreeTileAvailabilityBitstreamInvalidValueC", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityBitstreamInvalidValueC.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in subtreeTileAvailabilityBitstreamLengthTooLarge", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityBitstreamLengthTooLarge.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("SUBTREE_AVAILABILITY_INCONSISTENT"); }); it("detects issues in subtreeTileAvailabilityBitstreamLengthTooSmall", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityBitstreamLengthTooSmall.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("SUBTREE_AVAILABILITY_INCONSISTENT"); }); it("detects issues in subtreeTileAvailabilityConstantInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityConstantInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in subtreeTileAvailabilityConstantInvalidValue", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityConstantInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in subtreeTileAvailabilityForParentMissingForAvailableTile", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityForParentMissingForAvailableTile.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("SUBTREE_AVAILABILITY_INCONSISTENT"); }); it("detects issues in subtreeTileAvailabilityInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeTileAvailabilityMissing", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in subtreeTileAvailabilityMissingForAvailableContent", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityMissingForAvailableContent.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("SUBTREE_AVAILABILITY_INCONSISTENT"); }); it("detects issues in subtreeTileAvailabilityNeitherBitstreamNorConstant", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileAvailabilityNeitherBitstreamNorConstant.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ANY_OF_ERROR"); }); it("detects issues in subtreeTileMetadataInvalidType", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileMetadataInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeTileMetadataInvalidValueA", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileMetadataInvalidValueA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in subtreeTileMetadataInvalidValueB", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/subtreeTileMetadataInvalidValueB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects no issues in validSubtree", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/validSubtree.json" ); expect(result.length).toEqual(0); }); it("detects issues in validSubtreeBuffersWithoutBufferViews", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/validSubtreeBuffersWithoutBufferViews.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BUFFERS_WITHOUT_BUFFER_VIEWS"); }); it("detects no issues in validSubtreeNoBuffers", async function () { const result = await validateSpecSubtreeFile( "specs/data/subtrees/validSubtreeNoBuffers.json" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/TilesetPackageValidationSpec.ts ================================================ import { Validators } from "../src/validation/Validators"; describe("Tileset package validation", function () { it("detects no issues in validTilesetPackage.3tz", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/packages/validTilesetPackage.3tz" ); expect(result.length).toEqual(0); }); it("detects no issues in validTilesetPackage.3dtiles", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/packages/validTilesetPackage.3dtiles" ); expect(result.length).toEqual(0); }); it("detects no issues in validTilesetPackageZipped.3tz", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/packages/validTilesetPackageZipped.3tz" ); expect(result.length).toEqual(0); }); it("detects no issues in validTilesetPackageZipped.3dtiles", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/packages/validTilesetPackageZipped.3dtiles" ); expect(result.length).toEqual(0); }); it("detects issues in tilesetPackageWithWarnings.3tz", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/packages/tilesetPackageWithWarnings.3tz" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_WARNING"); }); it("detects issues in tilesetPackageWithWarnings.3dtiles", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/packages/tilesetPackageWithWarnings.3dtiles" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_WARNING"); }); }); ================================================ FILE: specs/TilesetValidationSpec.ts ================================================ import { ValidationOptions } from "../src/validation/ValidationOptions"; import { Validators } from "../src/validation/Validators"; describe("Tileset validation", function () { it("detects issues in assetTilesetVersionInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/assetTilesetVersionInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in assetVersionInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/assetVersionInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in assetVersionMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/assetVersionMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in assetVersionUnknown", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/assetVersionUnknown.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ASSET_VERSION_UNKNOWN"); }); it("detects issues in boundingVolumeBoxArrayInvalidElementType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/boundingVolumeBoxArrayInvalidElementType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in boundingVolumeBoxInvalidArrayLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/boundingVolumeBoxInvalidArrayLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in boundingVolumeMissingProperty", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/boundingVolumeMissingProperty.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ANY_OF_ERROR"); }); it("detects issues in boundingVolumeRegionArrayElementsOutOfRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/boundingVolumeRegionArrayElementsOutOfRange.json" ); expect(result.length).toEqual(6); expect(result.get(0).type).toEqual("BOUNDING_VOLUME_INVALID"); expect(result.get(1).type).toEqual("BOUNDING_VOLUME_INVALID"); expect(result.get(2).type).toEqual("BOUNDING_VOLUME_INVALID"); expect(result.get(3).type).toEqual("BOUNDING_VOLUME_INVALID"); expect(result.get(4).type).toEqual("BOUNDING_VOLUME_INVALID"); expect(result.get(5).type).toEqual("BOUNDING_VOLUME_INVALID"); }); it("detects issues in boundingVolumeRegionArrayInvalidElementType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/boundingVolumeRegionArrayInvalidElementType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in boundingVolumeRegionInvalidArrayLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/boundingVolumeRegionInvalidArrayLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in boundingVolumeSphereArrayElementOutOfRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/boundingVolumeSphereArrayElementOutOfRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BOUNDING_VOLUME_INVALID"); }); it("detects issues in boundingVolumeSphereArrayInvalidElementType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/boundingVolumeSphereArrayInvalidElementType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in boundingVolumeSphereInvalidArrayLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/boundingVolumeSphereInvalidArrayLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in groupClassIdInvalid", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/groupClassIdInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in groupClassIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/groupClassIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in groupWithoutSchema", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/groupWithoutSchema.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in implicitTilingAvailableLevelsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingAvailableLevelsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in implicitTilingAvailableLevelsInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingAvailableLevelsInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in implicitTilingContentsUriTemplateVariableInvalid", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingContentsUriTemplateVariableInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TEMPLATE_URI_INVALID_VARIABLE_NAME"); }); it("detects issues in implicitTilingContentUriTemplateVariableInvalid", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingContentUriTemplateVariableInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TEMPLATE_URI_INVALID_VARIABLE_NAME"); }); it("detects issues in implicitTilingInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in implicitTilingRootWithChildren", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingRootWithChildren.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TILE_IMPLICIT_ROOT_INVALID"); }); it("detects issues in implicitTilingRootWithContentBoundingVolume", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingRootWithContentBoundingVolume.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TILE_IMPLICIT_ROOT_INVALID"); }); it("detects issues in implicitTilingRootWithMetadata", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingRootWithMetadata.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TILE_IMPLICIT_ROOT_INVALID"); }); it("detects issues in implicitTilingSubdivisionSchemeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingSubdivisionSchemeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in implicitTilingSubdivisionSchemeInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingSubdivisionSchemeInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in implicitTilingSubtreeLevelsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingSubtreeLevelsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in implicitTilingSubtreeLevelsInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingSubtreeLevelsInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in implicitTilingSubtreesInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingSubtreesInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in implicitTilingSubtreesUriInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingSubtreesUriInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in implicitTilingSubtreesUriMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingSubtreesUriMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in implicitTilingSubtreesUriTemplateVariableInvalid", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingSubtreesUriTemplateVariableInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TEMPLATE_URI_INVALID_VARIABLE_NAME"); }); it("detects issues in implicitTilingSubtreesUriTemplateVariableMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingSubtreesUriTemplateVariableMissing.json" ); // Expect the IMPLICIT_TILING_ERROR here, because the file // for the template URI for the test cannot be resolved expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("TEMPLATE_URI_MISSING_VARIABLE_NAME"); }); it("detects issues in implicitTilingValid", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingValid.json" ); // Expect the TILE_IMPLICIT_ROOT_INVALID here, because the file // for the template URI for the test cannot be resolved expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TILE_IMPLICIT_ROOT_INVALID"); }); it("detects issues in implicitTilingWithBoundingSphere", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/implicitTilingWithBoundingSphere.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TILE_IMPLICIT_ROOT_INVALID"); }); it("detects issues in invalidJson", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/invalidJson.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("JSON_PARSE_ERROR"); }); it("detects issues in propertiesInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/propertiesInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in propertiesMaximumInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/propertiesMaximumInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in propertiesMaximumMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/propertiesMaximumMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in propertiesMinimumInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/propertiesMinimumInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in propertiesMinimumLargerThanMaximum", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/propertiesMinimumLargerThanMaximum.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "PROPERTIES_MINIMUM_LARGER_THAN_MAXIMUM" ); }); it("detects issues in propertiesMinimumMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/propertiesMinimumMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in statisticsClassesIdInvalid", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/statisticsClassesIdInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in statisticsClassesInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/statisticsClassesInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in statisticsClassesMinPropertiesMismatch", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/statisticsClassesMinPropertiesMismatch.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("NUMBER_OF_PROPERTIES_MISMATCH"); }); it("detects issues in statisticsClassesPropertiesMinPropertiesMismatch", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/statisticsClassesPropertiesMinPropertiesMismatch.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("NUMBER_OF_PROPERTIES_MISMATCH"); }); it("detects issues in statisticsClassesPropertiesPropertyNameInvalid", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/statisticsClassesPropertiesPropertyNameInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in statisticsClassesValueInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/statisticsClassesValueInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in statisticsClassesWithoutSchema", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/statisticsClassesWithoutSchema.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in tileChildrenEmptyArray", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileChildrenEmptyArray.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_UNEXPECTED"); }); it("detects issues in tileContentBoundingVolumeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentBoundingVolumeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in tileContentBoundingVolumeNotInTileBoundingVolume", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentBoundingVolumeNotInTileBoundingVolume.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BOUNDING_VOLUMES_INCONSISTENT"); }); it("detects no issues in tileContentBoundingVolumeWithRotationTransform", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentBoundingVolumeWithRotationTransform.json" ); expect(result.length).toEqual(0); }); it("detects no issues in tileContentBoundingVolumeWithTransform", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentBoundingVolumeWithTransform.json" ); expect(result.length).toEqual(0); }); it("detects issues in tileContentGroupInvalidIndex", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentGroupInvalidIndex.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in tileContentGroupInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentGroupInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in tileContentGroupNegativeIndex", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentGroupNegativeIndex.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in tileContentGroupWithoutTilesetGroups", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentGroupWithoutTilesetGroups.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in tileContentInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in tileContentsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in tileGeometricErrorMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileGeometricErrorMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in tileGeometricErrorNegative", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileGeometricErrorNegative.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in tileGeometricErrorNotSmallerThanParentGeometricError", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileGeometricErrorNotSmallerThanParentGeometricError.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("TILE_GEOMETRIC_ERRORS_INCONSISTENT"); expect(result.get(1).type).toEqual("TILE_GEOMETRIC_ERRORS_INCONSISTENT"); }); it("detects issues in tileInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in tileMetadataClassInvalid", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileMetadataClassInvalid.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in tileMetadataClassInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileMetadataClassInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in tileMetadataClassMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileMetadataClassMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in tileMetadataScalarValueNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileMetadataScalarValueNotInRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in tileMetadataVec3ElementValueNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileMetadataVec3ElementValueNotInRange.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(1).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in tileMetadataVec3ArrayElementValueNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileMetadataVec3ArrayElementValueNotInRange.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(1).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in tileMetadataRequiredPropertyMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileMetadataRequiredPropertyMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_REQUIRED_BUT_MISSING"); }); it("detects issues in tileMetadataRequiredPropertyNull", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileMetadataRequiredPropertyNull.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_REQUIRED_BUT_MISSING"); }); it("detects issues in tileMetadataWithoutSchema", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileMetadataWithoutSchema.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in tileRefineInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileRefineInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in tileRefineMissingInRoot", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileRefineMissingInRoot.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TILE_REFINE_MISSING_IN_ROOT"); }); it("detects issues in tileRefineMissingInRootOfExternal", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileRefineMissingInRootOfExternal.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTERNAL_TILESET_VALIDATION_ERROR"); }); it("detects issues in tileRefineWrongCase", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileRefineWrongCase.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TILE_REFINE_WRONG_CASE"); }); it("detects issues in tileRefineWrongType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileRefineWrongType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in tilesetAssetMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetAssetMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in tilesetGeometricErrorMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetGeometricErrorMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in tilesetGeometricErrorNegative", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetGeometricErrorNegative.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in tilesetMetadataEntityPropertyEnumInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetMetadataEntityPropertyEnumInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "CLASS_PROPERTY_ENUM_VALUE_NAME_NOT_FOUND" ); }); it("detects issues in tilesetMetadataEntityPropertyMaxNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetMetadataEntityPropertyMaxNotInRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects issues in tilesetMetadataEntityPropertyMaxWithNormalizedNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetMetadataEntityPropertyMaxWithNormalizedNotInRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects issues in tilesetMetadataEntityPropertyMaxWithOffsetNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetMetadataEntityPropertyMaxWithOffsetNotInRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects issues in tilesetMetadataEntityPropertyMaxWithScaleNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetMetadataEntityPropertyMaxWithScaleNotInRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects issues in tilesetMetadataEntityPropertyMinNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetMetadataEntityPropertyMinNotInRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects issues in tilesetMetadataEntityPropertyMinWithNormalizedNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetMetadataEntityPropertyMinWithNormalizedNotInRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects issues in tilesetMetadataEntityPropertyMinWithOffsetNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetMetadataEntityPropertyMinWithOffsetNotInRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects issues in tilesetMetadataEntityPropertyMinWithScaleNotInRange", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetMetadataEntityPropertyMinWithScaleNotInRange.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects issues in tilesetSchemaUriInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetSchemaUriInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in tilesetWithSchemaAndSchemaUri", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetWithSchemaAndSchemaUri.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ONE_OF_ERROR"); }); it("detects issues in tilesetWithUnicodeBOM", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetWithUnicodeBOM.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IO_ERROR"); }); it("detects issues in tileTransformInvalidArrayElementType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileTransformInvalidArrayElementType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in tileTransformInvalidArrayLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileTransformInvalidArrayLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in tileTransformInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileTransformInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects no issues in tileTransformNonInvertible", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileTransformNonInvertible.json" ); // The matrix is not invertible, but it is affine. // So this should not cause an issue. expect(result.length).toEqual(0); }); it("detects issues in tileTransformNotAffine", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileTransformNotAffine.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TRANSFORM_INVALID"); }); it("detects issues in tileWithContentAndContents", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileWithContentAndContents.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ONE_OF_ERROR"); }); it("detects no issues in validTileset", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTileset.json" ); expect(result.length).toEqual(0); }); it("detects issues in validTilesetWithCustomSemantics", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithCustomSemantics.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_UNKNOWN"); expect(result.get(1).type).toEqual("METADATA_SEMANTIC_UNKNOWN"); }); it("detects no issues in validTilesetWithCustomSemantics when registering the custom semantics matcher", async function () { const validationOptions: ValidationOptions = ValidationOptions.fromJson({ semanticSchemaFileNames: [ "specs/data/tilesets/customSemanticsSchema.json", ], }); const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithCustomSemantics.json", validationOptions ); expect(result.length).toEqual(0); }); it("detects issues in validTilesetWithCustomSemanticsWithInvalidType (after registering the custom semantics matcher)", async function () { const validationOptions: ValidationOptions = ValidationOptions.fromJson({ semanticSchemaFileNames: [ "specs/data/tilesets/customSemanticsSchema.json", ], }); const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithCustomSemanticsWithInvalidType.json", validationOptions ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); expect(result.get(1).type).toEqual("METADATA_SEMANTIC_INVALID"); }); it("detects issues in validTilesetWithExternalValidTilesetWithValidB3dmWithInvalidGlb", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithExternalValidTilesetWithValidB3dmWithInvalidGlb.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTERNAL_TILESET_VALIDATION_ERROR"); }); it("detects issues in validTilesetWithGlbWithErrors", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithGlbWithErrors.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); it("detects issues in validTilesetWithGltfWithErrors", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithGltfWithErrors.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); it("detects issues in validTilesetWithGltfWithWarnings", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithGltfWithWarnings.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_WARNING"); }); it("detects issues in validTilesetWithInvalidB3dm", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithInvalidB3dm.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); it("detects issues in validTilesetWithInvalidB3dmWithGlbWithInfos", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithInvalidB3dmWithGlbWithInfos.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); // Expect the 'infos' from the glTF validation to still be present, // even though the B3DM validation already caused an error due to // the invalid alignment. // See https://github.com/CesiumGS/3d-tiles-validator/issues/299 expect(result.get(0).causes.length).toEqual(2); expect(result.get(0).causes[0].type).toEqual("BINARY_INVALID_ALIGNMENT"); expect(result.get(0).causes[1].type).toEqual("CONTENT_VALIDATION_INFO"); }); it("detects issues in validTilesetWithInvalidSchemaFromUri", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithInvalidSchemaFromUri.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects no issues in validTilesetWithSchema", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithSchema.json" ); expect(result.length).toEqual(0); }); it("detects issues in validTilesetWithUnresolvableSchemaUri", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithUnresolvableSchemaUri.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IO_ERROR"); }); it("detects no issues in validTilesetWithValidB3dm", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithValidB3dm.json" ); expect(result.length).toEqual(0); }); it("detects issues in validTilesetWithValidCmptWithGlbInfo", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithValidCmptWithGlbInfo.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_INFO"); }); it("detects no issues in validTilesetWithValid3tz", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithValid3tz.json" ); expect(result.length).toEqual(0); }); it("detects issues in validTilesetWith3tzWithError", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWith3tzWithError.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); it("detects issues in validTilesetWithInvalid3tz", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithInvalid3tz.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); it("detects issues in validTilesetWithInvalidI3dm", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithInvalidI3dm.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); it("detects issues in validTilesetWithInvalidPnts", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithInvalidPnts.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); it("detects issues in validTilesetWithValidB3dmWithInvalidGlb", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithValidB3dmWithInvalidGlb.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); it("detects no issues in validTilesetWithValidGltf", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithValidGltf.json" ); expect(result.length).toEqual(0); }); it("detects no issues in validTilesetWithValidSchemaFromUri", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithValidSchemaFromUri.json" ); expect(result.length).toEqual(0); }); it("detects issues in extensionFoundButNotUsed", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionFoundButNotUsed.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(1).type).toEqual("EXTENSION_FOUND_BUT_NOT_USED"); }); it("detects issues in extensionNotDeclared_1_0_glTF", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionNotDeclared_1_0_glTF.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTENSION_FOUND_BUT_NOT_USED"); }); it("detects issues in extensionNotNecessary_1_1_glTF", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionNotNecessary_1_1_glTF.json" ); expect(result.length).toEqual(0); }); it("detects issues in extensionNotDeclaredAsRequired", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionNotDeclaredAsRequired.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTENSION_REQUIRED_BUT_NOT_DECLARED"); }); it("detects issues in extensionRequiredButNotUsed", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionRequiredButNotUsed.json" ); expect(result.length).toEqual(3); expect(result.get(0).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(1).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(2).type).toEqual("EXTENSION_REQUIRED_BUT_NOT_USED"); }); it("detects issues in extensionsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in extensionsRequiredDuplicateElement", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionsRequiredDuplicateElement.json" ); expect(result.length).toEqual(3); expect(result.get(0).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(1).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(2).type).toEqual("ARRAY_ELEMENT_NOT_UNIQUE"); }); it("detects issues in extensionsRequiredInvalidArrayLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionsRequiredInvalidArrayLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in extensionsRequiredInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionsRequiredInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in extensionsUsedDuplicateElement", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionsUsedDuplicateElement.json" ); expect(result.length).toEqual(3); expect(result.get(0).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(1).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(2).type).toEqual("ARRAY_ELEMENT_NOT_UNIQUE"); }); it("detects issues in extensionsUsedInvalidArrayLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionsUsedInvalidArrayLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in extensionsUsedInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionsUsedInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in extensionsValueInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionsValueInvalidType.json" ); expect(result.length).toEqual(3); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); expect(result.get(1).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(2).type).toEqual("EXTENSION_USED_BUT_NOT_FOUND"); }); it("detects issues in extensionUsedButNotFound", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extensionUsedButNotFound.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("EXTENSION_NOT_SUPPORTED"); expect(result.get(1).type).toEqual("EXTENSION_USED_BUT_NOT_FOUND"); }); it("detects issues in extrasUnexpectedType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/extrasUnexpectedType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_UNEXPECTED"); }); it("detects issues in validTilesetWithIB3dmWithInvalidAlignment", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/validTilesetWithIB3dmWithInvalidAlignment.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); it("detects issues in tilesetWithCycleA", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetWithCycleA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTERNAL_TILESET_VALIDATION_ERROR"); }); it("detects no issues in tilesetWithMultipleExternal", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tilesetWithMultipleExternal.json" ); expect(result.length).toEqual(0); }); it("detects no issues in tilesets/tiles/i3dm/i3dmWithUri/tileset.json", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tiles/i3dm/i3dmWithUri/tileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_WARNING"); }); }); ================================================ FILE: specs/data/Samples/ImplicitTileMetadata/subtrees/1.1/0.0.0.json ================================================ { "buffers": [ { "byteLength": 32, "uri": "../shared.bin" } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 1 }, { "buffer": 0, "byteOffset": 8, "byteLength": 5 }, { "buffer": 0, "byteOffset": 16, "byteLength": 12 } ], "tileAvailability": { "bitstream": 0, "availableCount": 5 }, "contentAvailability": [ { "constant": 1 } ], "childSubtreeAvailability": { "constant": 0 }, "propertyTables": [ { "class": "tile", "count": 1, "properties": { "quadrant": { "values": 1 }, "color": { "values": 2 } } } ], "tileMetadata": 0 } ================================================ FILE: specs/data/Samples/ImplicitTileMetadata/tileset_1.1.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "ImplicitTileMetadataSchema", "classes": { "tile": { "properties": { "quadrant": { "type": "ENUM", "enumType": "quadrantType" }, "color": { "type": "VEC3", "componentType": "UINT8" } } } }, "enums": { "quadrantType": { "valueType": "UINT8", "values": [ { "name": "Southwest", "value": 0 }, { "name": "Southeast", "value": 1 }, { "name": "Northwest", "value": 2 }, { "name": "Northeast", "value": 3 }, { "name": "None", "value": 4 } ] } } }, "geometricError": 240, "root": { "boundingVolume": { "region": [ -1.3197209591796106, 0.6988424218, -1.3196390408203893, 0.6989055782, 0, 88 ] }, "content": { "uri": "content/{level}/{x}/{y}.b3dm" }, "implicitTiling": { "subdivisionScheme": "QUADTREE", "subtreeLevels": 2, "availableLevels": 2, "subtrees": { "uri": "subtrees/1.1/{level}.{x}.{y}.json" } }, "geometricError": 70, "refine": "ADD" } } ================================================ FILE: specs/data/Samples/PaddingIssues/README.md ================================================ A set of tests for the handling of padding bytes for GLB data in B3DM tiles. (Created for https://github.com/CesiumGS/3d-tiles-validator/issues/256) The tilesets `tilesetA`/`B`/`C`/`D` refer to B3DM files `llA`/`B`/`C`/`D`, respectively. - A: A B3DM where the length was not aligned to 8 bytes, causing an issue: "The byte length must be aligned to 8 bytes" - B: Contains additional 0-bytes at the end of the B3DM, to ensure that its length is aligned to 8 bytes. The validator will extract the length of the actual GLB data (without padding) from the GLB header. This passes validation. - C: Contains additional 0-bytes at the end of the BIN chunk of the GLB. The glTF validator will report an issue: "GLB-stored BIN chunk contains 4 extra padding byte(s)." - D: Contains ` `-bytes (spaces) at the end of the JSON chunk of the GLB. This also passes validation. ================================================ FILE: specs/data/Samples/PaddingIssues/tilesetA.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "llA.b3dm" } } } ================================================ FILE: specs/data/Samples/PaddingIssues/tilesetB.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "llB.b3dm" } } } ================================================ FILE: specs/data/Samples/PaddingIssues/tilesetC.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "llC.b3dm" } } } ================================================ FILE: specs/data/Samples/PaddingIssues/tilesetD.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "llD.b3dm" } } } ================================================ FILE: specs/data/Samples/PaddingIssues/tilesetE.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "llD.b3dm" } } } ================================================ FILE: specs/data/Samples/README.md ================================================ - `TilesetOfTilesets` is the original one from https://github.com/CesiumGS/cesium/tree/66e626c0f9d567f58ead7922d965490a5034e895/Specs/Data/Cesium3DTiles/Tilesets - `TilesetOfTilesetsWithError` is the same, but with "tileset3/ll.b3dm" modified so that it contains an invalid size, causing a content validation error - `SparseImplicitQuadtree` is from https://github.com/javagl/3d-tiles-samples/tree/7272499dcf9a998ef80c741c9da77abcfe3bf011/1.1/SparseImplicitQuadtree - `TilesetWithFullMetadata` is https://github.com/javagl/3d-tiles-samples/tree/ec028f3580f71fa5b730fa9020f071fc22391ac3/1.1/TilesetWithFullMetadata - `TilesetGzipped` is from https://github.com/CesiumGS/3d-tiles-validator/tree/b583fa66b29645506e66288db39b2d29aacb02c0/validator/specs/data/TilesetGzipped - `ImplicitTileMetadats` is based on https://github.com/CesiumGS/cesium/tree/ad90cfdf3a59ab9a2ab6dff9212198253d5a7c31/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata, but with fixes to pass validation ================================================ FILE: specs/data/Samples/SparseImplicitQuadtree/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 1024.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.00625, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.00625 ] }, "geometricError" : 32.0, "refine" : "ADD", "content" : { "uri" : "content/content_{level}__{x}_{y}.glb" }, "implicitTiling" : { "subdivisionScheme" : "QUADTREE", "subtreeLevels" : 3, "availableLevels" : 6, "subtrees" : { "uri" : "subtrees/{level}.{x}.{y}.subtree" } } } } ================================================ FILE: specs/data/Samples/TilesetOfTilesets/tileset.json ================================================ { "asset": { "version": "1.0", "tilesetVersion": "1.2.3" }, "properties": { "id": { "minimum": 0, "maximum": 9 }, "Longitude": { "minimum": -1.3197192952275933, "maximum": -1.319644104024109 }, "Latitude": { "minimum": 0.698848878034009, "maximum": 0.6989046192460953 }, "Height": { "minimum": 6.161747192963958, "maximum": 85.41026367992163 } }, "geometricError": 240, "root": { "boundingVolume": { "region": [ -1.3197209591796106, 0.6988424218, -1.3196390408203893, 0.6989055782, 0, 88 ] }, "geometricError": 70, "refine": "ADD", "content": { "uri": "tileset2.json" } } } ================================================ FILE: specs/data/Samples/TilesetOfTilesets/tileset2.json ================================================ { "asset": { "version": "1.0" }, "geometricError": 240, "root": { "boundingVolume": { "region": [ -1.3197209591796106, 0.6988424218, -1.3196390408203893, 0.6989055782, 0, 88 ] }, "geometricError": 70, "refine": "ADD", "content": { "uri": "parent.b3dm" }, "children": [ { "boundingVolume": { "region": [ -1.3197209591796106, 0.6988424218, -1.31968, 0.698874, 0, 20 ] }, "geometricError": 0, "content": { "uri": "tileset3/tileset3.json" } }, { "boundingVolume": { "region": [ -1.31968, 0.6988424218, -1.3196390408203893, 0.698874, 0, 20 ] }, "geometricError": 0, "content": { "uri": "lr.b3dm" } }, { "boundingVolume": { "region": [ -1.31968, 0.698874, -1.3196390408203893, 0.6989055782, 0, 20 ] }, "geometricError": 0, "content": { "uri": "ur.b3dm" } }, { "boundingVolume": { "region": [ -1.3197209591796106, 0.698874, -1.31968, 0.6989055782, 0, 20 ] }, "geometricError": 0, "content": { "uri": "ul.b3dm" } } ] } } ================================================ FILE: specs/data/Samples/TilesetOfTilesets/tileset3/tileset3.json ================================================ { "asset": { "version": "1.0" }, "geometricError": 70, "root": { "boundingVolume": { "region": [ -1.3197209591796106, 0.6988424218, -1.31968, 0.698874, 0, 20 ] }, "geometricError": 0, "refine": "ADD", "content": { "uri": "ll.b3dm" } } } ================================================ FILE: specs/data/Samples/TilesetOfTilesetsWithError/tileset.json ================================================ { "asset": { "version": "1.0", "tilesetVersion": "1.2.3" }, "properties": { "id": { "minimum": 0, "maximum": 9 }, "Longitude": { "minimum": -1.3197192952275933, "maximum": -1.319644104024109 }, "Latitude": { "minimum": 0.698848878034009, "maximum": 0.6989046192460953 }, "Height": { "minimum": 6.161747192963958, "maximum": 85.41026367992163 } }, "geometricError": 240, "root": { "boundingVolume": { "region": [ -1.3197209591796106, 0.6988424218, -1.3196390408203893, 0.6989055782, 0, 88 ] }, "geometricError": 70, "refine": "ADD", "content": { "uri": "tileset2.json" } } } ================================================ FILE: specs/data/Samples/TilesetOfTilesetsWithError/tileset2.json ================================================ { "asset": { "version": "1.0" }, "geometricError": 240, "root": { "boundingVolume": { "region": [ -1.3197209591796106, 0.6988424218, -1.3196390408203893, 0.6989055782, 0, 88 ] }, "geometricError": 70, "refine": "ADD", "content": { "uri": "parent.b3dm" }, "children": [ { "boundingVolume": { "region": [ -1.3197209591796106, 0.6988424218, -1.31968, 0.698874, 0, 20 ] }, "geometricError": 0, "content": { "uri": "tileset3/tileset3.json" } }, { "boundingVolume": { "region": [ -1.31968, 0.6988424218, -1.3196390408203893, 0.698874, 0, 20 ] }, "geometricError": 0, "content": { "uri": "lr.b3dm" } }, { "boundingVolume": { "region": [ -1.31968, 0.698874, -1.3196390408203893, 0.6989055782, 0, 20 ] }, "geometricError": 0, "content": { "uri": "ur.b3dm" } }, { "boundingVolume": { "region": [ -1.3197209591796106, 0.698874, -1.31968, 0.6989055782, 0, 20 ] }, "geometricError": 0, "content": { "uri": "ul.b3dm" } } ] } } ================================================ FILE: specs/data/Samples/TilesetOfTilesetsWithError/tileset3/tileset3.json ================================================ { "asset": { "version": "1.0" }, "geometricError": 70, "root": { "boundingVolume": { "region": [ -1.3197209591796106, 0.6988424218, -1.31968, 0.698874, 0, 20 ] }, "geometricError": 0, "refine": "ADD", "content": { "uri": "ll.b3dm" } } } ================================================ FILE: specs/data/Samples/TilesetWithFullMetadata/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "schema" : { "id": "TilesetWithFullMetadataSchema", "classes" : { "exampleClass" : { "name" : "Full example metadata class", "description" : "An example metadata class with all property types", "properties" : { "example_STRING" : { "name" : "Example STRING property", "description" : "An example property, with type STRING", "type" : "STRING", "array" : false }, "example_variable_length_STRING_array" : { "name" : "Example variable-length STRING array property", "description" : "An example variable length array property, with type STRING", "type" : "STRING", "array" : true }, "example_fixed_length_STRING_array" : { "name" : "Example fixed-length STRING array property", "description" : "An example fixed length array property, with type STRING", "type" : "STRING", "array" : true, "count" : 5 }, "example_BOOLEAN" : { "name" : "Example BOOLEAN property", "description" : "An example property, with type BOOLEAN", "type" : "BOOLEAN", "array" : false }, "example_variable_length_BOOLEAN_array" : { "name" : "Example variable-length BOOLEAN array property", "description" : "An example variable length array property, with type BOOLEAN", "type" : "BOOLEAN", "array" : true }, "example_fixed_length_BOOLEAN_array" : { "name" : "Example fixed-length BOOLEAN array property", "description" : "An example fixed length array property, with type BOOLEAN", "type" : "BOOLEAN", "array" : true, "count" : 5 }, "example_ENUM" : { "name" : "Example ENUM property", "description" : "An example property, with type ENUM, enum type exampleEnumType", "type" : "ENUM", "enumType" : "exampleEnumType", "array" : false }, "example_variable_length_ENUM_array" : { "name" : "Example variable-length ENUM array property", "description" : "An example variable length array property, with type ENUM, enum type exampleEnumType", "type" : "ENUM", "enumType" : "exampleEnumType", "array" : true }, "example_fixed_length_ENUM_array" : { "name" : "Example fixed-length ENUM array property", "description" : "An example fixed length array property, with type ENUM, enum type exampleEnumType", "type" : "ENUM", "enumType" : "exampleEnumType", "array" : true, "count" : 5 }, "example_INT8_SCALAR" : { "name" : "Example SCALAR property with INT8 components", "description" : "An example property, with type SCALAR, with component type INT8", "type" : "SCALAR", "componentType" : "INT8", "array" : false, "normalized" : false }, "example_variable_length_INT8_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with INT8 components", "description" : "An example variable length array property, with type SCALAR, with component type INT8", "type" : "SCALAR", "componentType" : "INT8", "array" : true, "normalized" : false }, "example_fixed_length_INT8_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with INT8 components", "description" : "An example fixed length array property, with type SCALAR, with component type INT8", "type" : "SCALAR", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT8_SCALAR" : { "name" : "Example SCALAR property with normalized INT8 components", "description" : "An example property, with type SCALAR, with component type INT8, normalized", "type" : "SCALAR", "componentType" : "INT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT8_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with normalized INT8 components", "description" : "An example variable length array property, with type SCALAR, with component type INT8, normalized", "type" : "SCALAR", "componentType" : "INT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT8_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with normalized INT8 components", "description" : "An example fixed length array property, with type SCALAR, with component type INT8, normalized", "type" : "SCALAR", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : true }, "example_UINT8_SCALAR" : { "name" : "Example SCALAR property with UINT8 components", "description" : "An example property, with type SCALAR, with component type UINT8", "type" : "SCALAR", "componentType" : "UINT8", "array" : false, "normalized" : false }, "example_variable_length_UINT8_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with UINT8 components", "description" : "An example variable length array property, with type SCALAR, with component type UINT8", "type" : "SCALAR", "componentType" : "UINT8", "array" : true, "normalized" : false }, "example_fixed_length_UINT8_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with UINT8 components", "description" : "An example fixed length array property, with type SCALAR, with component type UINT8", "type" : "SCALAR", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT8_SCALAR" : { "name" : "Example SCALAR property with normalized UINT8 components", "description" : "An example property, with type SCALAR, with component type UINT8, normalized", "type" : "SCALAR", "componentType" : "UINT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT8_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with normalized UINT8 components", "description" : "An example variable length array property, with type SCALAR, with component type UINT8, normalized", "type" : "SCALAR", "componentType" : "UINT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT8_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with normalized UINT8 components", "description" : "An example fixed length array property, with type SCALAR, with component type UINT8, normalized", "type" : "SCALAR", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : true }, "example_INT16_SCALAR" : { "name" : "Example SCALAR property with INT16 components", "description" : "An example property, with type SCALAR, with component type INT16", "type" : "SCALAR", "componentType" : "INT16", "array" : false, "normalized" : false }, "example_variable_length_INT16_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with INT16 components", "description" : "An example variable length array property, with type SCALAR, with component type INT16", "type" : "SCALAR", "componentType" : "INT16", "array" : true, "normalized" : false }, "example_fixed_length_INT16_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with INT16 components", "description" : "An example fixed length array property, with type SCALAR, with component type INT16", "type" : "SCALAR", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT16_SCALAR" : { "name" : "Example SCALAR property with normalized INT16 components", "description" : "An example property, with type SCALAR, with component type INT16, normalized", "type" : "SCALAR", "componentType" : "INT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT16_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with normalized INT16 components", "description" : "An example variable length array property, with type SCALAR, with component type INT16, normalized", "type" : "SCALAR", "componentType" : "INT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT16_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with normalized INT16 components", "description" : "An example fixed length array property, with type SCALAR, with component type INT16, normalized", "type" : "SCALAR", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : true }, "example_UINT16_SCALAR" : { "name" : "Example SCALAR property with UINT16 components", "description" : "An example property, with type SCALAR, with component type UINT16", "type" : "SCALAR", "componentType" : "UINT16", "array" : false, "normalized" : false }, "example_variable_length_UINT16_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with UINT16 components", "description" : "An example variable length array property, with type SCALAR, with component type UINT16", "type" : "SCALAR", "componentType" : "UINT16", "array" : true, "normalized" : false }, "example_fixed_length_UINT16_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with UINT16 components", "description" : "An example fixed length array property, with type SCALAR, with component type UINT16", "type" : "SCALAR", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT16_SCALAR" : { "name" : "Example SCALAR property with normalized UINT16 components", "description" : "An example property, with type SCALAR, with component type UINT16, normalized", "type" : "SCALAR", "componentType" : "UINT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT16_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with normalized UINT16 components", "description" : "An example variable length array property, with type SCALAR, with component type UINT16, normalized", "type" : "SCALAR", "componentType" : "UINT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT16_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with normalized UINT16 components", "description" : "An example fixed length array property, with type SCALAR, with component type UINT16, normalized", "type" : "SCALAR", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : true }, "example_INT32_SCALAR" : { "name" : "Example SCALAR property with INT32 components", "description" : "An example property, with type SCALAR, with component type INT32", "type" : "SCALAR", "componentType" : "INT32", "array" : false, "normalized" : false }, "example_variable_length_INT32_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with INT32 components", "description" : "An example variable length array property, with type SCALAR, with component type INT32", "type" : "SCALAR", "componentType" : "INT32", "array" : true, "normalized" : false }, "example_fixed_length_INT32_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with INT32 components", "description" : "An example fixed length array property, with type SCALAR, with component type INT32", "type" : "SCALAR", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT32_SCALAR" : { "name" : "Example SCALAR property with normalized INT32 components", "description" : "An example property, with type SCALAR, with component type INT32, normalized", "type" : "SCALAR", "componentType" : "INT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT32_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with normalized INT32 components", "description" : "An example variable length array property, with type SCALAR, with component type INT32, normalized", "type" : "SCALAR", "componentType" : "INT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT32_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with normalized INT32 components", "description" : "An example fixed length array property, with type SCALAR, with component type INT32, normalized", "type" : "SCALAR", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : true }, "example_UINT32_SCALAR" : { "name" : "Example SCALAR property with UINT32 components", "description" : "An example property, with type SCALAR, with component type UINT32", "type" : "SCALAR", "componentType" : "UINT32", "array" : false, "normalized" : false }, "example_variable_length_UINT32_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with UINT32 components", "description" : "An example variable length array property, with type SCALAR, with component type UINT32", "type" : "SCALAR", "componentType" : "UINT32", "array" : true, "normalized" : false }, "example_fixed_length_UINT32_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with UINT32 components", "description" : "An example fixed length array property, with type SCALAR, with component type UINT32", "type" : "SCALAR", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT32_SCALAR" : { "name" : "Example SCALAR property with normalized UINT32 components", "description" : "An example property, with type SCALAR, with component type UINT32, normalized", "type" : "SCALAR", "componentType" : "UINT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT32_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with normalized UINT32 components", "description" : "An example variable length array property, with type SCALAR, with component type UINT32, normalized", "type" : "SCALAR", "componentType" : "UINT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT32_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with normalized UINT32 components", "description" : "An example fixed length array property, with type SCALAR, with component type UINT32, normalized", "type" : "SCALAR", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : true }, "example_INT64_SCALAR" : { "name" : "Example SCALAR property with INT64 components", "description" : "An example property, with type SCALAR, with component type INT64", "type" : "SCALAR", "componentType" : "INT64", "array" : false, "normalized" : false }, "example_variable_length_INT64_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with INT64 components", "description" : "An example variable length array property, with type SCALAR, with component type INT64", "type" : "SCALAR", "componentType" : "INT64", "array" : true, "normalized" : false }, "example_fixed_length_INT64_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with INT64 components", "description" : "An example fixed length array property, with type SCALAR, with component type INT64", "type" : "SCALAR", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT64_SCALAR" : { "name" : "Example SCALAR property with normalized INT64 components", "description" : "An example property, with type SCALAR, with component type INT64, normalized", "type" : "SCALAR", "componentType" : "INT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT64_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with normalized INT64 components", "description" : "An example variable length array property, with type SCALAR, with component type INT64, normalized", "type" : "SCALAR", "componentType" : "INT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT64_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with normalized INT64 components", "description" : "An example fixed length array property, with type SCALAR, with component type INT64, normalized", "type" : "SCALAR", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : true }, "example_UINT64_SCALAR" : { "name" : "Example SCALAR property with UINT64 components", "description" : "An example property, with type SCALAR, with component type UINT64", "type" : "SCALAR", "componentType" : "UINT64", "array" : false, "normalized" : false }, "example_variable_length_UINT64_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with UINT64 components", "description" : "An example variable length array property, with type SCALAR, with component type UINT64", "type" : "SCALAR", "componentType" : "UINT64", "array" : true, "normalized" : false }, "example_fixed_length_UINT64_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with UINT64 components", "description" : "An example fixed length array property, with type SCALAR, with component type UINT64", "type" : "SCALAR", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT64_SCALAR" : { "name" : "Example SCALAR property with normalized UINT64 components", "description" : "An example property, with type SCALAR, with component type UINT64, normalized", "type" : "SCALAR", "componentType" : "UINT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT64_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with normalized UINT64 components", "description" : "An example variable length array property, with type SCALAR, with component type UINT64, normalized", "type" : "SCALAR", "componentType" : "UINT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT64_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with normalized UINT64 components", "description" : "An example fixed length array property, with type SCALAR, with component type UINT64, normalized", "type" : "SCALAR", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : true }, "example_FLOAT32_SCALAR" : { "name" : "Example SCALAR property with FLOAT32 components", "description" : "An example property, with type SCALAR, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32", "array" : false, "normalized" : false }, "example_variable_length_FLOAT32_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with FLOAT32 components", "description" : "An example variable length array property, with type SCALAR, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT32_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with FLOAT32 components", "description" : "An example fixed length array property, with type SCALAR, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32", "array" : true, "count" : 5, "normalized" : false }, "example_FLOAT64_SCALAR" : { "name" : "Example SCALAR property with FLOAT64 components", "description" : "An example property, with type SCALAR, with component type FLOAT64", "type" : "SCALAR", "componentType" : "FLOAT64", "array" : false, "normalized" : false }, "example_variable_length_FLOAT64_SCALAR_array" : { "name" : "Example variable-length SCALAR array property with FLOAT64 components", "description" : "An example variable length array property, with type SCALAR, with component type FLOAT64", "type" : "SCALAR", "componentType" : "FLOAT64", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT64_SCALAR_array" : { "name" : "Example fixed-length SCALAR array property with FLOAT64 components", "description" : "An example fixed length array property, with type SCALAR, with component type FLOAT64", "type" : "SCALAR", "componentType" : "FLOAT64", "array" : true, "count" : 5, "normalized" : false }, "example_INT8_VEC2" : { "name" : "Example VEC2 property with INT8 components", "description" : "An example property, with type VEC2, with component type INT8", "type" : "VEC2", "componentType" : "INT8", "array" : false, "normalized" : false }, "example_variable_length_INT8_VEC2_array" : { "name" : "Example variable-length VEC2 array property with INT8 components", "description" : "An example variable length array property, with type VEC2, with component type INT8", "type" : "VEC2", "componentType" : "INT8", "array" : true, "normalized" : false }, "example_fixed_length_INT8_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with INT8 components", "description" : "An example fixed length array property, with type VEC2, with component type INT8", "type" : "VEC2", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT8_VEC2" : { "name" : "Example VEC2 property with normalized INT8 components", "description" : "An example property, with type VEC2, with component type INT8, normalized", "type" : "VEC2", "componentType" : "INT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT8_VEC2_array" : { "name" : "Example variable-length VEC2 array property with normalized INT8 components", "description" : "An example variable length array property, with type VEC2, with component type INT8, normalized", "type" : "VEC2", "componentType" : "INT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT8_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with normalized INT8 components", "description" : "An example fixed length array property, with type VEC2, with component type INT8, normalized", "type" : "VEC2", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : true }, "example_UINT8_VEC2" : { "name" : "Example VEC2 property with UINT8 components", "description" : "An example property, with type VEC2, with component type UINT8", "type" : "VEC2", "componentType" : "UINT8", "array" : false, "normalized" : false }, "example_variable_length_UINT8_VEC2_array" : { "name" : "Example variable-length VEC2 array property with UINT8 components", "description" : "An example variable length array property, with type VEC2, with component type UINT8", "type" : "VEC2", "componentType" : "UINT8", "array" : true, "normalized" : false }, "example_fixed_length_UINT8_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with UINT8 components", "description" : "An example fixed length array property, with type VEC2, with component type UINT8", "type" : "VEC2", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT8_VEC2" : { "name" : "Example VEC2 property with normalized UINT8 components", "description" : "An example property, with type VEC2, with component type UINT8, normalized", "type" : "VEC2", "componentType" : "UINT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT8_VEC2_array" : { "name" : "Example variable-length VEC2 array property with normalized UINT8 components", "description" : "An example variable length array property, with type VEC2, with component type UINT8, normalized", "type" : "VEC2", "componentType" : "UINT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT8_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with normalized UINT8 components", "description" : "An example fixed length array property, with type VEC2, with component type UINT8, normalized", "type" : "VEC2", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : true }, "example_INT16_VEC2" : { "name" : "Example VEC2 property with INT16 components", "description" : "An example property, with type VEC2, with component type INT16", "type" : "VEC2", "componentType" : "INT16", "array" : false, "normalized" : false }, "example_variable_length_INT16_VEC2_array" : { "name" : "Example variable-length VEC2 array property with INT16 components", "description" : "An example variable length array property, with type VEC2, with component type INT16", "type" : "VEC2", "componentType" : "INT16", "array" : true, "normalized" : false }, "example_fixed_length_INT16_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with INT16 components", "description" : "An example fixed length array property, with type VEC2, with component type INT16", "type" : "VEC2", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT16_VEC2" : { "name" : "Example VEC2 property with normalized INT16 components", "description" : "An example property, with type VEC2, with component type INT16, normalized", "type" : "VEC2", "componentType" : "INT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT16_VEC2_array" : { "name" : "Example variable-length VEC2 array property with normalized INT16 components", "description" : "An example variable length array property, with type VEC2, with component type INT16, normalized", "type" : "VEC2", "componentType" : "INT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT16_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with normalized INT16 components", "description" : "An example fixed length array property, with type VEC2, with component type INT16, normalized", "type" : "VEC2", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : true }, "example_UINT16_VEC2" : { "name" : "Example VEC2 property with UINT16 components", "description" : "An example property, with type VEC2, with component type UINT16", "type" : "VEC2", "componentType" : "UINT16", "array" : false, "normalized" : false }, "example_variable_length_UINT16_VEC2_array" : { "name" : "Example variable-length VEC2 array property with UINT16 components", "description" : "An example variable length array property, with type VEC2, with component type UINT16", "type" : "VEC2", "componentType" : "UINT16", "array" : true, "normalized" : false }, "example_fixed_length_UINT16_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with UINT16 components", "description" : "An example fixed length array property, with type VEC2, with component type UINT16", "type" : "VEC2", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT16_VEC2" : { "name" : "Example VEC2 property with normalized UINT16 components", "description" : "An example property, with type VEC2, with component type UINT16, normalized", "type" : "VEC2", "componentType" : "UINT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT16_VEC2_array" : { "name" : "Example variable-length VEC2 array property with normalized UINT16 components", "description" : "An example variable length array property, with type VEC2, with component type UINT16, normalized", "type" : "VEC2", "componentType" : "UINT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT16_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with normalized UINT16 components", "description" : "An example fixed length array property, with type VEC2, with component type UINT16, normalized", "type" : "VEC2", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : true }, "example_INT32_VEC2" : { "name" : "Example VEC2 property with INT32 components", "description" : "An example property, with type VEC2, with component type INT32", "type" : "VEC2", "componentType" : "INT32", "array" : false, "normalized" : false }, "example_variable_length_INT32_VEC2_array" : { "name" : "Example variable-length VEC2 array property with INT32 components", "description" : "An example variable length array property, with type VEC2, with component type INT32", "type" : "VEC2", "componentType" : "INT32", "array" : true, "normalized" : false }, "example_fixed_length_INT32_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with INT32 components", "description" : "An example fixed length array property, with type VEC2, with component type INT32", "type" : "VEC2", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT32_VEC2" : { "name" : "Example VEC2 property with normalized INT32 components", "description" : "An example property, with type VEC2, with component type INT32, normalized", "type" : "VEC2", "componentType" : "INT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT32_VEC2_array" : { "name" : "Example variable-length VEC2 array property with normalized INT32 components", "description" : "An example variable length array property, with type VEC2, with component type INT32, normalized", "type" : "VEC2", "componentType" : "INT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT32_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with normalized INT32 components", "description" : "An example fixed length array property, with type VEC2, with component type INT32, normalized", "type" : "VEC2", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : true }, "example_UINT32_VEC2" : { "name" : "Example VEC2 property with UINT32 components", "description" : "An example property, with type VEC2, with component type UINT32", "type" : "VEC2", "componentType" : "UINT32", "array" : false, "normalized" : false }, "example_variable_length_UINT32_VEC2_array" : { "name" : "Example variable-length VEC2 array property with UINT32 components", "description" : "An example variable length array property, with type VEC2, with component type UINT32", "type" : "VEC2", "componentType" : "UINT32", "array" : true, "normalized" : false }, "example_fixed_length_UINT32_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with UINT32 components", "description" : "An example fixed length array property, with type VEC2, with component type UINT32", "type" : "VEC2", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT32_VEC2" : { "name" : "Example VEC2 property with normalized UINT32 components", "description" : "An example property, with type VEC2, with component type UINT32, normalized", "type" : "VEC2", "componentType" : "UINT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT32_VEC2_array" : { "name" : "Example variable-length VEC2 array property with normalized UINT32 components", "description" : "An example variable length array property, with type VEC2, with component type UINT32, normalized", "type" : "VEC2", "componentType" : "UINT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT32_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with normalized UINT32 components", "description" : "An example fixed length array property, with type VEC2, with component type UINT32, normalized", "type" : "VEC2", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : true }, "example_INT64_VEC2" : { "name" : "Example VEC2 property with INT64 components", "description" : "An example property, with type VEC2, with component type INT64", "type" : "VEC2", "componentType" : "INT64", "array" : false, "normalized" : false }, "example_variable_length_INT64_VEC2_array" : { "name" : "Example variable-length VEC2 array property with INT64 components", "description" : "An example variable length array property, with type VEC2, with component type INT64", "type" : "VEC2", "componentType" : "INT64", "array" : true, "normalized" : false }, "example_fixed_length_INT64_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with INT64 components", "description" : "An example fixed length array property, with type VEC2, with component type INT64", "type" : "VEC2", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT64_VEC2" : { "name" : "Example VEC2 property with normalized INT64 components", "description" : "An example property, with type VEC2, with component type INT64, normalized", "type" : "VEC2", "componentType" : "INT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT64_VEC2_array" : { "name" : "Example variable-length VEC2 array property with normalized INT64 components", "description" : "An example variable length array property, with type VEC2, with component type INT64, normalized", "type" : "VEC2", "componentType" : "INT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT64_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with normalized INT64 components", "description" : "An example fixed length array property, with type VEC2, with component type INT64, normalized", "type" : "VEC2", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : true }, "example_UINT64_VEC2" : { "name" : "Example VEC2 property with UINT64 components", "description" : "An example property, with type VEC2, with component type UINT64", "type" : "VEC2", "componentType" : "UINT64", "array" : false, "normalized" : false }, "example_variable_length_UINT64_VEC2_array" : { "name" : "Example variable-length VEC2 array property with UINT64 components", "description" : "An example variable length array property, with type VEC2, with component type UINT64", "type" : "VEC2", "componentType" : "UINT64", "array" : true, "normalized" : false }, "example_fixed_length_UINT64_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with UINT64 components", "description" : "An example fixed length array property, with type VEC2, with component type UINT64", "type" : "VEC2", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT64_VEC2" : { "name" : "Example VEC2 property with normalized UINT64 components", "description" : "An example property, with type VEC2, with component type UINT64, normalized", "type" : "VEC2", "componentType" : "UINT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT64_VEC2_array" : { "name" : "Example variable-length VEC2 array property with normalized UINT64 components", "description" : "An example variable length array property, with type VEC2, with component type UINT64, normalized", "type" : "VEC2", "componentType" : "UINT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT64_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with normalized UINT64 components", "description" : "An example fixed length array property, with type VEC2, with component type UINT64, normalized", "type" : "VEC2", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : true }, "example_FLOAT32_VEC2" : { "name" : "Example VEC2 property with FLOAT32 components", "description" : "An example property, with type VEC2, with component type FLOAT32", "type" : "VEC2", "componentType" : "FLOAT32", "array" : false, "normalized" : false }, "example_variable_length_FLOAT32_VEC2_array" : { "name" : "Example variable-length VEC2 array property with FLOAT32 components", "description" : "An example variable length array property, with type VEC2, with component type FLOAT32", "type" : "VEC2", "componentType" : "FLOAT32", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT32_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with FLOAT32 components", "description" : "An example fixed length array property, with type VEC2, with component type FLOAT32", "type" : "VEC2", "componentType" : "FLOAT32", "array" : true, "count" : 5, "normalized" : false }, "example_FLOAT64_VEC2" : { "name" : "Example VEC2 property with FLOAT64 components", "description" : "An example property, with type VEC2, with component type FLOAT64", "type" : "VEC2", "componentType" : "FLOAT64", "array" : false, "normalized" : false }, "example_variable_length_FLOAT64_VEC2_array" : { "name" : "Example variable-length VEC2 array property with FLOAT64 components", "description" : "An example variable length array property, with type VEC2, with component type FLOAT64", "type" : "VEC2", "componentType" : "FLOAT64", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT64_VEC2_array" : { "name" : "Example fixed-length VEC2 array property with FLOAT64 components", "description" : "An example fixed length array property, with type VEC2, with component type FLOAT64", "type" : "VEC2", "componentType" : "FLOAT64", "array" : true, "count" : 5, "normalized" : false }, "example_INT8_VEC3" : { "name" : "Example VEC3 property with INT8 components", "description" : "An example property, with type VEC3, with component type INT8", "type" : "VEC3", "componentType" : "INT8", "array" : false, "normalized" : false }, "example_variable_length_INT8_VEC3_array" : { "name" : "Example variable-length VEC3 array property with INT8 components", "description" : "An example variable length array property, with type VEC3, with component type INT8", "type" : "VEC3", "componentType" : "INT8", "array" : true, "normalized" : false }, "example_fixed_length_INT8_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with INT8 components", "description" : "An example fixed length array property, with type VEC3, with component type INT8", "type" : "VEC3", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT8_VEC3" : { "name" : "Example VEC3 property with normalized INT8 components", "description" : "An example property, with type VEC3, with component type INT8, normalized", "type" : "VEC3", "componentType" : "INT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT8_VEC3_array" : { "name" : "Example variable-length VEC3 array property with normalized INT8 components", "description" : "An example variable length array property, with type VEC3, with component type INT8, normalized", "type" : "VEC3", "componentType" : "INT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT8_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with normalized INT8 components", "description" : "An example fixed length array property, with type VEC3, with component type INT8, normalized", "type" : "VEC3", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : true }, "example_UINT8_VEC3" : { "name" : "Example VEC3 property with UINT8 components", "description" : "An example property, with type VEC3, with component type UINT8", "type" : "VEC3", "componentType" : "UINT8", "array" : false, "normalized" : false }, "example_variable_length_UINT8_VEC3_array" : { "name" : "Example variable-length VEC3 array property with UINT8 components", "description" : "An example variable length array property, with type VEC3, with component type UINT8", "type" : "VEC3", "componentType" : "UINT8", "array" : true, "normalized" : false }, "example_fixed_length_UINT8_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with UINT8 components", "description" : "An example fixed length array property, with type VEC3, with component type UINT8", "type" : "VEC3", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT8_VEC3" : { "name" : "Example VEC3 property with normalized UINT8 components", "description" : "An example property, with type VEC3, with component type UINT8, normalized", "type" : "VEC3", "componentType" : "UINT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT8_VEC3_array" : { "name" : "Example variable-length VEC3 array property with normalized UINT8 components", "description" : "An example variable length array property, with type VEC3, with component type UINT8, normalized", "type" : "VEC3", "componentType" : "UINT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT8_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with normalized UINT8 components", "description" : "An example fixed length array property, with type VEC3, with component type UINT8, normalized", "type" : "VEC3", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : true }, "example_INT16_VEC3" : { "name" : "Example VEC3 property with INT16 components", "description" : "An example property, with type VEC3, with component type INT16", "type" : "VEC3", "componentType" : "INT16", "array" : false, "normalized" : false }, "example_variable_length_INT16_VEC3_array" : { "name" : "Example variable-length VEC3 array property with INT16 components", "description" : "An example variable length array property, with type VEC3, with component type INT16", "type" : "VEC3", "componentType" : "INT16", "array" : true, "normalized" : false }, "example_fixed_length_INT16_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with INT16 components", "description" : "An example fixed length array property, with type VEC3, with component type INT16", "type" : "VEC3", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT16_VEC3" : { "name" : "Example VEC3 property with normalized INT16 components", "description" : "An example property, with type VEC3, with component type INT16, normalized", "type" : "VEC3", "componentType" : "INT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT16_VEC3_array" : { "name" : "Example variable-length VEC3 array property with normalized INT16 components", "description" : "An example variable length array property, with type VEC3, with component type INT16, normalized", "type" : "VEC3", "componentType" : "INT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT16_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with normalized INT16 components", "description" : "An example fixed length array property, with type VEC3, with component type INT16, normalized", "type" : "VEC3", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : true }, "example_UINT16_VEC3" : { "name" : "Example VEC3 property with UINT16 components", "description" : "An example property, with type VEC3, with component type UINT16", "type" : "VEC3", "componentType" : "UINT16", "array" : false, "normalized" : false }, "example_variable_length_UINT16_VEC3_array" : { "name" : "Example variable-length VEC3 array property with UINT16 components", "description" : "An example variable length array property, with type VEC3, with component type UINT16", "type" : "VEC3", "componentType" : "UINT16", "array" : true, "normalized" : false }, "example_fixed_length_UINT16_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with UINT16 components", "description" : "An example fixed length array property, with type VEC3, with component type UINT16", "type" : "VEC3", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT16_VEC3" : { "name" : "Example VEC3 property with normalized UINT16 components", "description" : "An example property, with type VEC3, with component type UINT16, normalized", "type" : "VEC3", "componentType" : "UINT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT16_VEC3_array" : { "name" : "Example variable-length VEC3 array property with normalized UINT16 components", "description" : "An example variable length array property, with type VEC3, with component type UINT16, normalized", "type" : "VEC3", "componentType" : "UINT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT16_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with normalized UINT16 components", "description" : "An example fixed length array property, with type VEC3, with component type UINT16, normalized", "type" : "VEC3", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : true }, "example_INT32_VEC3" : { "name" : "Example VEC3 property with INT32 components", "description" : "An example property, with type VEC3, with component type INT32", "type" : "VEC3", "componentType" : "INT32", "array" : false, "normalized" : false }, "example_variable_length_INT32_VEC3_array" : { "name" : "Example variable-length VEC3 array property with INT32 components", "description" : "An example variable length array property, with type VEC3, with component type INT32", "type" : "VEC3", "componentType" : "INT32", "array" : true, "normalized" : false }, "example_fixed_length_INT32_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with INT32 components", "description" : "An example fixed length array property, with type VEC3, with component type INT32", "type" : "VEC3", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT32_VEC3" : { "name" : "Example VEC3 property with normalized INT32 components", "description" : "An example property, with type VEC3, with component type INT32, normalized", "type" : "VEC3", "componentType" : "INT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT32_VEC3_array" : { "name" : "Example variable-length VEC3 array property with normalized INT32 components", "description" : "An example variable length array property, with type VEC3, with component type INT32, normalized", "type" : "VEC3", "componentType" : "INT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT32_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with normalized INT32 components", "description" : "An example fixed length array property, with type VEC3, with component type INT32, normalized", "type" : "VEC3", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : true }, "example_UINT32_VEC3" : { "name" : "Example VEC3 property with UINT32 components", "description" : "An example property, with type VEC3, with component type UINT32", "type" : "VEC3", "componentType" : "UINT32", "array" : false, "normalized" : false }, "example_variable_length_UINT32_VEC3_array" : { "name" : "Example variable-length VEC3 array property with UINT32 components", "description" : "An example variable length array property, with type VEC3, with component type UINT32", "type" : "VEC3", "componentType" : "UINT32", "array" : true, "normalized" : false }, "example_fixed_length_UINT32_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with UINT32 components", "description" : "An example fixed length array property, with type VEC3, with component type UINT32", "type" : "VEC3", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT32_VEC3" : { "name" : "Example VEC3 property with normalized UINT32 components", "description" : "An example property, with type VEC3, with component type UINT32, normalized", "type" : "VEC3", "componentType" : "UINT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT32_VEC3_array" : { "name" : "Example variable-length VEC3 array property with normalized UINT32 components", "description" : "An example variable length array property, with type VEC3, with component type UINT32, normalized", "type" : "VEC3", "componentType" : "UINT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT32_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with normalized UINT32 components", "description" : "An example fixed length array property, with type VEC3, with component type UINT32, normalized", "type" : "VEC3", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : true }, "example_INT64_VEC3" : { "name" : "Example VEC3 property with INT64 components", "description" : "An example property, with type VEC3, with component type INT64", "type" : "VEC3", "componentType" : "INT64", "array" : false, "normalized" : false }, "example_variable_length_INT64_VEC3_array" : { "name" : "Example variable-length VEC3 array property with INT64 components", "description" : "An example variable length array property, with type VEC3, with component type INT64", "type" : "VEC3", "componentType" : "INT64", "array" : true, "normalized" : false }, "example_fixed_length_INT64_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with INT64 components", "description" : "An example fixed length array property, with type VEC3, with component type INT64", "type" : "VEC3", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT64_VEC3" : { "name" : "Example VEC3 property with normalized INT64 components", "description" : "An example property, with type VEC3, with component type INT64, normalized", "type" : "VEC3", "componentType" : "INT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT64_VEC3_array" : { "name" : "Example variable-length VEC3 array property with normalized INT64 components", "description" : "An example variable length array property, with type VEC3, with component type INT64, normalized", "type" : "VEC3", "componentType" : "INT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT64_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with normalized INT64 components", "description" : "An example fixed length array property, with type VEC3, with component type INT64, normalized", "type" : "VEC3", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : true }, "example_UINT64_VEC3" : { "name" : "Example VEC3 property with UINT64 components", "description" : "An example property, with type VEC3, with component type UINT64", "type" : "VEC3", "componentType" : "UINT64", "array" : false, "normalized" : false }, "example_variable_length_UINT64_VEC3_array" : { "name" : "Example variable-length VEC3 array property with UINT64 components", "description" : "An example variable length array property, with type VEC3, with component type UINT64", "type" : "VEC3", "componentType" : "UINT64", "array" : true, "normalized" : false }, "example_fixed_length_UINT64_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with UINT64 components", "description" : "An example fixed length array property, with type VEC3, with component type UINT64", "type" : "VEC3", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT64_VEC3" : { "name" : "Example VEC3 property with normalized UINT64 components", "description" : "An example property, with type VEC3, with component type UINT64, normalized", "type" : "VEC3", "componentType" : "UINT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT64_VEC3_array" : { "name" : "Example variable-length VEC3 array property with normalized UINT64 components", "description" : "An example variable length array property, with type VEC3, with component type UINT64, normalized", "type" : "VEC3", "componentType" : "UINT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT64_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with normalized UINT64 components", "description" : "An example fixed length array property, with type VEC3, with component type UINT64, normalized", "type" : "VEC3", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : true }, "example_FLOAT32_VEC3" : { "name" : "Example VEC3 property with FLOAT32 components", "description" : "An example property, with type VEC3, with component type FLOAT32", "type" : "VEC3", "componentType" : "FLOAT32", "array" : false, "normalized" : false }, "example_variable_length_FLOAT32_VEC3_array" : { "name" : "Example variable-length VEC3 array property with FLOAT32 components", "description" : "An example variable length array property, with type VEC3, with component type FLOAT32", "type" : "VEC3", "componentType" : "FLOAT32", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT32_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with FLOAT32 components", "description" : "An example fixed length array property, with type VEC3, with component type FLOAT32", "type" : "VEC3", "componentType" : "FLOAT32", "array" : true, "count" : 5, "normalized" : false }, "example_FLOAT64_VEC3" : { "name" : "Example VEC3 property with FLOAT64 components", "description" : "An example property, with type VEC3, with component type FLOAT64", "type" : "VEC3", "componentType" : "FLOAT64", "array" : false, "normalized" : false }, "example_variable_length_FLOAT64_VEC3_array" : { "name" : "Example variable-length VEC3 array property with FLOAT64 components", "description" : "An example variable length array property, with type VEC3, with component type FLOAT64", "type" : "VEC3", "componentType" : "FLOAT64", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT64_VEC3_array" : { "name" : "Example fixed-length VEC3 array property with FLOAT64 components", "description" : "An example fixed length array property, with type VEC3, with component type FLOAT64", "type" : "VEC3", "componentType" : "FLOAT64", "array" : true, "count" : 5, "normalized" : false }, "example_INT8_VEC4" : { "name" : "Example VEC4 property with INT8 components", "description" : "An example property, with type VEC4, with component type INT8", "type" : "VEC4", "componentType" : "INT8", "array" : false, "normalized" : false }, "example_variable_length_INT8_VEC4_array" : { "name" : "Example variable-length VEC4 array property with INT8 components", "description" : "An example variable length array property, with type VEC4, with component type INT8", "type" : "VEC4", "componentType" : "INT8", "array" : true, "normalized" : false }, "example_fixed_length_INT8_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with INT8 components", "description" : "An example fixed length array property, with type VEC4, with component type INT8", "type" : "VEC4", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT8_VEC4" : { "name" : "Example VEC4 property with normalized INT8 components", "description" : "An example property, with type VEC4, with component type INT8, normalized", "type" : "VEC4", "componentType" : "INT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT8_VEC4_array" : { "name" : "Example variable-length VEC4 array property with normalized INT8 components", "description" : "An example variable length array property, with type VEC4, with component type INT8, normalized", "type" : "VEC4", "componentType" : "INT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT8_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with normalized INT8 components", "description" : "An example fixed length array property, with type VEC4, with component type INT8, normalized", "type" : "VEC4", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : true }, "example_UINT8_VEC4" : { "name" : "Example VEC4 property with UINT8 components", "description" : "An example property, with type VEC4, with component type UINT8", "type" : "VEC4", "componentType" : "UINT8", "array" : false, "normalized" : false }, "example_variable_length_UINT8_VEC4_array" : { "name" : "Example variable-length VEC4 array property with UINT8 components", "description" : "An example variable length array property, with type VEC4, with component type UINT8", "type" : "VEC4", "componentType" : "UINT8", "array" : true, "normalized" : false }, "example_fixed_length_UINT8_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with UINT8 components", "description" : "An example fixed length array property, with type VEC4, with component type UINT8", "type" : "VEC4", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT8_VEC4" : { "name" : "Example VEC4 property with normalized UINT8 components", "description" : "An example property, with type VEC4, with component type UINT8, normalized", "type" : "VEC4", "componentType" : "UINT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT8_VEC4_array" : { "name" : "Example variable-length VEC4 array property with normalized UINT8 components", "description" : "An example variable length array property, with type VEC4, with component type UINT8, normalized", "type" : "VEC4", "componentType" : "UINT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT8_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with normalized UINT8 components", "description" : "An example fixed length array property, with type VEC4, with component type UINT8, normalized", "type" : "VEC4", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : true }, "example_INT16_VEC4" : { "name" : "Example VEC4 property with INT16 components", "description" : "An example property, with type VEC4, with component type INT16", "type" : "VEC4", "componentType" : "INT16", "array" : false, "normalized" : false }, "example_variable_length_INT16_VEC4_array" : { "name" : "Example variable-length VEC4 array property with INT16 components", "description" : "An example variable length array property, with type VEC4, with component type INT16", "type" : "VEC4", "componentType" : "INT16", "array" : true, "normalized" : false }, "example_fixed_length_INT16_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with INT16 components", "description" : "An example fixed length array property, with type VEC4, with component type INT16", "type" : "VEC4", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT16_VEC4" : { "name" : "Example VEC4 property with normalized INT16 components", "description" : "An example property, with type VEC4, with component type INT16, normalized", "type" : "VEC4", "componentType" : "INT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT16_VEC4_array" : { "name" : "Example variable-length VEC4 array property with normalized INT16 components", "description" : "An example variable length array property, with type VEC4, with component type INT16, normalized", "type" : "VEC4", "componentType" : "INT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT16_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with normalized INT16 components", "description" : "An example fixed length array property, with type VEC4, with component type INT16, normalized", "type" : "VEC4", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : true }, "example_UINT16_VEC4" : { "name" : "Example VEC4 property with UINT16 components", "description" : "An example property, with type VEC4, with component type UINT16", "type" : "VEC4", "componentType" : "UINT16", "array" : false, "normalized" : false }, "example_variable_length_UINT16_VEC4_array" : { "name" : "Example variable-length VEC4 array property with UINT16 components", "description" : "An example variable length array property, with type VEC4, with component type UINT16", "type" : "VEC4", "componentType" : "UINT16", "array" : true, "normalized" : false }, "example_fixed_length_UINT16_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with UINT16 components", "description" : "An example fixed length array property, with type VEC4, with component type UINT16", "type" : "VEC4", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT16_VEC4" : { "name" : "Example VEC4 property with normalized UINT16 components", "description" : "An example property, with type VEC4, with component type UINT16, normalized", "type" : "VEC4", "componentType" : "UINT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT16_VEC4_array" : { "name" : "Example variable-length VEC4 array property with normalized UINT16 components", "description" : "An example variable length array property, with type VEC4, with component type UINT16, normalized", "type" : "VEC4", "componentType" : "UINT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT16_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with normalized UINT16 components", "description" : "An example fixed length array property, with type VEC4, with component type UINT16, normalized", "type" : "VEC4", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : true }, "example_INT32_VEC4" : { "name" : "Example VEC4 property with INT32 components", "description" : "An example property, with type VEC4, with component type INT32", "type" : "VEC4", "componentType" : "INT32", "array" : false, "normalized" : false }, "example_variable_length_INT32_VEC4_array" : { "name" : "Example variable-length VEC4 array property with INT32 components", "description" : "An example variable length array property, with type VEC4, with component type INT32", "type" : "VEC4", "componentType" : "INT32", "array" : true, "normalized" : false }, "example_fixed_length_INT32_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with INT32 components", "description" : "An example fixed length array property, with type VEC4, with component type INT32", "type" : "VEC4", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT32_VEC4" : { "name" : "Example VEC4 property with normalized INT32 components", "description" : "An example property, with type VEC4, with component type INT32, normalized", "type" : "VEC4", "componentType" : "INT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT32_VEC4_array" : { "name" : "Example variable-length VEC4 array property with normalized INT32 components", "description" : "An example variable length array property, with type VEC4, with component type INT32, normalized", "type" : "VEC4", "componentType" : "INT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT32_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with normalized INT32 components", "description" : "An example fixed length array property, with type VEC4, with component type INT32, normalized", "type" : "VEC4", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : true }, "example_UINT32_VEC4" : { "name" : "Example VEC4 property with UINT32 components", "description" : "An example property, with type VEC4, with component type UINT32", "type" : "VEC4", "componentType" : "UINT32", "array" : false, "normalized" : false }, "example_variable_length_UINT32_VEC4_array" : { "name" : "Example variable-length VEC4 array property with UINT32 components", "description" : "An example variable length array property, with type VEC4, with component type UINT32", "type" : "VEC4", "componentType" : "UINT32", "array" : true, "normalized" : false }, "example_fixed_length_UINT32_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with UINT32 components", "description" : "An example fixed length array property, with type VEC4, with component type UINT32", "type" : "VEC4", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT32_VEC4" : { "name" : "Example VEC4 property with normalized UINT32 components", "description" : "An example property, with type VEC4, with component type UINT32, normalized", "type" : "VEC4", "componentType" : "UINT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT32_VEC4_array" : { "name" : "Example variable-length VEC4 array property with normalized UINT32 components", "description" : "An example variable length array property, with type VEC4, with component type UINT32, normalized", "type" : "VEC4", "componentType" : "UINT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT32_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with normalized UINT32 components", "description" : "An example fixed length array property, with type VEC4, with component type UINT32, normalized", "type" : "VEC4", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : true }, "example_INT64_VEC4" : { "name" : "Example VEC4 property with INT64 components", "description" : "An example property, with type VEC4, with component type INT64", "type" : "VEC4", "componentType" : "INT64", "array" : false, "normalized" : false }, "example_variable_length_INT64_VEC4_array" : { "name" : "Example variable-length VEC4 array property with INT64 components", "description" : "An example variable length array property, with type VEC4, with component type INT64", "type" : "VEC4", "componentType" : "INT64", "array" : true, "normalized" : false }, "example_fixed_length_INT64_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with INT64 components", "description" : "An example fixed length array property, with type VEC4, with component type INT64", "type" : "VEC4", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT64_VEC4" : { "name" : "Example VEC4 property with normalized INT64 components", "description" : "An example property, with type VEC4, with component type INT64, normalized", "type" : "VEC4", "componentType" : "INT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT64_VEC4_array" : { "name" : "Example variable-length VEC4 array property with normalized INT64 components", "description" : "An example variable length array property, with type VEC4, with component type INT64, normalized", "type" : "VEC4", "componentType" : "INT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT64_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with normalized INT64 components", "description" : "An example fixed length array property, with type VEC4, with component type INT64, normalized", "type" : "VEC4", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : true }, "example_UINT64_VEC4" : { "name" : "Example VEC4 property with UINT64 components", "description" : "An example property, with type VEC4, with component type UINT64", "type" : "VEC4", "componentType" : "UINT64", "array" : false, "normalized" : false }, "example_variable_length_UINT64_VEC4_array" : { "name" : "Example variable-length VEC4 array property with UINT64 components", "description" : "An example variable length array property, with type VEC4, with component type UINT64", "type" : "VEC4", "componentType" : "UINT64", "array" : true, "normalized" : false }, "example_fixed_length_UINT64_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with UINT64 components", "description" : "An example fixed length array property, with type VEC4, with component type UINT64", "type" : "VEC4", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT64_VEC4" : { "name" : "Example VEC4 property with normalized UINT64 components", "description" : "An example property, with type VEC4, with component type UINT64, normalized", "type" : "VEC4", "componentType" : "UINT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT64_VEC4_array" : { "name" : "Example variable-length VEC4 array property with normalized UINT64 components", "description" : "An example variable length array property, with type VEC4, with component type UINT64, normalized", "type" : "VEC4", "componentType" : "UINT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT64_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with normalized UINT64 components", "description" : "An example fixed length array property, with type VEC4, with component type UINT64, normalized", "type" : "VEC4", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : true }, "example_FLOAT32_VEC4" : { "name" : "Example VEC4 property with FLOAT32 components", "description" : "An example property, with type VEC4, with component type FLOAT32", "type" : "VEC4", "componentType" : "FLOAT32", "array" : false, "normalized" : false }, "example_variable_length_FLOAT32_VEC4_array" : { "name" : "Example variable-length VEC4 array property with FLOAT32 components", "description" : "An example variable length array property, with type VEC4, with component type FLOAT32", "type" : "VEC4", "componentType" : "FLOAT32", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT32_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with FLOAT32 components", "description" : "An example fixed length array property, with type VEC4, with component type FLOAT32", "type" : "VEC4", "componentType" : "FLOAT32", "array" : true, "count" : 5, "normalized" : false }, "example_FLOAT64_VEC4" : { "name" : "Example VEC4 property with FLOAT64 components", "description" : "An example property, with type VEC4, with component type FLOAT64", "type" : "VEC4", "componentType" : "FLOAT64", "array" : false, "normalized" : false }, "example_variable_length_FLOAT64_VEC4_array" : { "name" : "Example variable-length VEC4 array property with FLOAT64 components", "description" : "An example variable length array property, with type VEC4, with component type FLOAT64", "type" : "VEC4", "componentType" : "FLOAT64", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT64_VEC4_array" : { "name" : "Example fixed-length VEC4 array property with FLOAT64 components", "description" : "An example fixed length array property, with type VEC4, with component type FLOAT64", "type" : "VEC4", "componentType" : "FLOAT64", "array" : true, "count" : 5, "normalized" : false }, "example_INT8_MAT2" : { "name" : "Example MAT2 property with INT8 components", "description" : "An example property, with type MAT2, with component type INT8", "type" : "MAT2", "componentType" : "INT8", "array" : false, "normalized" : false }, "example_variable_length_INT8_MAT2_array" : { "name" : "Example variable-length MAT2 array property with INT8 components", "description" : "An example variable length array property, with type MAT2, with component type INT8", "type" : "MAT2", "componentType" : "INT8", "array" : true, "normalized" : false }, "example_fixed_length_INT8_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with INT8 components", "description" : "An example fixed length array property, with type MAT2, with component type INT8", "type" : "MAT2", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT8_MAT2" : { "name" : "Example MAT2 property with normalized INT8 components", "description" : "An example property, with type MAT2, with component type INT8, normalized", "type" : "MAT2", "componentType" : "INT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT8_MAT2_array" : { "name" : "Example variable-length MAT2 array property with normalized INT8 components", "description" : "An example variable length array property, with type MAT2, with component type INT8, normalized", "type" : "MAT2", "componentType" : "INT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT8_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with normalized INT8 components", "description" : "An example fixed length array property, with type MAT2, with component type INT8, normalized", "type" : "MAT2", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : true }, "example_UINT8_MAT2" : { "name" : "Example MAT2 property with UINT8 components", "description" : "An example property, with type MAT2, with component type UINT8", "type" : "MAT2", "componentType" : "UINT8", "array" : false, "normalized" : false }, "example_variable_length_UINT8_MAT2_array" : { "name" : "Example variable-length MAT2 array property with UINT8 components", "description" : "An example variable length array property, with type MAT2, with component type UINT8", "type" : "MAT2", "componentType" : "UINT8", "array" : true, "normalized" : false }, "example_fixed_length_UINT8_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with UINT8 components", "description" : "An example fixed length array property, with type MAT2, with component type UINT8", "type" : "MAT2", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT8_MAT2" : { "name" : "Example MAT2 property with normalized UINT8 components", "description" : "An example property, with type MAT2, with component type UINT8, normalized", "type" : "MAT2", "componentType" : "UINT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT8_MAT2_array" : { "name" : "Example variable-length MAT2 array property with normalized UINT8 components", "description" : "An example variable length array property, with type MAT2, with component type UINT8, normalized", "type" : "MAT2", "componentType" : "UINT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT8_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with normalized UINT8 components", "description" : "An example fixed length array property, with type MAT2, with component type UINT8, normalized", "type" : "MAT2", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : true }, "example_INT16_MAT2" : { "name" : "Example MAT2 property with INT16 components", "description" : "An example property, with type MAT2, with component type INT16", "type" : "MAT2", "componentType" : "INT16", "array" : false, "normalized" : false }, "example_variable_length_INT16_MAT2_array" : { "name" : "Example variable-length MAT2 array property with INT16 components", "description" : "An example variable length array property, with type MAT2, with component type INT16", "type" : "MAT2", "componentType" : "INT16", "array" : true, "normalized" : false }, "example_fixed_length_INT16_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with INT16 components", "description" : "An example fixed length array property, with type MAT2, with component type INT16", "type" : "MAT2", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT16_MAT2" : { "name" : "Example MAT2 property with normalized INT16 components", "description" : "An example property, with type MAT2, with component type INT16, normalized", "type" : "MAT2", "componentType" : "INT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT16_MAT2_array" : { "name" : "Example variable-length MAT2 array property with normalized INT16 components", "description" : "An example variable length array property, with type MAT2, with component type INT16, normalized", "type" : "MAT2", "componentType" : "INT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT16_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with normalized INT16 components", "description" : "An example fixed length array property, with type MAT2, with component type INT16, normalized", "type" : "MAT2", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : true }, "example_UINT16_MAT2" : { "name" : "Example MAT2 property with UINT16 components", "description" : "An example property, with type MAT2, with component type UINT16", "type" : "MAT2", "componentType" : "UINT16", "array" : false, "normalized" : false }, "example_variable_length_UINT16_MAT2_array" : { "name" : "Example variable-length MAT2 array property with UINT16 components", "description" : "An example variable length array property, with type MAT2, with component type UINT16", "type" : "MAT2", "componentType" : "UINT16", "array" : true, "normalized" : false }, "example_fixed_length_UINT16_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with UINT16 components", "description" : "An example fixed length array property, with type MAT2, with component type UINT16", "type" : "MAT2", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT16_MAT2" : { "name" : "Example MAT2 property with normalized UINT16 components", "description" : "An example property, with type MAT2, with component type UINT16, normalized", "type" : "MAT2", "componentType" : "UINT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT16_MAT2_array" : { "name" : "Example variable-length MAT2 array property with normalized UINT16 components", "description" : "An example variable length array property, with type MAT2, with component type UINT16, normalized", "type" : "MAT2", "componentType" : "UINT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT16_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with normalized UINT16 components", "description" : "An example fixed length array property, with type MAT2, with component type UINT16, normalized", "type" : "MAT2", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : true }, "example_INT32_MAT2" : { "name" : "Example MAT2 property with INT32 components", "description" : "An example property, with type MAT2, with component type INT32", "type" : "MAT2", "componentType" : "INT32", "array" : false, "normalized" : false }, "example_variable_length_INT32_MAT2_array" : { "name" : "Example variable-length MAT2 array property with INT32 components", "description" : "An example variable length array property, with type MAT2, with component type INT32", "type" : "MAT2", "componentType" : "INT32", "array" : true, "normalized" : false }, "example_fixed_length_INT32_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with INT32 components", "description" : "An example fixed length array property, with type MAT2, with component type INT32", "type" : "MAT2", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT32_MAT2" : { "name" : "Example MAT2 property with normalized INT32 components", "description" : "An example property, with type MAT2, with component type INT32, normalized", "type" : "MAT2", "componentType" : "INT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT32_MAT2_array" : { "name" : "Example variable-length MAT2 array property with normalized INT32 components", "description" : "An example variable length array property, with type MAT2, with component type INT32, normalized", "type" : "MAT2", "componentType" : "INT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT32_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with normalized INT32 components", "description" : "An example fixed length array property, with type MAT2, with component type INT32, normalized", "type" : "MAT2", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : true }, "example_UINT32_MAT2" : { "name" : "Example MAT2 property with UINT32 components", "description" : "An example property, with type MAT2, with component type UINT32", "type" : "MAT2", "componentType" : "UINT32", "array" : false, "normalized" : false }, "example_variable_length_UINT32_MAT2_array" : { "name" : "Example variable-length MAT2 array property with UINT32 components", "description" : "An example variable length array property, with type MAT2, with component type UINT32", "type" : "MAT2", "componentType" : "UINT32", "array" : true, "normalized" : false }, "example_fixed_length_UINT32_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with UINT32 components", "description" : "An example fixed length array property, with type MAT2, with component type UINT32", "type" : "MAT2", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT32_MAT2" : { "name" : "Example MAT2 property with normalized UINT32 components", "description" : "An example property, with type MAT2, with component type UINT32, normalized", "type" : "MAT2", "componentType" : "UINT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT32_MAT2_array" : { "name" : "Example variable-length MAT2 array property with normalized UINT32 components", "description" : "An example variable length array property, with type MAT2, with component type UINT32, normalized", "type" : "MAT2", "componentType" : "UINT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT32_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with normalized UINT32 components", "description" : "An example fixed length array property, with type MAT2, with component type UINT32, normalized", "type" : "MAT2", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : true }, "example_INT64_MAT2" : { "name" : "Example MAT2 property with INT64 components", "description" : "An example property, with type MAT2, with component type INT64", "type" : "MAT2", "componentType" : "INT64", "array" : false, "normalized" : false }, "example_variable_length_INT64_MAT2_array" : { "name" : "Example variable-length MAT2 array property with INT64 components", "description" : "An example variable length array property, with type MAT2, with component type INT64", "type" : "MAT2", "componentType" : "INT64", "array" : true, "normalized" : false }, "example_fixed_length_INT64_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with INT64 components", "description" : "An example fixed length array property, with type MAT2, with component type INT64", "type" : "MAT2", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT64_MAT2" : { "name" : "Example MAT2 property with normalized INT64 components", "description" : "An example property, with type MAT2, with component type INT64, normalized", "type" : "MAT2", "componentType" : "INT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT64_MAT2_array" : { "name" : "Example variable-length MAT2 array property with normalized INT64 components", "description" : "An example variable length array property, with type MAT2, with component type INT64, normalized", "type" : "MAT2", "componentType" : "INT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT64_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with normalized INT64 components", "description" : "An example fixed length array property, with type MAT2, with component type INT64, normalized", "type" : "MAT2", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : true }, "example_UINT64_MAT2" : { "name" : "Example MAT2 property with UINT64 components", "description" : "An example property, with type MAT2, with component type UINT64", "type" : "MAT2", "componentType" : "UINT64", "array" : false, "normalized" : false }, "example_variable_length_UINT64_MAT2_array" : { "name" : "Example variable-length MAT2 array property with UINT64 components", "description" : "An example variable length array property, with type MAT2, with component type UINT64", "type" : "MAT2", "componentType" : "UINT64", "array" : true, "normalized" : false }, "example_fixed_length_UINT64_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with UINT64 components", "description" : "An example fixed length array property, with type MAT2, with component type UINT64", "type" : "MAT2", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT64_MAT2" : { "name" : "Example MAT2 property with normalized UINT64 components", "description" : "An example property, with type MAT2, with component type UINT64, normalized", "type" : "MAT2", "componentType" : "UINT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT64_MAT2_array" : { "name" : "Example variable-length MAT2 array property with normalized UINT64 components", "description" : "An example variable length array property, with type MAT2, with component type UINT64, normalized", "type" : "MAT2", "componentType" : "UINT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT64_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with normalized UINT64 components", "description" : "An example fixed length array property, with type MAT2, with component type UINT64, normalized", "type" : "MAT2", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : true }, "example_FLOAT32_MAT2" : { "name" : "Example MAT2 property with FLOAT32 components", "description" : "An example property, with type MAT2, with component type FLOAT32", "type" : "MAT2", "componentType" : "FLOAT32", "array" : false, "normalized" : false }, "example_variable_length_FLOAT32_MAT2_array" : { "name" : "Example variable-length MAT2 array property with FLOAT32 components", "description" : "An example variable length array property, with type MAT2, with component type FLOAT32", "type" : "MAT2", "componentType" : "FLOAT32", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT32_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with FLOAT32 components", "description" : "An example fixed length array property, with type MAT2, with component type FLOAT32", "type" : "MAT2", "componentType" : "FLOAT32", "array" : true, "count" : 5, "normalized" : false }, "example_FLOAT64_MAT2" : { "name" : "Example MAT2 property with FLOAT64 components", "description" : "An example property, with type MAT2, with component type FLOAT64", "type" : "MAT2", "componentType" : "FLOAT64", "array" : false, "normalized" : false }, "example_variable_length_FLOAT64_MAT2_array" : { "name" : "Example variable-length MAT2 array property with FLOAT64 components", "description" : "An example variable length array property, with type MAT2, with component type FLOAT64", "type" : "MAT2", "componentType" : "FLOAT64", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT64_MAT2_array" : { "name" : "Example fixed-length MAT2 array property with FLOAT64 components", "description" : "An example fixed length array property, with type MAT2, with component type FLOAT64", "type" : "MAT2", "componentType" : "FLOAT64", "array" : true, "count" : 5, "normalized" : false }, "example_INT8_MAT3" : { "name" : "Example MAT3 property with INT8 components", "description" : "An example property, with type MAT3, with component type INT8", "type" : "MAT3", "componentType" : "INT8", "array" : false, "normalized" : false }, "example_variable_length_INT8_MAT3_array" : { "name" : "Example variable-length MAT3 array property with INT8 components", "description" : "An example variable length array property, with type MAT3, with component type INT8", "type" : "MAT3", "componentType" : "INT8", "array" : true, "normalized" : false }, "example_fixed_length_INT8_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with INT8 components", "description" : "An example fixed length array property, with type MAT3, with component type INT8", "type" : "MAT3", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT8_MAT3" : { "name" : "Example MAT3 property with normalized INT8 components", "description" : "An example property, with type MAT3, with component type INT8, normalized", "type" : "MAT3", "componentType" : "INT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT8_MAT3_array" : { "name" : "Example variable-length MAT3 array property with normalized INT8 components", "description" : "An example variable length array property, with type MAT3, with component type INT8, normalized", "type" : "MAT3", "componentType" : "INT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT8_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with normalized INT8 components", "description" : "An example fixed length array property, with type MAT3, with component type INT8, normalized", "type" : "MAT3", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : true }, "example_UINT8_MAT3" : { "name" : "Example MAT3 property with UINT8 components", "description" : "An example property, with type MAT3, with component type UINT8", "type" : "MAT3", "componentType" : "UINT8", "array" : false, "normalized" : false }, "example_variable_length_UINT8_MAT3_array" : { "name" : "Example variable-length MAT3 array property with UINT8 components", "description" : "An example variable length array property, with type MAT3, with component type UINT8", "type" : "MAT3", "componentType" : "UINT8", "array" : true, "normalized" : false }, "example_fixed_length_UINT8_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with UINT8 components", "description" : "An example fixed length array property, with type MAT3, with component type UINT8", "type" : "MAT3", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT8_MAT3" : { "name" : "Example MAT3 property with normalized UINT8 components", "description" : "An example property, with type MAT3, with component type UINT8, normalized", "type" : "MAT3", "componentType" : "UINT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT8_MAT3_array" : { "name" : "Example variable-length MAT3 array property with normalized UINT8 components", "description" : "An example variable length array property, with type MAT3, with component type UINT8, normalized", "type" : "MAT3", "componentType" : "UINT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT8_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with normalized UINT8 components", "description" : "An example fixed length array property, with type MAT3, with component type UINT8, normalized", "type" : "MAT3", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : true }, "example_INT16_MAT3" : { "name" : "Example MAT3 property with INT16 components", "description" : "An example property, with type MAT3, with component type INT16", "type" : "MAT3", "componentType" : "INT16", "array" : false, "normalized" : false }, "example_variable_length_INT16_MAT3_array" : { "name" : "Example variable-length MAT3 array property with INT16 components", "description" : "An example variable length array property, with type MAT3, with component type INT16", "type" : "MAT3", "componentType" : "INT16", "array" : true, "normalized" : false }, "example_fixed_length_INT16_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with INT16 components", "description" : "An example fixed length array property, with type MAT3, with component type INT16", "type" : "MAT3", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT16_MAT3" : { "name" : "Example MAT3 property with normalized INT16 components", "description" : "An example property, with type MAT3, with component type INT16, normalized", "type" : "MAT3", "componentType" : "INT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT16_MAT3_array" : { "name" : "Example variable-length MAT3 array property with normalized INT16 components", "description" : "An example variable length array property, with type MAT3, with component type INT16, normalized", "type" : "MAT3", "componentType" : "INT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT16_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with normalized INT16 components", "description" : "An example fixed length array property, with type MAT3, with component type INT16, normalized", "type" : "MAT3", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : true }, "example_UINT16_MAT3" : { "name" : "Example MAT3 property with UINT16 components", "description" : "An example property, with type MAT3, with component type UINT16", "type" : "MAT3", "componentType" : "UINT16", "array" : false, "normalized" : false }, "example_variable_length_UINT16_MAT3_array" : { "name" : "Example variable-length MAT3 array property with UINT16 components", "description" : "An example variable length array property, with type MAT3, with component type UINT16", "type" : "MAT3", "componentType" : "UINT16", "array" : true, "normalized" : false }, "example_fixed_length_UINT16_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with UINT16 components", "description" : "An example fixed length array property, with type MAT3, with component type UINT16", "type" : "MAT3", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT16_MAT3" : { "name" : "Example MAT3 property with normalized UINT16 components", "description" : "An example property, with type MAT3, with component type UINT16, normalized", "type" : "MAT3", "componentType" : "UINT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT16_MAT3_array" : { "name" : "Example variable-length MAT3 array property with normalized UINT16 components", "description" : "An example variable length array property, with type MAT3, with component type UINT16, normalized", "type" : "MAT3", "componentType" : "UINT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT16_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with normalized UINT16 components", "description" : "An example fixed length array property, with type MAT3, with component type UINT16, normalized", "type" : "MAT3", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : true }, "example_INT32_MAT3" : { "name" : "Example MAT3 property with INT32 components", "description" : "An example property, with type MAT3, with component type INT32", "type" : "MAT3", "componentType" : "INT32", "array" : false, "normalized" : false }, "example_variable_length_INT32_MAT3_array" : { "name" : "Example variable-length MAT3 array property with INT32 components", "description" : "An example variable length array property, with type MAT3, with component type INT32", "type" : "MAT3", "componentType" : "INT32", "array" : true, "normalized" : false }, "example_fixed_length_INT32_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with INT32 components", "description" : "An example fixed length array property, with type MAT3, with component type INT32", "type" : "MAT3", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT32_MAT3" : { "name" : "Example MAT3 property with normalized INT32 components", "description" : "An example property, with type MAT3, with component type INT32, normalized", "type" : "MAT3", "componentType" : "INT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT32_MAT3_array" : { "name" : "Example variable-length MAT3 array property with normalized INT32 components", "description" : "An example variable length array property, with type MAT3, with component type INT32, normalized", "type" : "MAT3", "componentType" : "INT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT32_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with normalized INT32 components", "description" : "An example fixed length array property, with type MAT3, with component type INT32, normalized", "type" : "MAT3", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : true }, "example_UINT32_MAT3" : { "name" : "Example MAT3 property with UINT32 components", "description" : "An example property, with type MAT3, with component type UINT32", "type" : "MAT3", "componentType" : "UINT32", "array" : false, "normalized" : false }, "example_variable_length_UINT32_MAT3_array" : { "name" : "Example variable-length MAT3 array property with UINT32 components", "description" : "An example variable length array property, with type MAT3, with component type UINT32", "type" : "MAT3", "componentType" : "UINT32", "array" : true, "normalized" : false }, "example_fixed_length_UINT32_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with UINT32 components", "description" : "An example fixed length array property, with type MAT3, with component type UINT32", "type" : "MAT3", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT32_MAT3" : { "name" : "Example MAT3 property with normalized UINT32 components", "description" : "An example property, with type MAT3, with component type UINT32, normalized", "type" : "MAT3", "componentType" : "UINT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT32_MAT3_array" : { "name" : "Example variable-length MAT3 array property with normalized UINT32 components", "description" : "An example variable length array property, with type MAT3, with component type UINT32, normalized", "type" : "MAT3", "componentType" : "UINT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT32_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with normalized UINT32 components", "description" : "An example fixed length array property, with type MAT3, with component type UINT32, normalized", "type" : "MAT3", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : true }, "example_INT64_MAT3" : { "name" : "Example MAT3 property with INT64 components", "description" : "An example property, with type MAT3, with component type INT64", "type" : "MAT3", "componentType" : "INT64", "array" : false, "normalized" : false }, "example_variable_length_INT64_MAT3_array" : { "name" : "Example variable-length MAT3 array property with INT64 components", "description" : "An example variable length array property, with type MAT3, with component type INT64", "type" : "MAT3", "componentType" : "INT64", "array" : true, "normalized" : false }, "example_fixed_length_INT64_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with INT64 components", "description" : "An example fixed length array property, with type MAT3, with component type INT64", "type" : "MAT3", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT64_MAT3" : { "name" : "Example MAT3 property with normalized INT64 components", "description" : "An example property, with type MAT3, with component type INT64, normalized", "type" : "MAT3", "componentType" : "INT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT64_MAT3_array" : { "name" : "Example variable-length MAT3 array property with normalized INT64 components", "description" : "An example variable length array property, with type MAT3, with component type INT64, normalized", "type" : "MAT3", "componentType" : "INT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT64_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with normalized INT64 components", "description" : "An example fixed length array property, with type MAT3, with component type INT64, normalized", "type" : "MAT3", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : true }, "example_UINT64_MAT3" : { "name" : "Example MAT3 property with UINT64 components", "description" : "An example property, with type MAT3, with component type UINT64", "type" : "MAT3", "componentType" : "UINT64", "array" : false, "normalized" : false }, "example_variable_length_UINT64_MAT3_array" : { "name" : "Example variable-length MAT3 array property with UINT64 components", "description" : "An example variable length array property, with type MAT3, with component type UINT64", "type" : "MAT3", "componentType" : "UINT64", "array" : true, "normalized" : false }, "example_fixed_length_UINT64_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with UINT64 components", "description" : "An example fixed length array property, with type MAT3, with component type UINT64", "type" : "MAT3", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT64_MAT3" : { "name" : "Example MAT3 property with normalized UINT64 components", "description" : "An example property, with type MAT3, with component type UINT64, normalized", "type" : "MAT3", "componentType" : "UINT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT64_MAT3_array" : { "name" : "Example variable-length MAT3 array property with normalized UINT64 components", "description" : "An example variable length array property, with type MAT3, with component type UINT64, normalized", "type" : "MAT3", "componentType" : "UINT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT64_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with normalized UINT64 components", "description" : "An example fixed length array property, with type MAT3, with component type UINT64, normalized", "type" : "MAT3", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : true }, "example_FLOAT32_MAT3" : { "name" : "Example MAT3 property with FLOAT32 components", "description" : "An example property, with type MAT3, with component type FLOAT32", "type" : "MAT3", "componentType" : "FLOAT32", "array" : false, "normalized" : false }, "example_variable_length_FLOAT32_MAT3_array" : { "name" : "Example variable-length MAT3 array property with FLOAT32 components", "description" : "An example variable length array property, with type MAT3, with component type FLOAT32", "type" : "MAT3", "componentType" : "FLOAT32", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT32_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with FLOAT32 components", "description" : "An example fixed length array property, with type MAT3, with component type FLOAT32", "type" : "MAT3", "componentType" : "FLOAT32", "array" : true, "count" : 5, "normalized" : false }, "example_FLOAT64_MAT3" : { "name" : "Example MAT3 property with FLOAT64 components", "description" : "An example property, with type MAT3, with component type FLOAT64", "type" : "MAT3", "componentType" : "FLOAT64", "array" : false, "normalized" : false }, "example_variable_length_FLOAT64_MAT3_array" : { "name" : "Example variable-length MAT3 array property with FLOAT64 components", "description" : "An example variable length array property, with type MAT3, with component type FLOAT64", "type" : "MAT3", "componentType" : "FLOAT64", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT64_MAT3_array" : { "name" : "Example fixed-length MAT3 array property with FLOAT64 components", "description" : "An example fixed length array property, with type MAT3, with component type FLOAT64", "type" : "MAT3", "componentType" : "FLOAT64", "array" : true, "count" : 5, "normalized" : false }, "example_INT8_MAT4" : { "name" : "Example MAT4 property with INT8 components", "description" : "An example property, with type MAT4, with component type INT8", "type" : "MAT4", "componentType" : "INT8", "array" : false, "normalized" : false }, "example_variable_length_INT8_MAT4_array" : { "name" : "Example variable-length MAT4 array property with INT8 components", "description" : "An example variable length array property, with type MAT4, with component type INT8", "type" : "MAT4", "componentType" : "INT8", "array" : true, "normalized" : false }, "example_fixed_length_INT8_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with INT8 components", "description" : "An example fixed length array property, with type MAT4, with component type INT8", "type" : "MAT4", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT8_MAT4" : { "name" : "Example MAT4 property with normalized INT8 components", "description" : "An example property, with type MAT4, with component type INT8, normalized", "type" : "MAT4", "componentType" : "INT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT8_MAT4_array" : { "name" : "Example variable-length MAT4 array property with normalized INT8 components", "description" : "An example variable length array property, with type MAT4, with component type INT8, normalized", "type" : "MAT4", "componentType" : "INT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT8_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with normalized INT8 components", "description" : "An example fixed length array property, with type MAT4, with component type INT8, normalized", "type" : "MAT4", "componentType" : "INT8", "array" : true, "count" : 5, "normalized" : true }, "example_UINT8_MAT4" : { "name" : "Example MAT4 property with UINT8 components", "description" : "An example property, with type MAT4, with component type UINT8", "type" : "MAT4", "componentType" : "UINT8", "array" : false, "normalized" : false }, "example_variable_length_UINT8_MAT4_array" : { "name" : "Example variable-length MAT4 array property with UINT8 components", "description" : "An example variable length array property, with type MAT4, with component type UINT8", "type" : "MAT4", "componentType" : "UINT8", "array" : true, "normalized" : false }, "example_fixed_length_UINT8_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with UINT8 components", "description" : "An example fixed length array property, with type MAT4, with component type UINT8", "type" : "MAT4", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT8_MAT4" : { "name" : "Example MAT4 property with normalized UINT8 components", "description" : "An example property, with type MAT4, with component type UINT8, normalized", "type" : "MAT4", "componentType" : "UINT8", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT8_MAT4_array" : { "name" : "Example variable-length MAT4 array property with normalized UINT8 components", "description" : "An example variable length array property, with type MAT4, with component type UINT8, normalized", "type" : "MAT4", "componentType" : "UINT8", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT8_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with normalized UINT8 components", "description" : "An example fixed length array property, with type MAT4, with component type UINT8, normalized", "type" : "MAT4", "componentType" : "UINT8", "array" : true, "count" : 5, "normalized" : true }, "example_INT16_MAT4" : { "name" : "Example MAT4 property with INT16 components", "description" : "An example property, with type MAT4, with component type INT16", "type" : "MAT4", "componentType" : "INT16", "array" : false, "normalized" : false }, "example_variable_length_INT16_MAT4_array" : { "name" : "Example variable-length MAT4 array property with INT16 components", "description" : "An example variable length array property, with type MAT4, with component type INT16", "type" : "MAT4", "componentType" : "INT16", "array" : true, "normalized" : false }, "example_fixed_length_INT16_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with INT16 components", "description" : "An example fixed length array property, with type MAT4, with component type INT16", "type" : "MAT4", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT16_MAT4" : { "name" : "Example MAT4 property with normalized INT16 components", "description" : "An example property, with type MAT4, with component type INT16, normalized", "type" : "MAT4", "componentType" : "INT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT16_MAT4_array" : { "name" : "Example variable-length MAT4 array property with normalized INT16 components", "description" : "An example variable length array property, with type MAT4, with component type INT16, normalized", "type" : "MAT4", "componentType" : "INT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT16_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with normalized INT16 components", "description" : "An example fixed length array property, with type MAT4, with component type INT16, normalized", "type" : "MAT4", "componentType" : "INT16", "array" : true, "count" : 5, "normalized" : true }, "example_UINT16_MAT4" : { "name" : "Example MAT4 property with UINT16 components", "description" : "An example property, with type MAT4, with component type UINT16", "type" : "MAT4", "componentType" : "UINT16", "array" : false, "normalized" : false }, "example_variable_length_UINT16_MAT4_array" : { "name" : "Example variable-length MAT4 array property with UINT16 components", "description" : "An example variable length array property, with type MAT4, with component type UINT16", "type" : "MAT4", "componentType" : "UINT16", "array" : true, "normalized" : false }, "example_fixed_length_UINT16_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with UINT16 components", "description" : "An example fixed length array property, with type MAT4, with component type UINT16", "type" : "MAT4", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT16_MAT4" : { "name" : "Example MAT4 property with normalized UINT16 components", "description" : "An example property, with type MAT4, with component type UINT16, normalized", "type" : "MAT4", "componentType" : "UINT16", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT16_MAT4_array" : { "name" : "Example variable-length MAT4 array property with normalized UINT16 components", "description" : "An example variable length array property, with type MAT4, with component type UINT16, normalized", "type" : "MAT4", "componentType" : "UINT16", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT16_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with normalized UINT16 components", "description" : "An example fixed length array property, with type MAT4, with component type UINT16, normalized", "type" : "MAT4", "componentType" : "UINT16", "array" : true, "count" : 5, "normalized" : true }, "example_INT32_MAT4" : { "name" : "Example MAT4 property with INT32 components", "description" : "An example property, with type MAT4, with component type INT32", "type" : "MAT4", "componentType" : "INT32", "array" : false, "normalized" : false }, "example_variable_length_INT32_MAT4_array" : { "name" : "Example variable-length MAT4 array property with INT32 components", "description" : "An example variable length array property, with type MAT4, with component type INT32", "type" : "MAT4", "componentType" : "INT32", "array" : true, "normalized" : false }, "example_fixed_length_INT32_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with INT32 components", "description" : "An example fixed length array property, with type MAT4, with component type INT32", "type" : "MAT4", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT32_MAT4" : { "name" : "Example MAT4 property with normalized INT32 components", "description" : "An example property, with type MAT4, with component type INT32, normalized", "type" : "MAT4", "componentType" : "INT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT32_MAT4_array" : { "name" : "Example variable-length MAT4 array property with normalized INT32 components", "description" : "An example variable length array property, with type MAT4, with component type INT32, normalized", "type" : "MAT4", "componentType" : "INT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT32_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with normalized INT32 components", "description" : "An example fixed length array property, with type MAT4, with component type INT32, normalized", "type" : "MAT4", "componentType" : "INT32", "array" : true, "count" : 5, "normalized" : true }, "example_UINT32_MAT4" : { "name" : "Example MAT4 property with UINT32 components", "description" : "An example property, with type MAT4, with component type UINT32", "type" : "MAT4", "componentType" : "UINT32", "array" : false, "normalized" : false }, "example_variable_length_UINT32_MAT4_array" : { "name" : "Example variable-length MAT4 array property with UINT32 components", "description" : "An example variable length array property, with type MAT4, with component type UINT32", "type" : "MAT4", "componentType" : "UINT32", "array" : true, "normalized" : false }, "example_fixed_length_UINT32_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with UINT32 components", "description" : "An example fixed length array property, with type MAT4, with component type UINT32", "type" : "MAT4", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT32_MAT4" : { "name" : "Example MAT4 property with normalized UINT32 components", "description" : "An example property, with type MAT4, with component type UINT32, normalized", "type" : "MAT4", "componentType" : "UINT32", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT32_MAT4_array" : { "name" : "Example variable-length MAT4 array property with normalized UINT32 components", "description" : "An example variable length array property, with type MAT4, with component type UINT32, normalized", "type" : "MAT4", "componentType" : "UINT32", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT32_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with normalized UINT32 components", "description" : "An example fixed length array property, with type MAT4, with component type UINT32, normalized", "type" : "MAT4", "componentType" : "UINT32", "array" : true, "count" : 5, "normalized" : true }, "example_INT64_MAT4" : { "name" : "Example MAT4 property with INT64 components", "description" : "An example property, with type MAT4, with component type INT64", "type" : "MAT4", "componentType" : "INT64", "array" : false, "normalized" : false }, "example_variable_length_INT64_MAT4_array" : { "name" : "Example variable-length MAT4 array property with INT64 components", "description" : "An example variable length array property, with type MAT4, with component type INT64", "type" : "MAT4", "componentType" : "INT64", "array" : true, "normalized" : false }, "example_fixed_length_INT64_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with INT64 components", "description" : "An example fixed length array property, with type MAT4, with component type INT64", "type" : "MAT4", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_INT64_MAT4" : { "name" : "Example MAT4 property with normalized INT64 components", "description" : "An example property, with type MAT4, with component type INT64, normalized", "type" : "MAT4", "componentType" : "INT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_INT64_MAT4_array" : { "name" : "Example variable-length MAT4 array property with normalized INT64 components", "description" : "An example variable length array property, with type MAT4, with component type INT64, normalized", "type" : "MAT4", "componentType" : "INT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_INT64_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with normalized INT64 components", "description" : "An example fixed length array property, with type MAT4, with component type INT64, normalized", "type" : "MAT4", "componentType" : "INT64", "array" : true, "count" : 5, "normalized" : true }, "example_UINT64_MAT4" : { "name" : "Example MAT4 property with UINT64 components", "description" : "An example property, with type MAT4, with component type UINT64", "type" : "MAT4", "componentType" : "UINT64", "array" : false, "normalized" : false }, "example_variable_length_UINT64_MAT4_array" : { "name" : "Example variable-length MAT4 array property with UINT64 components", "description" : "An example variable length array property, with type MAT4, with component type UINT64", "type" : "MAT4", "componentType" : "UINT64", "array" : true, "normalized" : false }, "example_fixed_length_UINT64_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with UINT64 components", "description" : "An example fixed length array property, with type MAT4, with component type UINT64", "type" : "MAT4", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : false }, "example_normalized_UINT64_MAT4" : { "name" : "Example MAT4 property with normalized UINT64 components", "description" : "An example property, with type MAT4, with component type UINT64, normalized", "type" : "MAT4", "componentType" : "UINT64", "array" : false, "normalized" : true }, "example_variable_length_normalized_UINT64_MAT4_array" : { "name" : "Example variable-length MAT4 array property with normalized UINT64 components", "description" : "An example variable length array property, with type MAT4, with component type UINT64, normalized", "type" : "MAT4", "componentType" : "UINT64", "array" : true, "normalized" : true }, "example_fixed_length_normalized_UINT64_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with normalized UINT64 components", "description" : "An example fixed length array property, with type MAT4, with component type UINT64, normalized", "type" : "MAT4", "componentType" : "UINT64", "array" : true, "count" : 5, "normalized" : true }, "example_FLOAT32_MAT4" : { "name" : "Example MAT4 property with FLOAT32 components", "description" : "An example property, with type MAT4, with component type FLOAT32", "type" : "MAT4", "componentType" : "FLOAT32", "array" : false, "normalized" : false }, "example_variable_length_FLOAT32_MAT4_array" : { "name" : "Example variable-length MAT4 array property with FLOAT32 components", "description" : "An example variable length array property, with type MAT4, with component type FLOAT32", "type" : "MAT4", "componentType" : "FLOAT32", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT32_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with FLOAT32 components", "description" : "An example fixed length array property, with type MAT4, with component type FLOAT32", "type" : "MAT4", "componentType" : "FLOAT32", "array" : true, "count" : 5, "normalized" : false }, "example_FLOAT64_MAT4" : { "name" : "Example MAT4 property with FLOAT64 components", "description" : "An example property, with type MAT4, with component type FLOAT64", "type" : "MAT4", "componentType" : "FLOAT64", "array" : false, "normalized" : false }, "example_variable_length_FLOAT64_MAT4_array" : { "name" : "Example variable-length MAT4 array property with FLOAT64 components", "description" : "An example variable length array property, with type MAT4, with component type FLOAT64", "type" : "MAT4", "componentType" : "FLOAT64", "array" : true, "normalized" : false }, "example_fixed_length_FLOAT64_MAT4_array" : { "name" : "Example fixed-length MAT4 array property with FLOAT64 components", "description" : "An example fixed length array property, with type MAT4, with component type FLOAT64", "type" : "MAT4", "componentType" : "FLOAT64", "array" : true, "count" : 5, "normalized" : false } } } }, "enums" : { "exampleEnumType" : { "values" : [ { "name" : "ExampleEnumValueA", "value" : 0 }, { "name" : "ExampleEnumValueB", "value" : 1 }, { "name" : "ExampleEnumValueC", "value" : 2 } ] } } }, "metadata" : { "class" : "exampleClass", "properties" : { "example_STRING" : "An example string", "example_variable_length_STRING_array" : [ "This", "is", "an", "example" ], "example_fixed_length_STRING_array" : [ "This", "is", "an", "example", "string" ], "example_BOOLEAN" : true, "example_variable_length_BOOLEAN_array" : [ true, false, true, false ], "example_fixed_length_BOOLEAN_array" : [ true, false, true, false, true ], "example_ENUM" : "ExampleEnumValueB", "example_variable_length_ENUM_array" : [ "ExampleEnumValueA", "ExampleEnumValueB", "ExampleEnumValueC", "ExampleEnumValueA" ], "example_fixed_length_ENUM_array" : [ "ExampleEnumValueA", "ExampleEnumValueB", "ExampleEnumValueC", "ExampleEnumValueA", "ExampleEnumValueB" ], "example_INT8_SCALAR" : -128, "example_variable_length_INT8_SCALAR_array" : [ -128, -43, 42, 127 ], "example_fixed_length_INT8_SCALAR_array" : [ -128, -64, 0, 63, 127 ], "example_normalized_INT8_SCALAR" : -128, "example_variable_length_normalized_INT8_SCALAR_array" : [ -128, -43, 42, 127 ], "example_fixed_length_normalized_INT8_SCALAR_array" : [ -128, -64, 0, 63, 127 ], "example_UINT8_SCALAR" : 255, "example_variable_length_UINT8_SCALAR_array" : [ 0, 84, 170, 255 ], "example_fixed_length_UINT8_SCALAR_array" : [ 0, 63, 127, 191, 255 ], "example_normalized_UINT8_SCALAR" : 255, "example_variable_length_normalized_UINT8_SCALAR_array" : [ 0, 84, 170, 255 ], "example_fixed_length_normalized_UINT8_SCALAR_array" : [ 0, 63, 127, 191, 255 ], "example_INT16_SCALAR" : -32768, "example_variable_length_INT16_SCALAR_array" : [ -32768, -10923, 10922, 32767 ], "example_fixed_length_INT16_SCALAR_array" : [ -32768, -16384, 0, 16383, 32767 ], "example_normalized_INT16_SCALAR" : -32768, "example_variable_length_normalized_INT16_SCALAR_array" : [ -32768, -10923, 10922, 32767 ], "example_fixed_length_normalized_INT16_SCALAR_array" : [ -32768, -16384, 0, 16383, 32767 ], "example_UINT16_SCALAR" : 65535, "example_variable_length_UINT16_SCALAR_array" : [ 0, 21844, 43690, 65535 ], "example_fixed_length_UINT16_SCALAR_array" : [ 0, 16383, 32767, 49151, 65535 ], "example_normalized_UINT16_SCALAR" : 65535, "example_variable_length_normalized_UINT16_SCALAR_array" : [ 0, 21844, 43690, 65535 ], "example_fixed_length_normalized_UINT16_SCALAR_array" : [ 0, 16383, 32767, 49151, 65535 ], "example_INT32_SCALAR" : -2147483648, "example_variable_length_INT32_SCALAR_array" : [ -2147483648, -715827883, 715827882, 2147483647 ], "example_fixed_length_INT32_SCALAR_array" : [ -2147483648, -1073741824, 0, 1073741823, 2147483647 ], "example_normalized_INT32_SCALAR" : -2147483648, "example_variable_length_normalized_INT32_SCALAR_array" : [ -2147483648, -715827883, 715827882, 2147483647 ], "example_fixed_length_normalized_INT32_SCALAR_array" : [ -2147483648, -1073741824, 0, 1073741823, 2147483647 ], "example_UINT32_SCALAR" : 4294967295, "example_variable_length_UINT32_SCALAR_array" : [ 0, 1431655764, 2863311530, 4294967295 ], "example_fixed_length_UINT32_SCALAR_array" : [ 0, 1073741823, 2147483647, 3221225471, 4294967295 ], "example_normalized_UINT32_SCALAR" : 4294967295, "example_variable_length_normalized_UINT32_SCALAR_array" : [ 0, 1431655764, 2863311530, 4294967295 ], "example_fixed_length_normalized_UINT32_SCALAR_array" : [ 0, 1073741823, 2147483647, 3221225471, 4294967295 ], "example_INT64_SCALAR" : -9223372036854775808, "example_variable_length_INT64_SCALAR_array" : [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], "example_fixed_length_INT64_SCALAR_array" : [ -9223372036854775808, -4611686018427387904, 0, 4611686018427387903, 9223372036854775807 ], "example_normalized_INT64_SCALAR" : -9223372036854775808, "example_variable_length_normalized_INT64_SCALAR_array" : [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], "example_fixed_length_normalized_INT64_SCALAR_array" : [ -9223372036854775808, -4611686018427387904, 0, 4611686018427387903, 9223372036854775807 ], "example_UINT64_SCALAR" : 18446744073709551615, "example_variable_length_UINT64_SCALAR_array" : [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], "example_fixed_length_UINT64_SCALAR_array" : [ 0, 4611686018427387903, 9223372036854775807, 13835058055282163711, 18446744073709551615 ], "example_normalized_UINT64_SCALAR" : 18446744073709551615, "example_variable_length_normalized_UINT64_SCALAR_array" : [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], "example_fixed_length_normalized_UINT64_SCALAR_array" : [ 0, 4611686018427387903, 9223372036854775807, 13835058055282163711, 18446744073709551615 ], "example_FLOAT32_SCALAR" : 1.2, "example_variable_length_FLOAT32_SCALAR_array" : [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], "example_fixed_length_FLOAT32_SCALAR_array" : [ -1.0, -0.5, 0.0, 0.5, 1.0 ], "example_FLOAT64_SCALAR" : 12.34, "example_variable_length_FLOAT64_SCALAR_array" : [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], "example_fixed_length_FLOAT64_SCALAR_array" : [ -1.0, -0.5, 0.0, 0.5, 1.0 ], "example_INT8_VEC2" : [ -128, 127 ], "example_variable_length_INT8_VEC2_array" : [ [ -128, 127 ], [ -128, 127 ], [ -128, 127 ], [ -128, 127 ] ], "example_fixed_length_INT8_VEC2_array" : [ [ -128, 127 ], [ -128, 127 ], [ -128, 127 ], [ -128, 127 ], [ -128, 127 ] ], "example_normalized_INT8_VEC2" : [ -128, 127 ], "example_variable_length_normalized_INT8_VEC2_array" : [ [ -128, 127 ], [ -128, 127 ], [ -128, 127 ], [ -128, 127 ] ], "example_fixed_length_normalized_INT8_VEC2_array" : [ [ -128, 127 ], [ -128, 127 ], [ -128, 127 ], [ -128, 127 ], [ -128, 127 ] ], "example_UINT8_VEC2" : [ 0, 255 ], "example_variable_length_UINT8_VEC2_array" : [ [ 0, 255 ], [ 0, 255 ], [ 0, 255 ], [ 0, 255 ] ], "example_fixed_length_UINT8_VEC2_array" : [ [ 0, 255 ], [ 0, 255 ], [ 0, 255 ], [ 0, 255 ], [ 0, 255 ] ], "example_normalized_UINT8_VEC2" : [ 0, 255 ], "example_variable_length_normalized_UINT8_VEC2_array" : [ [ 0, 255 ], [ 0, 255 ], [ 0, 255 ], [ 0, 255 ] ], "example_fixed_length_normalized_UINT8_VEC2_array" : [ [ 0, 255 ], [ 0, 255 ], [ 0, 255 ], [ 0, 255 ], [ 0, 255 ] ], "example_INT16_VEC2" : [ -32768, 32767 ], "example_variable_length_INT16_VEC2_array" : [ [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ] ], "example_fixed_length_INT16_VEC2_array" : [ [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ] ], "example_normalized_INT16_VEC2" : [ -32768, 32767 ], "example_variable_length_normalized_INT16_VEC2_array" : [ [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ] ], "example_fixed_length_normalized_INT16_VEC2_array" : [ [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ], [ -32768, 32767 ] ], "example_UINT16_VEC2" : [ 0, 65535 ], "example_variable_length_UINT16_VEC2_array" : [ [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ] ], "example_fixed_length_UINT16_VEC2_array" : [ [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ] ], "example_normalized_UINT16_VEC2" : [ 0, 65535 ], "example_variable_length_normalized_UINT16_VEC2_array" : [ [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ] ], "example_fixed_length_normalized_UINT16_VEC2_array" : [ [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ], [ 0, 65535 ] ], "example_INT32_VEC2" : [ -2147483648, 2147483647 ], "example_variable_length_INT32_VEC2_array" : [ [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ] ], "example_fixed_length_INT32_VEC2_array" : [ [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ] ], "example_normalized_INT32_VEC2" : [ -2147483648, 2147483647 ], "example_variable_length_normalized_INT32_VEC2_array" : [ [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ] ], "example_fixed_length_normalized_INT32_VEC2_array" : [ [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ], [ -2147483648, 2147483647 ] ], "example_UINT32_VEC2" : [ 0, 4294967295 ], "example_variable_length_UINT32_VEC2_array" : [ [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ] ], "example_fixed_length_UINT32_VEC2_array" : [ [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ] ], "example_normalized_UINT32_VEC2" : [ 0, 4294967295 ], "example_variable_length_normalized_UINT32_VEC2_array" : [ [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ] ], "example_fixed_length_normalized_UINT32_VEC2_array" : [ [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ], [ 0, 4294967295 ] ], "example_INT64_VEC2" : [ -9223372036854775808, 9223372036854775807 ], "example_variable_length_INT64_VEC2_array" : [ [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ] ], "example_fixed_length_INT64_VEC2_array" : [ [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ] ], "example_normalized_INT64_VEC2" : [ -9223372036854775808, 9223372036854775807 ], "example_variable_length_normalized_INT64_VEC2_array" : [ [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ] ], "example_fixed_length_normalized_INT64_VEC2_array" : [ [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ], [ -9223372036854775808, 9223372036854775807 ] ], "example_UINT64_VEC2" : [ 0, 18446744073709551615 ], "example_variable_length_UINT64_VEC2_array" : [ [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ] ], "example_fixed_length_UINT64_VEC2_array" : [ [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ] ], "example_normalized_UINT64_VEC2" : [ 0, 18446744073709551615 ], "example_variable_length_normalized_UINT64_VEC2_array" : [ [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ] ], "example_fixed_length_normalized_UINT64_VEC2_array" : [ [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ], [ 0, 18446744073709551615 ] ], "example_FLOAT32_VEC2" : [ -1.0, 1.0 ], "example_variable_length_FLOAT32_VEC2_array" : [ [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ] ], "example_fixed_length_FLOAT32_VEC2_array" : [ [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ] ], "example_FLOAT64_VEC2" : [ -1.0, 1.0 ], "example_variable_length_FLOAT64_VEC2_array" : [ [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ] ], "example_fixed_length_FLOAT64_VEC2_array" : [ [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ], [ -1.0, 1.0 ] ], "example_INT8_VEC3" : [ -128, 0, 127 ], "example_variable_length_INT8_VEC3_array" : [ [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ] ], "example_fixed_length_INT8_VEC3_array" : [ [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ] ], "example_normalized_INT8_VEC3" : [ -128, 0, 127 ], "example_variable_length_normalized_INT8_VEC3_array" : [ [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ] ], "example_fixed_length_normalized_INT8_VEC3_array" : [ [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ], [ -128, 0, 127 ] ], "example_UINT8_VEC3" : [ 0, 127, 255 ], "example_variable_length_UINT8_VEC3_array" : [ [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ] ], "example_fixed_length_UINT8_VEC3_array" : [ [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ] ], "example_normalized_UINT8_VEC3" : [ 0, 127, 255 ], "example_variable_length_normalized_UINT8_VEC3_array" : [ [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ] ], "example_fixed_length_normalized_UINT8_VEC3_array" : [ [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ], [ 0, 127, 255 ] ], "example_INT16_VEC3" : [ -32768, 0, 32767 ], "example_variable_length_INT16_VEC3_array" : [ [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ] ], "example_fixed_length_INT16_VEC3_array" : [ [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ] ], "example_normalized_INT16_VEC3" : [ -32768, 0, 32767 ], "example_variable_length_normalized_INT16_VEC3_array" : [ [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ] ], "example_fixed_length_normalized_INT16_VEC3_array" : [ [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ], [ -32768, 0, 32767 ] ], "example_UINT16_VEC3" : [ 0, 32767, 65535 ], "example_variable_length_UINT16_VEC3_array" : [ [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ] ], "example_fixed_length_UINT16_VEC3_array" : [ [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ] ], "example_normalized_UINT16_VEC3" : [ 0, 32767, 65535 ], "example_variable_length_normalized_UINT16_VEC3_array" : [ [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ] ], "example_fixed_length_normalized_UINT16_VEC3_array" : [ [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ], [ 0, 32767, 65535 ] ], "example_INT32_VEC3" : [ -2147483648, 0, 2147483647 ], "example_variable_length_INT32_VEC3_array" : [ [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ] ], "example_fixed_length_INT32_VEC3_array" : [ [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ] ], "example_normalized_INT32_VEC3" : [ -2147483648, 0, 2147483647 ], "example_variable_length_normalized_INT32_VEC3_array" : [ [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ] ], "example_fixed_length_normalized_INT32_VEC3_array" : [ [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ], [ -2147483648, 0, 2147483647 ] ], "example_UINT32_VEC3" : [ 0, 2147483647, 4294967295 ], "example_variable_length_UINT32_VEC3_array" : [ [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ] ], "example_fixed_length_UINT32_VEC3_array" : [ [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ] ], "example_normalized_UINT32_VEC3" : [ 0, 2147483647, 4294967295 ], "example_variable_length_normalized_UINT32_VEC3_array" : [ [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ] ], "example_fixed_length_normalized_UINT32_VEC3_array" : [ [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ], [ 0, 2147483647, 4294967295 ] ], "example_INT64_VEC3" : [ -9223372036854775808, 0, 9223372036854775807 ], "example_variable_length_INT64_VEC3_array" : [ [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ] ], "example_fixed_length_INT64_VEC3_array" : [ [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ] ], "example_normalized_INT64_VEC3" : [ -9223372036854775808, 0, 9223372036854775807 ], "example_variable_length_normalized_INT64_VEC3_array" : [ [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ] ], "example_fixed_length_normalized_INT64_VEC3_array" : [ [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ], [ -9223372036854775808, 0, 9223372036854775807 ] ], "example_UINT64_VEC3" : [ 0, 9223372036854775807, 18446744073709551615 ], "example_variable_length_UINT64_VEC3_array" : [ [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ] ], "example_fixed_length_UINT64_VEC3_array" : [ [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ] ], "example_normalized_UINT64_VEC3" : [ 0, 9223372036854775807, 18446744073709551615 ], "example_variable_length_normalized_UINT64_VEC3_array" : [ [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ] ], "example_fixed_length_normalized_UINT64_VEC3_array" : [ [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ], [ 0, 9223372036854775807, 18446744073709551615 ] ], "example_FLOAT32_VEC3" : [ -1.0, 0.0, 1.0 ], "example_variable_length_FLOAT32_VEC3_array" : [ [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ] ], "example_fixed_length_FLOAT32_VEC3_array" : [ [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ] ], "example_FLOAT64_VEC3" : [ -1.0, 0.0, 1.0 ], "example_variable_length_FLOAT64_VEC3_array" : [ [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ] ], "example_fixed_length_FLOAT64_VEC3_array" : [ [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ], [ -1.0, 0.0, 1.0 ] ], "example_INT8_VEC4" : [ -128, -43, 42, 127 ], "example_variable_length_INT8_VEC4_array" : [ [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ] ], "example_fixed_length_INT8_VEC4_array" : [ [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ] ], "example_normalized_INT8_VEC4" : [ -128, -43, 42, 127 ], "example_variable_length_normalized_INT8_VEC4_array" : [ [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ] ], "example_fixed_length_normalized_INT8_VEC4_array" : [ [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ] ], "example_UINT8_VEC4" : [ 0, 84, 170, 255 ], "example_variable_length_UINT8_VEC4_array" : [ [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ] ], "example_fixed_length_UINT8_VEC4_array" : [ [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ] ], "example_normalized_UINT8_VEC4" : [ 0, 84, 170, 255 ], "example_variable_length_normalized_UINT8_VEC4_array" : [ [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ] ], "example_fixed_length_normalized_UINT8_VEC4_array" : [ [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ] ], "example_INT16_VEC4" : [ -32768, -10923, 10922, 32767 ], "example_variable_length_INT16_VEC4_array" : [ [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ] ], "example_fixed_length_INT16_VEC4_array" : [ [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ] ], "example_normalized_INT16_VEC4" : [ -32768, -10923, 10922, 32767 ], "example_variable_length_normalized_INT16_VEC4_array" : [ [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ] ], "example_fixed_length_normalized_INT16_VEC4_array" : [ [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ] ], "example_UINT16_VEC4" : [ 0, 21844, 43690, 65535 ], "example_variable_length_UINT16_VEC4_array" : [ [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ] ], "example_fixed_length_UINT16_VEC4_array" : [ [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ] ], "example_normalized_UINT16_VEC4" : [ 0, 21844, 43690, 65535 ], "example_variable_length_normalized_UINT16_VEC4_array" : [ [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ] ], "example_fixed_length_normalized_UINT16_VEC4_array" : [ [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ] ], "example_INT32_VEC4" : [ -2147483648, -715827883, 715827882, 2147483647 ], "example_variable_length_INT32_VEC4_array" : [ [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ] ], "example_fixed_length_INT32_VEC4_array" : [ [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ] ], "example_normalized_INT32_VEC4" : [ -2147483648, -715827883, 715827882, 2147483647 ], "example_variable_length_normalized_INT32_VEC4_array" : [ [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ] ], "example_fixed_length_normalized_INT32_VEC4_array" : [ [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ] ], "example_UINT32_VEC4" : [ 0, 1431655764, 2863311530, 4294967295 ], "example_variable_length_UINT32_VEC4_array" : [ [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ] ], "example_fixed_length_UINT32_VEC4_array" : [ [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ] ], "example_normalized_UINT32_VEC4" : [ 0, 1431655764, 2863311530, 4294967295 ], "example_variable_length_normalized_UINT32_VEC4_array" : [ [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ] ], "example_fixed_length_normalized_UINT32_VEC4_array" : [ [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ] ], "example_INT64_VEC4" : [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], "example_variable_length_INT64_VEC4_array" : [ [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ] ], "example_fixed_length_INT64_VEC4_array" : [ [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ] ], "example_normalized_INT64_VEC4" : [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], "example_variable_length_normalized_INT64_VEC4_array" : [ [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ] ], "example_fixed_length_normalized_INT64_VEC4_array" : [ [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ] ], "example_UINT64_VEC4" : [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], "example_variable_length_UINT64_VEC4_array" : [ [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ] ], "example_fixed_length_UINT64_VEC4_array" : [ [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ] ], "example_normalized_UINT64_VEC4" : [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], "example_variable_length_normalized_UINT64_VEC4_array" : [ [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ] ], "example_fixed_length_normalized_UINT64_VEC4_array" : [ [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ] ], "example_FLOAT32_VEC4" : [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], "example_variable_length_FLOAT32_VEC4_array" : [ [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ] ], "example_fixed_length_FLOAT32_VEC4_array" : [ [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ] ], "example_FLOAT64_VEC4" : [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], "example_variable_length_FLOAT64_VEC4_array" : [ [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ] ], "example_fixed_length_FLOAT64_VEC4_array" : [ [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ] ], "example_INT8_MAT2" : [ -128, -43, 42, 127 ], "example_variable_length_INT8_MAT2_array" : [ [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ] ], "example_fixed_length_INT8_MAT2_array" : [ [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ] ], "example_normalized_INT8_MAT2" : [ -128, -43, 42, 127 ], "example_variable_length_normalized_INT8_MAT2_array" : [ [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ] ], "example_fixed_length_normalized_INT8_MAT2_array" : [ [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ], [ -128, -43, 42, 127 ] ], "example_UINT8_MAT2" : [ 0, 84, 170, 255 ], "example_variable_length_UINT8_MAT2_array" : [ [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ] ], "example_fixed_length_UINT8_MAT2_array" : [ [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ] ], "example_normalized_UINT8_MAT2" : [ 0, 84, 170, 255 ], "example_variable_length_normalized_UINT8_MAT2_array" : [ [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ] ], "example_fixed_length_normalized_UINT8_MAT2_array" : [ [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ], [ 0, 84, 170, 255 ] ], "example_INT16_MAT2" : [ -32768, -10923, 10922, 32767 ], "example_variable_length_INT16_MAT2_array" : [ [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ] ], "example_fixed_length_INT16_MAT2_array" : [ [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ] ], "example_normalized_INT16_MAT2" : [ -32768, -10923, 10922, 32767 ], "example_variable_length_normalized_INT16_MAT2_array" : [ [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ] ], "example_fixed_length_normalized_INT16_MAT2_array" : [ [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ], [ -32768, -10923, 10922, 32767 ] ], "example_UINT16_MAT2" : [ 0, 21844, 43690, 65535 ], "example_variable_length_UINT16_MAT2_array" : [ [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ] ], "example_fixed_length_UINT16_MAT2_array" : [ [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ] ], "example_normalized_UINT16_MAT2" : [ 0, 21844, 43690, 65535 ], "example_variable_length_normalized_UINT16_MAT2_array" : [ [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ] ], "example_fixed_length_normalized_UINT16_MAT2_array" : [ [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ], [ 0, 21844, 43690, 65535 ] ], "example_INT32_MAT2" : [ -2147483648, -715827883, 715827882, 2147483647 ], "example_variable_length_INT32_MAT2_array" : [ [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ] ], "example_fixed_length_INT32_MAT2_array" : [ [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ] ], "example_normalized_INT32_MAT2" : [ -2147483648, -715827883, 715827882, 2147483647 ], "example_variable_length_normalized_INT32_MAT2_array" : [ [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ] ], "example_fixed_length_normalized_INT32_MAT2_array" : [ [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ], [ -2147483648, -715827883, 715827882, 2147483647 ] ], "example_UINT32_MAT2" : [ 0, 1431655764, 2863311530, 4294967295 ], "example_variable_length_UINT32_MAT2_array" : [ [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ] ], "example_fixed_length_UINT32_MAT2_array" : [ [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ] ], "example_normalized_UINT32_MAT2" : [ 0, 1431655764, 2863311530, 4294967295 ], "example_variable_length_normalized_UINT32_MAT2_array" : [ [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ] ], "example_fixed_length_normalized_UINT32_MAT2_array" : [ [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ], [ 0, 1431655764, 2863311530, 4294967295 ] ], "example_INT64_MAT2" : [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], "example_variable_length_INT64_MAT2_array" : [ [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ] ], "example_fixed_length_INT64_MAT2_array" : [ [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ] ], "example_normalized_INT64_MAT2" : [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], "example_variable_length_normalized_INT64_MAT2_array" : [ [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ] ], "example_fixed_length_normalized_INT64_MAT2_array" : [ [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ], [ -9223372036854775808, -3074457346233150072, 3074457346233150071, 9223372036854775807 ] ], "example_UINT64_MAT2" : [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], "example_variable_length_UINT64_MAT2_array" : [ [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ] ], "example_fixed_length_UINT64_MAT2_array" : [ [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ] ], "example_normalized_UINT64_MAT2" : [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], "example_variable_length_normalized_UINT64_MAT2_array" : [ [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ] ], "example_fixed_length_normalized_UINT64_MAT2_array" : [ [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ], [ 0, 6148914690621625735, 12297829383087925879, 18446744073709551615 ] ], "example_FLOAT32_MAT2" : [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], "example_variable_length_FLOAT32_MAT2_array" : [ [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ] ], "example_fixed_length_FLOAT32_MAT2_array" : [ [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ] ], "example_FLOAT64_MAT2" : [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], "example_variable_length_FLOAT64_MAT2_array" : [ [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ] ], "example_fixed_length_FLOAT64_MAT2_array" : [ [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ], [ -1.0, -0.3333333334, 0.3333333334, 1.0 ] ], "example_INT8_MAT3" : [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], "example_variable_length_INT8_MAT3_array" : [ [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ] ], "example_fixed_length_INT8_MAT3_array" : [ [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ] ], "example_normalized_INT8_MAT3" : [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], "example_variable_length_normalized_INT8_MAT3_array" : [ [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ] ], "example_fixed_length_normalized_INT8_MAT3_array" : [ [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ], [ -128, -96, -64, -32, 0, 31, 63, 95, 127 ] ], "example_UINT8_MAT3" : [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], "example_variable_length_UINT8_MAT3_array" : [ [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ] ], "example_fixed_length_UINT8_MAT3_array" : [ [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ] ], "example_normalized_UINT8_MAT3" : [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], "example_variable_length_normalized_UINT8_MAT3_array" : [ [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ] ], "example_fixed_length_normalized_UINT8_MAT3_array" : [ [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ], [ 0, 31, 63, 95, 127, 159, 191, 223, 255 ] ], "example_INT16_MAT3" : [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], "example_variable_length_INT16_MAT3_array" : [ [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ] ], "example_fixed_length_INT16_MAT3_array" : [ [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ] ], "example_normalized_INT16_MAT3" : [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], "example_variable_length_normalized_INT16_MAT3_array" : [ [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ] ], "example_fixed_length_normalized_INT16_MAT3_array" : [ [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ], [ -32768, -24576, -16384, -8192, 0, 8191, 16383, 24575, 32767 ] ], "example_UINT16_MAT3" : [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], "example_variable_length_UINT16_MAT3_array" : [ [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ] ], "example_fixed_length_UINT16_MAT3_array" : [ [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ] ], "example_normalized_UINT16_MAT3" : [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], "example_variable_length_normalized_UINT16_MAT3_array" : [ [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ] ], "example_fixed_length_normalized_UINT16_MAT3_array" : [ [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ], [ 0, 8191, 16383, 24575, 32767, 40959, 49151, 57343, 65535 ] ], "example_INT32_MAT3" : [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], "example_variable_length_INT32_MAT3_array" : [ [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ] ], "example_fixed_length_INT32_MAT3_array" : [ [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ] ], "example_normalized_INT32_MAT3" : [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], "example_variable_length_normalized_INT32_MAT3_array" : [ [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ] ], "example_fixed_length_normalized_INT32_MAT3_array" : [ [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ], [ -2147483648, -1610612736, -1073741824, -536870912, 0, 536870911, 1073741823, 1610612735, 2147483647 ] ], "example_UINT32_MAT3" : [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], "example_variable_length_UINT32_MAT3_array" : [ [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ] ], "example_fixed_length_UINT32_MAT3_array" : [ [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ] ], "example_normalized_UINT32_MAT3" : [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], "example_variable_length_normalized_UINT32_MAT3_array" : [ [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ] ], "example_fixed_length_normalized_UINT32_MAT3_array" : [ [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ], [ 0, 536870911, 1073741823, 1610612735, 2147483647, 2684354559, 3221225471, 3758096383, 4294967295 ] ], "example_INT64_MAT3" : [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], "example_variable_length_INT64_MAT3_array" : [ [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ] ], "example_fixed_length_INT64_MAT3_array" : [ [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ] ], "example_normalized_INT64_MAT3" : [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], "example_variable_length_normalized_INT64_MAT3_array" : [ [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ] ], "example_fixed_length_normalized_INT64_MAT3_array" : [ [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ], [ -9223372036854775808, -6917529027641081856, -4611686018427387904, -2305843009213693952, 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807 ] ], "example_UINT64_MAT3" : [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], "example_variable_length_UINT64_MAT3_array" : [ [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ] ], "example_fixed_length_UINT64_MAT3_array" : [ [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ] ], "example_normalized_UINT64_MAT3" : [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], "example_variable_length_normalized_UINT64_MAT3_array" : [ [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ] ], "example_fixed_length_normalized_UINT64_MAT3_array" : [ [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ], [ 0, 2305843009213693951, 4611686018427387903, 6917529027641081855, 9223372036854775807, 11529215046068469759, 13835058055282163711, 16140901064495857663, 18446744073709551615 ] ], "example_FLOAT32_MAT3" : [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], "example_variable_length_FLOAT32_MAT3_array" : [ [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ] ], "example_fixed_length_FLOAT32_MAT3_array" : [ [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ] ], "example_FLOAT64_MAT3" : [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], "example_variable_length_FLOAT64_MAT3_array" : [ [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ] ], "example_fixed_length_FLOAT64_MAT3_array" : [ [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ], [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0 ] ], "example_INT8_MAT4" : [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], "example_variable_length_INT8_MAT4_array" : [ [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ] ], "example_fixed_length_INT8_MAT4_array" : [ [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ] ], "example_normalized_INT8_MAT4" : [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], "example_variable_length_normalized_INT8_MAT4_array" : [ [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ] ], "example_fixed_length_normalized_INT8_MAT4_array" : [ [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ], [ -128, -110, -94, -77, -59, -43, -26, -8, 7, 25, 42, 58, 76, 93, 109, 127 ] ], "example_UINT8_MAT4" : [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], "example_variable_length_UINT8_MAT4_array" : [ [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ] ], "example_fixed_length_UINT8_MAT4_array" : [ [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ] ], "example_normalized_UINT8_MAT4" : [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], "example_variable_length_normalized_UINT8_MAT4_array" : [ [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ] ], "example_fixed_length_normalized_UINT8_MAT4_array" : [ [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ], [ 0, 17, 33, 51, 68, 84, 102, 119, 135, 153, 170, 186, 204, 221, 237, 255 ] ], "example_INT16_MAT4" : [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], "example_variable_length_INT16_MAT4_array" : [ [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ] ], "example_fixed_length_INT16_MAT4_array" : [ [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ] ], "example_normalized_INT16_MAT4" : [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], "example_variable_length_normalized_INT16_MAT4_array" : [ [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ] ], "example_fixed_length_normalized_INT16_MAT4_array" : [ [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ], [ -32768, -28398, -24030, -19661, -15291, -10923, -6554, -2184, 2183, 6553, 10922, 15290, 19660, 24029, 28397, 32767 ] ], "example_UINT16_MAT4" : [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], "example_variable_length_UINT16_MAT4_array" : [ [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ] ], "example_fixed_length_UINT16_MAT4_array" : [ [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ] ], "example_normalized_UINT16_MAT4" : [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], "example_variable_length_normalized_UINT16_MAT4_array" : [ [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ] ], "example_fixed_length_normalized_UINT16_MAT4_array" : [ [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ], [ 0, 4369, 8737, 13107, 17476, 21844, 26214, 30583, 34951, 39321, 43690, 48058, 52428, 56797, 61165, 65535 ] ], "example_INT32_MAT4" : [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], "example_variable_length_INT32_MAT4_array" : [ [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ] ], "example_fixed_length_INT32_MAT4_array" : [ [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ] ], "example_normalized_INT32_MAT4" : [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], "example_variable_length_normalized_INT32_MAT4_array" : [ [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ] ], "example_fixed_length_normalized_INT32_MAT4_array" : [ [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ], [ -2147483648, -1861152494, -1574821342, -1288490189, -1002159035, -715827883, -429496730, -143165576, 143165575, 429496729, 715827882, 1002159034, 1288490188, 1574821341, 1861152493, 2147483647 ] ], "example_UINT32_MAT4" : [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], "example_variable_length_UINT32_MAT4_array" : [ [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ] ], "example_fixed_length_UINT32_MAT4_array" : [ [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ] ], "example_normalized_UINT32_MAT4" : [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], "example_variable_length_normalized_UINT32_MAT4_array" : [ [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ] ], "example_fixed_length_normalized_UINT32_MAT4_array" : [ [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ], [ 0, 286331153, 572662305, 858993459, 1145324612, 1431655764, 1717986918, 2004318071, 2290649223, 2576980377, 2863311530, 3149642682, 3435973836, 3722304989, 4008636141, 4294967295 ] ], "example_INT64_MAT4" : [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], "example_variable_length_INT64_MAT4_array" : [ [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ] ], "example_fixed_length_INT64_MAT4_array" : [ [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ] ], "example_normalized_INT64_MAT4" : [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], "example_variable_length_normalized_INT64_MAT4_array" : [ [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ] ], "example_fixed_length_normalized_INT64_MAT4_array" : [ [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ], [ -9223372036854775808, -7993589097992580897, -6763806160975060395, -5534023222112865485, -4304240283250670574, -3074457346233150072, -1844674407370955162, -614891468508760251, 614891468508760250, 1844674407370955161, 3074457346233150071, 4304240283250670573, 5534023222112865484, 6763806160975060394, 7993589097992580896, 9223372036854775807 ] ], "example_UINT64_MAT4" : [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], "example_variable_length_UINT64_MAT4_array" : [ [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ] ], "example_fixed_length_UINT64_MAT4_array" : [ [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ] ], "example_normalized_UINT64_MAT4" : [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], "example_variable_length_normalized_UINT64_MAT4_array" : [ [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ] ], "example_fixed_length_normalized_UINT64_MAT4_array" : [ [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ], [ 0, 1229782938862194910, 2459565875879715412, 3689348814741910323, 4919131753604105233, 6148914690621625735, 7378697629483820646, 8608480568346015556, 9838263505363536058, 11068046444225730969, 12297829383087925879, 13527612320105446381, 14757395258967641292, 15987178197829836202, 17216961134847356704, 18446744073709551615 ] ], "example_FLOAT32_MAT4" : [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], "example_variable_length_FLOAT32_MAT4_array" : [ [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ] ], "example_fixed_length_FLOAT32_MAT4_array" : [ [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ] ], "example_FLOAT64_MAT4" : [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], "example_variable_length_FLOAT64_MAT4_array" : [ [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ] ], "example_fixed_length_FLOAT64_MAT4_array" : [ [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ], [ -1.0, -0.8666666666, -0.7333333334, -0.6, -0.4666666666, -0.3333333334, -0.2, -0.0666666666, 0.0666666666, 0.2, 0.3333333334, 0.4666666666, 0.6, 0.7333333334, 0.8666666666, 1.0 ] ] } }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/buffers/bufferViewsElementBufferInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": "NOT_A_NUMBER", "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementBufferInvalidValueA.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 123.456, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementBufferInvalidValueB.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": -1, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementBufferInvalidValueC.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 12345, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementByteLengthInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": "NOT_A_NUMBER" }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementByteLengthInvalidValueA.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 123.456 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementByteLengthInvalidValueB.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": -1 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementByteOffsetInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": "NOT_A_NUMBER", "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementByteOffsetInvalidValueA.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 123.456, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementByteOffsetInvalidValueB.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": -1, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementExceedsBufferLength.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 123, "byteLength": 234 } ] } ================================================ FILE: specs/data/buffers/bufferViewsElementInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ "NOT_AN_OBJECT", { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/bufferViewsInvalidLength.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [] } ================================================ FILE: specs/data/buffers/bufferViewsInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": "NOT_AN_OBJECT" } ================================================ FILE: specs/data/buffers/buffersElementByteLengthInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": "NOT_A_NUMBER" }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersElementByteLengthInvalidValueA.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 123.456 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersElementByteLengthInvalidValueB.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": -1 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersElementByteLengthMissing.json ================================================ { "buffers": [{ "uri": "validBuffer.bin" }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersElementInvalidType.json ================================================ { "buffers": [ "NOT_AN_OBJECT" ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersElementNameInvalidLength.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "name":"", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersElementNameInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "name": 123.346, "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersElementUriInvalidType.json ================================================ { "buffers": [{ "uri": 123.346, "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersElementUriMissing.json ================================================ { "buffers": [{ "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersInvalidLength.json ================================================ { "buffers": [], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/buffers/buffersInvalidType.json ================================================ { "buffers": "NOT_AN_OBJECT", "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ] } ================================================ FILE: specs/data/extensions/boundingVolumeS2/s2AndInvalidBox.json ================================================ { "asset": { "version": "1.1" }, "extensionsUsed": [ "3DTILES_bounding_volume_S2" ], "extensionsRequired": [ "3DTILES_bounding_volume_S2" ], "geometricError": 2.0, "root": { "refine": "ADD", "geometricError": 1.0, "boundingVolume": { "box": [ 1, 2, 3], "extensions": { "3DTILES_bounding_volume_S2": { "token": "1", "minimumHeight": 0, "maximumHeight": 10000 } } } } } ================================================ FILE: specs/data/extensions/boundingVolumeS2/s2MaximumHeightInvalidType.json ================================================ { "asset": { "version": "1.1" }, "extensionsUsed": [ "3DTILES_bounding_volume_S2" ], "extensionsRequired": [ "3DTILES_bounding_volume_S2" ], "geometricError": 2.0, "root": { "refine": "ADD", "geometricError": 1.0, "boundingVolume": { "extensions": { "3DTILES_bounding_volume_S2": { "token": "1", "minimumHeight": 0, "maximumHeight": "NOT_A_NUMBER" } } } } } ================================================ FILE: specs/data/extensions/boundingVolumeS2/s2MinimumHeightGreaterThanMaximumHeight.json ================================================ { "asset": { "version": "1.1" }, "extensionsUsed": [ "3DTILES_bounding_volume_S2" ], "extensionsRequired": [ "3DTILES_bounding_volume_S2" ], "geometricError": 2.0, "root": { "refine": "ADD", "geometricError": 1.0, "boundingVolume": { "extensions": { "3DTILES_bounding_volume_S2": { "token": "1", "minimumHeight": 100, "maximumHeight": 99 } } } } } ================================================ FILE: specs/data/extensions/boundingVolumeS2/s2MinimumHeightInvalidType.json ================================================ { "asset": { "version": "1.1" }, "extensionsUsed": [ "3DTILES_bounding_volume_S2" ], "extensionsRequired": [ "3DTILES_bounding_volume_S2" ], "geometricError": 2.0, "root": { "refine": "ADD", "geometricError": 1.0, "boundingVolume": { "extensions": { "3DTILES_bounding_volume_S2": { "token": "1", "minimumHeight": "NOT_A_NUMBER", "maximumHeight": 10000 } } } } } ================================================ FILE: specs/data/extensions/boundingVolumeS2/s2TokenInvalidType.json ================================================ { "asset": { "version": "1.1" }, "extensionsUsed": [ "3DTILES_bounding_volume_S2" ], "extensionsRequired": [ "3DTILES_bounding_volume_S2" ], "geometricError": 2.0, "root": { "refine": "ADD", "geometricError": 1.0, "boundingVolume": { "extensions": { "3DTILES_bounding_volume_S2": { "token": 12345, "minimumHeight": 0, "maximumHeight": 10000 } } } } } ================================================ FILE: specs/data/extensions/boundingVolumeS2/s2TokenInvalidValue.json ================================================ { "asset": { "version": "1.1" }, "extensionsUsed": [ "3DTILES_bounding_volume_S2" ], "extensionsRequired": [ "3DTILES_bounding_volume_S2" ], "geometricError": 2.0, "root": { "refine": "ADD", "geometricError": 1.0, "boundingVolume": { "extensions": { "3DTILES_bounding_volume_S2": { "token": "NOT_A_VALID_TOKEN", "minimumHeight": 0, "maximumHeight": 10000 } } } } } ================================================ FILE: specs/data/extensions/boundingVolumeS2/s2TokenMissing.json ================================================ { "asset": { "version": "1.1" }, "extensionsUsed": [ "3DTILES_bounding_volume_S2" ], "extensionsRequired": [ "3DTILES_bounding_volume_S2" ], "geometricError": 2.0, "root": { "refine": "ADD", "geometricError": 1.0, "boundingVolume": { "extensions": { "3DTILES_bounding_volume_S2": { "minimumHeight": 0, "maximumHeight": 10000 } } } } } ================================================ FILE: specs/data/extensions/boundingVolumeS2/validTilesetWithS2.json ================================================ { "asset": { "version": "1.1" }, "extensionsUsed": [ "3DTILES_bounding_volume_S2" ], "extensionsRequired": [ "3DTILES_bounding_volume_S2" ], "geometricError": 2.0, "root": { "refine": "ADD", "geometricError": 1.0, "boundingVolume": { "extensions": { "3DTILES_bounding_volume_S2": { "token": "1", "minimumHeight": 0, "maximumHeight": 10000 } } } } } ================================================ FILE: specs/data/extensions/contentGltf/contentGltfExtensionRequiredButNotUsed.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsRequired": [ "KHR_materials_unlit" ] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/contentGltfExtensionsRequiredDuplicateElement.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsUsed": [ "KHR_materials_unlit" ], "extensionsRequired": [ "KHR_materials_unlit", "KHR_materials_unlit" ] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/contentGltfExtensionsRequiredInvalidArrayLength.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsRequired": [] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/contentGltfExtensionsRequiredInvalidElementType.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsUsed": [ "KHR_materials_unlit" ], "extensionsRequired": [ "KHR_materials_unlit", 1234 ] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/contentGltfExtensionsRequiredInvalidType.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsRequired": "NOT_AN_ARRAY" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/contentGltfExtensionsUsedDuplicateElement.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsUsed": [ "KHR_materials_unlit", "KHR_materials_unlit" ] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/contentGltfExtensionsUsedInvalidArrayLength.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsUsed": [] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/contentGltfExtensionsUsedInvalidElementType.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsUsed": [ "KHR_materials_unlit", 1234 ] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/contentGltfExtensionsUsedInvalidType.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsUsed": "NOT_AN_ARRAY" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/tileset_1_0_withContentGltfRequiredButNotUsed.json ================================================ { "extensionsRequired": ["3DTILES_content_gltf"], "asset" : { "version" : "1.0" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/tileset_1_0_withContentGltfUsedButNotFound.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensionsRequired": ["3DTILES_content_gltf"], "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/b3dm/valid.b3dm" } } } ================================================ FILE: specs/data/extensions/contentGltf/tileset_1_0_withContentGltfUsedButNotRequired.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "asset" : { "version" : "1.0" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/tileset_1_1_withContentGltfUsedButNotFound.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/validTileset_1_0_withExtensionObject.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensionsRequired": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsUsed": [ "KHR_materials_unlit" ] } }, "asset" : { "version" : "1.0" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/b3dm/valid.b3dm" } } } ================================================ FILE: specs/data/extensions/contentGltf/validTileset_1_0_withGltf.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensionsRequired": ["3DTILES_content_gltf"], "asset" : { "version" : "1.0" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/validTileset_1_1_withContentGltfUsedAndFound.json ================================================ { "extensionsUsed": ["3DTILES_content_gltf"], "extensions": { "3DTILES_content_gltf": { "extensionsUsed": [ "KHR_materials_unlit" ] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/contentGltf/validTileset_1_1_withGltf.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "../../tilesets/tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/extensions/gpm/anchorPointMetadataContentIndexInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "anchorPointMetadata": { "placementType": "SeparateContent", "contentIndex": "NOT_A_NUMBER" }, "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/anchorPointMetadataContentIndexInvalidValue.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "contents": [ { "uri": "validTileset.json" }, { "uri": "validTileset.json" } ] }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "anchorPointMetadata": { "placementType": "SeparateContent", "contentIndex": 123 }, "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/anchorPointMetadataContentIndexMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "anchorPointMetadata": { "placementType": "SeparateContent" }, "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/anchorPointMetadataPlacementTypeInvalidValue.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "anchorPointMetadata": { "placementType": "INVALID_VALUE", "contentIndex": 1 }, "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/anchorPointMetadataPlacementTypeMeshContentWithContentIndex.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "anchorPointMetadata": { "placementType": "MeshContent", "contentIndex": 1 }, "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/anchorPointMetadataPlacementTypeMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "anchorPointMetadata": { "contentIndex": 1 }, "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionRecordCollectionIdInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": 12345, "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionRecordCollectionIdMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionRecordPlatformIdInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": 12345, "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionRecordPlatformIdMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionRecordSensorRecordsElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ "NOT_AN_OBJECT", { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionRecordSensorRecordsInvalidLength.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionRecordSensorRecordsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": "NOT_AN_OBJECT" } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionRecordSensorRecordsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id" } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionUnitRecordCollectionUnitIdInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": 12345, "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionUnitRecordCollectionUnitIdMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionUnitRecordExtentInformationInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": "NOT_AN_OBJECT" } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionUnitRecordExtentInformationMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0 } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionUnitRecordPointSourceIdInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": "NOT_A_NUMBER", "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionUnitRecordPointSourceIdInvalidValue.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": -12345, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionUnitRecordPointSourceIdMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionUnitRecordReferenceDateTimeInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": 12345, "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/collectionUnitRecordReferenceDateTimeMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupGroupFlagsElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ "NOT_A_BOOLEAN", true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupGroupFlagsInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupGroupFlagsInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupGroupFlagsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupGroupsGroupFlagsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": "NOT_AN_OBJECT", "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupGroupsParamsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": "NOT_AN_OBJECT" } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupGroupsParamsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupParamsElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ "NOT_AN_OBJECT", { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupParamsInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupParamsInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupRotationThetasInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": "NOT_AN_OBJECT", "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/correlationGroupRotationThetasMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/covarUpperTriangleElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, "NOT_A_NUMBER", 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/covarUpperTriangleInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/covarUpperTriangleInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534, 0.1, 0.2 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ "NOT_AN_OBJECT", [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": "NOT_AN_OBJECT", "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrLengthsElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, "NOT_A_NUMBER", 1.0 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrLengthsInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrLengthsInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178, 1.0 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrLengthsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": "NOT_AN_OBJECT" }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationLsrLengthsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationOriginInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": "NOT_AN_OBJECT", "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/extentInformationOriginMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/idInformationDatasetIdInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": 12345, "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/idInformationDatasetIdMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/idInformationReferenceDateTimeInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": 12345 }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/idInformationReferenceDateTimeMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsDampeningParamInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": "NOT_A_NUMBER" }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsDampeningParamMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsInterpNumPostsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": "NOT_A_NUMBER", "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsInterpNumPostsInvalidValueA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 1.2, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsInterpNumPostsInvalidValueB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 0, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsInterpNumPostsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsInterpolationModeInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": 12345, "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsInterpolationModeInvalidValue.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "INVALID_VALUE", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsInterpolationModeMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsInterpolationModeNearestNeighborWithDampeningParam.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "nearestNeighbor", "dampeningParam": 1.0 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/interpolationParamsInterpolationModeNearestNeighborWithInterpNumPoints.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "nearestNeighbor", "interpNumPosts": 2 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/lsrAxisUnitVectorsNotOrthogonalA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [0.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/lsrAxisUnitVectorsNotOrthogonalB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 1.0, 0.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/lsrAxisUnitVectorsNotOrthogonalC.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordCollectionRecordListElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ "NOT_AN_OBJECT" ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordCollectionRecordListInvalidLength.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordCollectionRecordListInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": "NOT_AN_OBJECT" }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordDatasetExtentInformationInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": "NOT_AN_OBJECT", "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordIdInformationInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": "NOT_AN_OBJECT", "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordIdInformationMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordImplementationInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": 12345, "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordImplementationMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordModelCoordSystemInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": "NOT_AN_OBJECT", "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordModelCoordSystemMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordVersionInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": 12345, "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/masterRecordVersionMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemCrsEcefInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": "NOT_AN_OBJECT" }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemCrsEcefMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF" }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefCrsEcefInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": "NOT_AN_OBJECT" }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefCrsEcefMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF" }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefWithAxisUnitVectors.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 }, "axisUnitVectors": [ [ 1.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], [ 0.0, 0.0, 1.0 ] ] }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefWithCrsHorizontalUtm.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 }, "crsHorizontalUtm": { "id": 32601 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefWithCrsVertical.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefWithOrigin.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 }, "origin": { "coordinates": [ 0.1, 0.2, 0.3 ], "crsEcef": { "id": 9753 } } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": 12345, "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeInvalidValue.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "INVALID_VALUE", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrAxisUnitVectorsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "LSR", "origin": { "coordinates": [ 0.1, 0.2, 0.3 ], "crsEcef": { "id": 9753 } }, "axisUnitVectors": "NOT_AN_OBJECT" }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrAxisUnitVectorsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "LSR", "origin": { "coordinates": [ 0.1, 0.2, 0.3 ], "crsEcef": { "id": 9753 } } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrOriginInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "LSR", "origin": "NOT_AN_OBJECT", "axisUnitVectors": [ [ 1.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], [ 0.0, 0.0, 1.0 ] ] }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrOriginMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "LSR", "axisUnitVectors": [ [ 1.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], [ 0.0, 0.0, 1.0 ] ] }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrWithCrsEcef.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "LSR", "origin": { "coordinates": [ 0.1, 0.2, 0.3 ], "crsEcef": { "id": 9753 } }, "axisUnitVectors": [ [ 1.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], [ 0.0, 0.0, 1.0 ] ], "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrWithCrsHorizontalUtm.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "LSR", "origin": { "coordinates": [ 0.1, 0.2, 0.3 ], "crsEcef": { "id": 9753 } }, "axisUnitVectors": [ [ 1.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], [ 0.0, 0.0, 1.0 ] ], "crsHorizontalUtm": { "id": 32601 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrWithCrsVertical.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "LSR", "origin": { "coordinates": [ 0.1, 0.2, 0.3 ], "crsEcef": { "id": 9753 } }, "axisUnitVectors": [ [ 1.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], [ 0.0, 0.0, 1.0 ] ], "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmCrsHorizontalUtmInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": "NOT_AN_OBJECT", "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmCrsHorizontalUtmMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmCrsVerticalInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": "NOT_AN_OBJECT" }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmCrsVerticalMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmWithAxisUnitVectors.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 }, "axisUnitVectors": [ [ 1.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], [ 0.0, 0.0, 1.0 ] ] }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmWithCrsEcef.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 }, "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmWithOrigin.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 }, "origin": { "coordinates": [ 0.1, 0.2, 0.3 ], "crsEcef": { "id": 9753 } } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmAnchorPointMetadataInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "anchorPointMetadata": "NOT_AN_OBJECT", "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmInterTileCorrelationGroupsElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ "NOT_AN_OBJECT", { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] }, { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmInterTileCorrelationGroupsInvalidLength.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] }, { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] }, { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] }, { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmInterTileCorrelationGroupsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": "NOT_AN_OBJECT", "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmInterTileCorrelationGroupsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmInterpolationParamsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": "NOT_AN_OBJECT", "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmInterpolationParamsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": "NOT_AN_OBJECT" } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmMasterRecordInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": "NOT_AN_OBJECT", "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmMasterRecordMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmPpeManifestInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": "NOT_AN_OBJECT" } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmThreeDimConformalParamsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": "NOT_AN_OBJECT" } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmUnmodeledErrorRecordInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": "NOT_AN_OBJECT", "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ngaGpmUnmodeledErrorRecordMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ] } } } ================================================ FILE: specs/data/extensions/gpm/organizationSystemIdPairOrganizationInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": 12345, "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/organizationSystemIdPairOrganizationMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/organizationSystemIdPairSystemIdInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": 12345 }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/organizationSystemIdPairSystemIdMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/point3dElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 0.1, 0.2, "NOT_A_NUMBER" ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/point3dInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 0.1, 0.2 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/point3dInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 0.1, 0.2, 0.3, 0.4 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/ppeManifestElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ "NOT_AN_OBJECT", { "source": "SIGZ" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ppeManifestInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [] } } } ================================================ FILE: specs/data/extensions/gpm/ppeManifestInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "ECEF", "crsEcef": { "id": 7662 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGZ" }, { "source": "SIGZ" }, { "source": "SIGZ" }, { "source": "SIGZ" }, { "source": "SIGZ" }, { "source": "SIGZ" }, { "source": "SIGZ" } ] } } } ================================================ FILE: specs/data/extensions/gpm/ppeMetadataMaxInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "max": "NOT_A_NUMBER", "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/ppeMetadataMinInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "min": "NOT_A_NUMBER", "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/ppeMetadataSourceInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": 12345 } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/ppeMetadataSourceMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/ppeMetadataSourceValuesNotUnique.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceDateTimeNotIso8601A.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "INVALID_VALUE" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceDateTimeNotIso8601B.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T99:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceDateTimeNotIso8601C.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-32" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceDateTimeNotIso8601D.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29, 11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemDefinitionMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System" } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemDescriptionInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1, "description": 12345 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemEpochInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": "NOT_A_NUMBER" } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemEpochMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" } } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemNameInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": 12345, "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemNameMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemOrgWithIdInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": "NOT_AN_OBJECT", "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemOrgWithIdMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemWithDefinitionAndEpoch.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "epoch": 1, "definition": "Example WKT definition" } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/referenceSystemWithDefinitionAndOrgWithId.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "definition": "Example WKT definition" } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/rotationThetasElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, "NOT_A_NUMBER", 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/rotationThetasInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/rotationThetasInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [-0.0743933049314506, 0.4697008438610212, 0.8796855992100932], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ "NOT_AN_OBJECT", { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsInvalidLength.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": "NOT_AN_OBJECT" } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode" } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordSensorIdInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": 12345, "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordSensorIdMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordSensorModeInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": 12345, "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordSensorModeMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordSensorTypeInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": 12345, "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordSensorTypeMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordsSensorModeMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordsSensorTypeInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": 12345, "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/sensorRecordsSensorTypeMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfAInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": "NOT_A_NUMBER", "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfAInvalidValueA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 0.0, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfAInvalidValueB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1.1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfAMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfAlphaInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": "NOT_A_NUMBER", "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfAlphaInvalidValueA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": -0.1, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfAlphaInvalidValueB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 1.0, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfAlphaMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfBetaInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": "NOT_A_NUMBER", "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfBetaInvalidValueA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": -0.1, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfBetaInvalidValueB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 10.1, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfBetaMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfTInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": "NOT_A_NUMBER" }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfTInvalidValue.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 0.0 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/spdcfTMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsCovarianceElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, "NOT_A_NUMBER", 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsCovarianceInvalidLengthFor4A.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsCovarianceInvalidLengthFor4B.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsCovarianceInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": "NOT_AN_OBJECT" } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsCovarianceMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsFlagsElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, "NOT_A_BOOLEAN", true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsFlagsInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsFlagsInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true, false ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsFlagsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": "NOT_AN_OBJECT", "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsFlagsInvalidValues.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ false, false, false, false, false, false, false ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [], "covariance": [] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsFlagsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsNormalizingScaleFactorInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": "NOT_A_NUMBER", "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsNormalizingScaleFactorMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsParametersElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, "NOT_A_NUMBER", 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsParametersInvalidLengthFor4A.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsParametersInvalidLengthFor4B.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3, 4 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsParametersInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": "NOT_AN_OBJECT", "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsParametersMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsRecenteringElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, "NOT_A_NUMBER", 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsRecenteringInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsRecenteringInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4, 4.5 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsRecenteringInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": "NOT_AN_OBJECT", "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/threeDimConformalParamsRecenteringMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unitVectorInvalidElementValueA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [0.1, 1.1, 0.3], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/unitVectorInvalidElementValueB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [0.1, -1.1, 0.3], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/unitVectorInvalidLength.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [ 0.1, 0.2 ], [0.9868514414437406, 0.16160517449656873, -0.0028284441562802665], [-0.14303538712009904, 0.8682099573522005, -0.47513403160149828] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/unitVectorNotUnitLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [0.99, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/unitVectorNotUnitLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "extensionsUsed": ["NGA_gpm"], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [912996.5952063048, -5541794.593278977, 3012483.770173006], "lsrAxisUnitVectors": [ [1.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100932 ], [ 0.9868514414437406, 0.16160517449656873, -0.0028284441562802665 ], [ -0.14303538712009904, 0.8682099573522005, -0.47513403160149828 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [0.0, 0.0, 0.0], "corrParams": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ], "posts": [ { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250.0 }, "interTileCorrelationGroups": [ { "groupFlags": [true, true, true], "rotationThetas": [0.0, 0.0, 0.0], "params": [ { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 }, { "A": 1.0, "alpha": 0.99, "beta": 0.0, "T": 10000.0 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [true, false, true, false, true, false, true], "recentering": [1.2, 2.3, 3.4], "normalizingScaleFactor": 1.2, "parameters": [0, 1, 2, 3], "covariance": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorCorrParamsInvalidElementType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ "NOT_AN_OBJECT", { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorCorrParamsInvalidLengthA.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorCorrParamsInvalidLengthB.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorCorrParamsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": "NOT_AN_OBJECT", "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorCorrParamsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorCorrRotationThetasInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": "NOT_AN_OBJECT", "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorCorrRotationThetasMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorPostCovarianceInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": "NOT_AN_OBJECT" } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorPostCovarianceMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorPostPositionInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": "NOT_AN_OBJECT", "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorPostPositionMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorPostsElementInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ "NOT_AN_OBJECT", { "position": [12.34, 23.45, 34.56], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorPostsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": "NOT_AN_OBJECT" }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorPostsMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": "unmodeled_error", "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorUniqueIdInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "uniqueId": 12345, "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/unmodeledErrorUniqueIdMissing.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2, "root": { "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5 ] }, "geometricError": 1 }, "extensionsUsed": [ "NGA_gpm" ], "extensions": { "NGA_gpm": { "masterRecord": { "version": "1.2i", "implementation": "Example", "modelCoordSystem": { "mcsType": "UTM", "crsHorizontalUtm": { "id": 32601 }, "crsVertical": { "name": "Example Reference System", "orgWithId": { "organization": "EPSG", "systemId": "Example System ID" }, "epoch": 1 } }, "idInformation": { "datasetId": "exportid", "referenceDateTime": "2024-04-29T11:21:49" }, "datasetExtentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] }, "collectionRecordList": [ { "collectionId": "collection id", "platformId": "platform id", "sensorRecords": [ { "sensorId": "sensorid", "sensorType": "sensortype", "sensorMode": "sensormode", "collectionUnitRecords": [ { "referenceDateTime": "2024-04-29T11:21:49", "collectionUnitId": "cuid", "pointSourceId": 0, "extentInformation": { "origin": [ 912996.5952063048, -5541794.593278977, 3012483.770173006 ], "lsrAxisUnitVectors": [ [ -0.0743933049314506, 0.4697008438610212, 0.8796855992100931 ], [ 0.9868514414437406, 0.16160517449656872, -0.0028284441562802663 ], [ -0.14303538712009903, 0.8682099573522005, -0.47513403160149825 ] ], "lsrLengths": [ 5984.896982990946, 6337.485178905554, 99.99999999975178 ] } } ] } ] } ] }, "unmodeledErrorRecord": { "corrRotationThetas": [ 0, 0, 0 ], "corrParams": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ], "posts": [ { "position": [ 12.34, 23.45, 34.56 ], "covariance": [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] }, "interpolationParams": { "interpolationMode": "IDW", "interpNumPosts": 6, "dampeningParam": 250 }, "interTileCorrelationGroups": [ { "groupFlags": [ true, true, true ], "rotationThetas": [ 0, 0, 0 ], "params": [ { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 }, { "A": 1, "alpha": 0.99, "beta": 0, "T": 10000 } ] } ], "ppeManifest": [ { "source": "SIGZ" }, { "source": "SIGR" } ], "threeDimConformalParams": { "flags": [ true, false, true, false, true, false, true ], "recentering": [ 1.2, 2.3, 3.4 ], "normalizingScaleFactor": 1.2, "parameters": [ 0, 1, 2, 3 ], "covariance": [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ] } } } } ================================================ FILE: specs/data/extensions/gpm/validTileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/bareGeometryTileset.json ================================================ { "extras": { "info": { "note": "This tileset is INVALID because it references a bare geometry GeoJSON file (bare_geometry.geojson) which contains only a geometry object instead of a Feature or FeatureCollection as required by the GeoJSON specification." } }, "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset": { "version": "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": {} } }, "geometricError": 2.0, "root": { "content": { "uri": "bare_geometry.geojson" }, "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/bare_geometry.geojson ================================================ { "type": "Polygon", "coordinates": [[[0.0, 0.0], [0.001, 0.0], [0.001, 0.001], [0.0, 0.001], [0.0, 0.0]]] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/content_schema.json ================================================ { "name": "Test Content Properties Schema", "semantic": "test_content_data", "geometry": { "type": "LineString", "dimensions": 2 }, "properties": [ { "id": "contentId", "type": "Integer", "description": "Unique identifier for content", "required": true }, { "id": "contentName", "type": "String", "description": "Name of the content feature", "required": false, "default": "Unnamed Feature" }, { "id": "elevation", "type": "Float", "description": "Elevation in meters", "unit": "meters", "min": -1000.0, "max": 9000.0, "required": false, "default": 0.0 }, { "id": "isActive", "type": "Boolean", "description": "Whether the feature is active", "required": false, "default": true } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/duplicatePropertyIdsTileset.json ================================================ { "extras": { "info": { "note": "This tileset is INVALID because the referenced schema (duplicate_property_ids_schema.json) contains properties with duplicate IDs, which violates the requirement that property IDs must be unique within a schema." } }, "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset": { "version": "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "duplicate_property_ids_schema.json" } } }, "geometricError": 2.0, "root": { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/duplicate_property_ids_schema.json ================================================ { "name": "Schema with Duplicate Property IDs", "semantic": "test_duplicate_ids", "geometry": { "type": "Point", "dimensions": 2 }, "properties": [ { "id": "duplicateId", "type": "Integer", "description": "First property with duplicate ID", "required": true }, { "id": "uniqueId", "type": "String", "description": "Property with unique ID", "required": false, "default": "unique" }, { "id": "duplicateId", "type": "Float", "description": "Second property with duplicate ID", "required": false, "default": 0.0 }, { "id": "anotherId", "type": "Boolean", "description": "Another unique property", "required": false, "default": true }, { "id": "duplicateId", "type": "String", "description": "Third property with duplicate ID", "required": false, "default": "third" } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/extensionsUsedButNotRequiredTileset.json ================================================ { "extras": { "info": { "note": "This tileset is INVALID because MAXAR_content_geojson is declared in extensionsUsed but NOT in extensionsRequired. For GeoJSON content, the extension must be declared in both arrays." } }, "extensionsUsed": [ "MAXAR_content_geojson" ], "asset": { "version": "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": {} } }, "geometricError": 2.0, "root": { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/geometryCollection.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "Mixed geometry feature", "id": 1 }, "geometry": { "type": "GeometryCollection", "geometries": [ { "type": "Point", "coordinates": [0.0, 0.0] }, { "type": "LineString", "coordinates": [ [0.0, 0.0], [1.0, 1.0] ] }, { "type": "Polygon", "coordinates": [ [ [0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0] ] ] } ] } } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/geometryCollectionTileset.json ================================================ { "extras": { "info": { "note": "This tileset is INVALID because it references a GeoJSON file (geometryCollection.geojson) that contains a Feature with GeometryCollection geometry, which is not supported by the MAXAR_content_geojson extension." } }, "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset": { "version": "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": {} } }, "geometricError": 2.0, "root": { "content": { "uri": "geometryCollection.geojson" }, "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalid.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": "invalid_coordinates" }, "properties": { "name": "Invalid Point" } } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidDefaultTypesTileset.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "invalid_default_types_schema.json" } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidExtensionObject.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": "not an object" } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidGeojsonTileset.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "vegetation_schema.json" } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "invalid.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidMinMaxOnNonNumericType.json ================================================ { "extras": { "info": { "note": "This tileset has min/max properties on non-numeric property types" } }, "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset": { "version": "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "invalid_minmax_schema.json" } } }, "geometricError": 2.0, "root": { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidMinMaxTileset.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "invalid_min_max_schema.json" } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidPropertiesSchemaUri.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": 123 } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidRequiredWithDefaultTileset.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "invalid_required_with_default_schema.json" } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidSchemaContent.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "invalid_content_schema.json" } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidTilesetWithGeojson.json ================================================ { "extras" : { "info": { "note": "This tileset is INVALID because it uses GeoJSON content (lineString.geojson) without declaring the MAXAR_content_geojson extension in the extensions section. The extension must be declared in extensionsUsed, extensionsRequired, and the extensions object to use GeoJSON content in 3D Tiles." } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalidUriFormat.json ================================================ { "extras": { "info": { "note": "This tileset has an invalid URI format in propertiesSchemaUri" } }, "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset": { "version": "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "invalid uri with spaces.json" } } }, "geometricError": 2.0, "root": { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalid_content_schema.json ================================================ { "name": "Invalid Content Properties Schema", "geometry": { "type": "InvalidGeometryType", "dimensions": 5 }, "properties": [ { "id": "", "type": "InvalidType", "min": "not a number", "default": "" } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalid_default_types_schema.json ================================================ { "name": "Invalid Default Types Schema", "semantic": "test_data", "geometry": { "type": "Point", "dimensions": 2 }, "properties": [ { "id": "invalidStringDefault", "type": "String", "description": "String property with number default", "required": false, "default": 123 }, { "id": "invalidIntegerDefault", "type": "Integer", "description": "Integer property with string default", "required": false, "default": "not a number" }, { "id": "invalidFloatDefault", "type": "Float", "description": "Float property with boolean default", "required": false, "default": true }, { "id": "invalidBooleanDefault", "type": "Boolean", "description": "Boolean property with string default", "required": false, "default": "false" }, { "id": "validStringDefault", "type": "String", "description": "String property with valid string default (including empty)", "required": false, "default": "" }, { "id": "validIntegerDefault", "type": "Integer", "description": "Integer property with valid integer default", "required": false, "default": 42 }, { "id": "validFloatDefault", "type": "Float", "description": "Float property with valid float default", "required": false, "default": 3.14 }, { "id": "validBooleanDefault", "type": "Boolean", "description": "Boolean property with valid boolean default", "required": false, "default": false }, { "id": "invalidVariantDefault", "type": "Variant", "description": "Variant property with default (not allowed)", "required": false, "default": "not allowed" }, { "id": "validVariantNoDefault", "type": "Variant", "description": "Variant property without default (allowed)", "required": false } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalid_min_max_schema.json ================================================ { "name": "Invalid Min/Max Properties Schema", "semantic": "test_data", "geometry": { "type": "Point", "dimensions": 2 }, "properties": [ { "id": "invalidMinMax", "type": "Integer", "description": "Property with invalid min > max", "min": 100, "max": 50, "required": true }, { "id": "validMinMax", "type": "Float", "description": "Property with valid min <= max", "min": 10.5, "max": 20.5, "required": true }, { "id": "equalMinMax", "type": "Integer", "description": "Property with min = max", "min": 42, "max": 42, "required": true } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalid_minmax_schema.json ================================================ { "name": "Invalid Min/Max Schema", "semantic": "test_invalid_minmax", "geometry": { "type": "Point", "dimensions": 2 }, "properties": [ { "id": "stringWithMin", "type": "String", "description": "String property with invalid min", "required": false, "default": "test", "min": 1 }, { "id": "booleanWithMax", "type": "Boolean", "description": "Boolean property with invalid max", "required": false, "default": true, "max": 10 }, { "id": "variantWithMinMax", "type": "Variant", "description": "Variant property with invalid min/max", "required": false, "min": 0, "max": 100 } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/invalid_required_with_default_schema.json ================================================ { "name": "Invalid Required with Default Properties Schema", "semantic": "test_data", "geometry": { "type": "Point", "dimensions": 2 }, "properties": [ { "id": "invalidRequiredWithDefault", "type": "String", "description": "Property that is required but has a default value", "required": true, "default": "This should not be allowed" }, { "id": "validRequired", "type": "Integer", "description": "Property that is required without default", "required": true }, { "id": "validOptionalWithDefault", "type": "String", "description": "Property that is optional with default", "required": false, "default": "This is allowed" } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/lineString.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "UL", "code": 12 }, "geometry": { "type": "LineString", "coordinates": [ [ -75.61209430782448, 40.042530611425896 ], [ -75.61219430782448, 40.042530611425896 ], [ -75.61219430782448, 40.042630611425896 ], [ -75.61209430782448, 40.042630611425896 ], [ -75.61209430782448, 40.042530611425896 ] ] } } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/nonExistentSchema.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "non_existent_schema.json" } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/test_schema.json ================================================ { "name": "Test Properties Schema", "semantic": "test_data", "geometry": { "type": "Point", "dimensions": 3 }, "properties": [ { "id": "testId", "type": "Integer", "description": "Test identifier", "required": true }, { "id": "testName", "type": "String", "description": "Test name", "required": false, "default": "Test" } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/validOptionalWithoutDefaultsTileset.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "valid_optional_without_defaults_schema.json" } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/validTilesetWithMaxarContentGeojson.json ================================================ { "extras" : { "info": { "note": "The MAXAR_content_geojson example has been taken from the specification README.md" } }, "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "geometry_model": { "type": "STRING" }, "name": { "type": "STRING" }, "schema": { "type": "STRING" }, "wff_version": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "geometry_model": "OBJECTS", "name": "Vegetation Layer", "schema": "wff/15", "wff_version": "1.5" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "vegetation_schema.json" } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/validWithPropertiesSchemaUri.json ================================================ { "extensionsUsed": [ "MAXAR_content_geojson" ], "extensionsRequired": [ "MAXAR_content_geojson" ], "asset" : { "version" : "1.1" }, "extensions": { "MAXAR_content_geojson": {} }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "tileset": { "properties": { "content_type": { "type": "STRING" }, "name": { "type": "STRING" } } } } }, "metadata": { "class": "tileset", "properties": { "content_type": "VECTOR", "name": "Test Layer" }, "extensions": { "MAXAR_content_geojson": { "propertiesSchemaUri": "content_schema.json" } } }, "geometricError" : 2.0, "root" : { "content": { "uri": "lineString.geojson" }, "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarContentGeojson/valid_optional_without_defaults_schema.json ================================================ { "name": "Valid Schema with Optional Properties Without Defaults", "semantic": "test_data", "geometry": { "type": "Point", "dimensions": 2 }, "properties": [ { "id": "validStringNoDefault", "type": "String", "description": "Non-required String property without default value (defaults to null)", "required": false }, { "id": "validIntegerNoDefault", "type": "Integer", "description": "Non-required Integer property without default value (defaults to null)" }, { "id": "validFloatNoDefault", "type": "Float", "description": "Non-required Float property without default value (defaults to null)", "required": false }, { "id": "validBooleanNoDefault", "type": "Boolean", "description": "Non-required Boolean property without default value (defaults to null)", "required": false }, { "id": "validVariantNoDefault", "type": "Variant", "description": "Non-required Variant property without default (allowed)", "required": false }, { "id": "validStringWithDefault", "type": "String", "description": "Non-required String property with default value", "required": false, "default": "default_value" }, { "id": "validRequiredNoDefault", "type": "Integer", "description": "Required property without default (allowed)", "required": true } ] } ================================================ FILE: specs/data/extensions/maxarContentGeojson/vegetation_schema.json ================================================ { "name": "Vegetation Properties Schema", "semantic": "vegetation_data", "geometry": { "type": "Polygon", "dimensions": 2 }, "properties": [ { "id": "vegetationId", "type": "Integer", "description": "Unique identifier for vegetation", "required": true }, { "id": "species", "type": "String", "description": "Species of vegetation", "required": true }, { "id": "height", "type": "Float", "description": "Height in meters", "unit": "meters", "min": 0.0, "max": 100.0, "required": false, "default": 1.0 } ] } ================================================ FILE: specs/data/extensions/maxarExtent/collinearOverlap.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [0.0, 0.0], [0.002, 0.0], [0.002, 0.002], [0.001, 0.002], [0.001, 0.0], [0.0, 0.0] ]] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/collinearOverlapTileset.json ================================================ { "extras": { "info": { "note": "Test file with MAXAR_extent extension: collinear overlap (invalid geometry)" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "collinearOverlap.geojson" } }, "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "region": [ -0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0 ] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/extent.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[[0.0, 0.0], [0.001, 0.0], [0.001, 0.001], [0.0, 0.001], [0.0, 0.0]]] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/extentOverflowingTileTileset.json ================================================ { "extras" : { "info": { "note": "Test file with MAXAR_extent extension in southern hemisphere with complex shape extending outside region bounds" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "extent_overflowing_tile.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "region": [2.617993877991494, -0.4363323129985824, 2.7925268031909273, -0.17453292519943295, 0.0, 1000.0] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/extent_overflowing_tile.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [ [ [ 155, -17.5 ], [ 156, -15 ], [ 158, -12 ], [ 159, -14 ], [ 157.5, -16 ], [ 158.5, -18 ], [ 156.5, -20 ], [ 154, -19 ], [ 152, -17 ], [ 153, -15 ], [ 149.999, -13 ], [ 152.5, -11 ], [ 154.5, -12.5 ], [ 155, -17.5 ] ] ] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/insufficientCoordinates.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [0.0, 0.0], [0.001, 0.0], [0.0, 0.0], [0.0, 0.0] ]] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/insufficientCoordinatesTileset.json ================================================ { "extras" : { "info": { "note": "Test file with MAXAR_extent extension containing insufficient coordinates (less than 3 unique)" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "insufficientCoordinates.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "region": [-0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/internalTouchRing.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [[ [0.0, 0.5], [1.0, 0.5], [0.0, 0.0], [1.0, -0.5], [0.0, -0.5], [0.0, 0.5] ]] } } ] } ================================================ FILE: specs/data/extensions/maxarExtent/internalTouchRingTileset.json ================================================ { "extras": { "info": { "note": "Ring vertex lies exactly on a non-adjacent ring edge (invalid)" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "internalTouchRing.geojson" } }, "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "region": [ -0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0 ] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/invalidEmptyUri.json ================================================ { "extras" : { "info": { "note": "Test file with invalid empty URI for MAXAR_extent extension" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/invalidGeojsonContent.json ================================================ { "extras" : { "info": { "note": "Test file with invalid GeoJSON content for MAXAR_extent extension" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "invalid_extent.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/invalidGeometryTypes.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [0.0, 0.0] }, "properties": {} }, { "type": "Feature", "geometry": { "type": "LineString", "coordinates": [[0.0, 0.0], [0.001, 0.001]] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/invalidGeometryTypesTileset.json ================================================ { "extras" : { "info": { "note": "Test file with MAXAR_extent extension containing invalid geometry types (Point, LineString)" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "invalidGeometryTypes.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "region": [-0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/invalidMissingUri.json ================================================ { "extras" : { "info": { "note": "Test file with missing URI property for MAXAR_extent extension" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/invalidNonResolvableUri.json ================================================ { "extras" : { "info": { "note": "Test file with non-resolvable URI for MAXAR_extent extension" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "non_existent_file.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/invalidSpatialExtent.json ================================================ { "extras" : { "info": { "note": "Test file with MAXAR_extent extension containing coordinates outside the bounding volume" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "large_extent.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "region": [-0.008726646259971648, -0.008726646259971648, 0.008726646259971648, 0.008726646259971648, 0.0, 1000.0] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/invalidUriType.json ================================================ { "extras" : { "info": { "note": "Test file with invalid URI type (number instead of string) for MAXAR_extent extension" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": 123 } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/invalid_extent.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": "invalid_coordinates_should_be_array" }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/large_extent.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [-2.0, -2.0], [2.0, -2.0], [2.0, 2.0], [-2.0, 2.0], [-2.0, -2.0] ]] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/nearMiss.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [0.0, 0.0], [0.001, 0.001], [0.002, 0.0001], [0.0, 0.002], [0.0, 0.0] ]] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/nearMissTileset.json ================================================ { "extras": { "info": { "note": "Test file with MAXAR_extent extension: near miss (no intersection)" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "nearMiss.geojson" } }, "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "region": [ -0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0 ] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/nearVertexOnOtherSideFail.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [[ [0.0, 0.5], [1.0, 0.5], [-1E-10, 0.0], [1.0, -0.5], [0.0, -0.5], [0.0, 0.5] ]] } } ] } ================================================ FILE: specs/data/extensions/maxarExtent/nearVertexOnOtherSideFailTileset.json ================================================ { "extras": { "info": { "note": "Invalid: vertex breaks the ring (intersection) — no longer a Jordan curve" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "nearVertexOnOtherSideFail.geojson" } }, "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "region": [ -0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0 ] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/nearVertexOnOtherSideOk.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [[ [0.0, 0.5], [1.0, 0.5], [1E-10, 0.0], [1.0, -0.5], [0.0, -0.5], [0.0, 0.5] ]] } } ] } ================================================ FILE: specs/data/extensions/maxarExtent/nearVertexOnOtherSideOkTileset.json ================================================ { "extras": { "info": { "note": "Valid: vertex lies very close to the other side of a ring (within epsilon)" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "nearVertexOnOtherSideOk.geojson" } }, "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "region": [ -0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0 ] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/overlappingRings.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [0.0, 0.0], [0.002, 0.0], [0.002, 0.0012], [0.0, 0.0012], [0.0, 0.0] ] ], [ [ [0.001, 0.0002], [0.0025, 0.0002], [0.0025, 0.0014], [0.001, 0.0014], [0.001, 0.0002] ] ] ] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/overlappingRingsTileset.json ================================================ { "extras": { "info": { "note": "Two non-self-intersecting rings that overlap; overlaps should be allowed and treated as union" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "overlappingRings.geojson" } }, "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "region": [ -0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0 ] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/selfIntersecting.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [0.0, 0.0], [0.002, 0.002], [0.002, 0.0], [0.0, 0.002], [0.0, 0.0] ]] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/selfIntersectingTileset.json ================================================ { "extras" : { "info": { "note": "Test file with MAXAR_extent extension containing self-intersecting polygon" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "selfIntersecting.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "region": [-0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/small_extent.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [-0.5, -0.5], [0.5, -0.5], [0.5, 0.5], [-0.5, 0.5], [-0.5, -0.5] ]] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/trueCrossing.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [0.0, 0.0], [0.002, 0.002], [0.002, 0.0], [0.0, 0.0], [0.0, 0.002], [0.002, 0.0], [0.0, 0.0] ]] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/trueCrossingTileset.json ================================================ { "extras": { "info": { "note": "Test file with MAXAR_extent extension: true crossing (should intersect)" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "trueCrossing.geojson" } }, "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "region": [ -0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0 ] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/validPolygonsOnly.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [-0.001, -0.001], [0.001, -0.001], [0.001, 0.001], [-0.001, 0.001], [-0.001, -0.001] ]] }, "properties": {} }, { "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": [ [[ [-0.0005, -0.0005], [0.0005, -0.0005], [0.0005, 0.0005], [-0.0005, 0.0005], [-0.0005, -0.0005] ]] ] }, "properties": {} } ] } ================================================ FILE: specs/data/extensions/maxarExtent/validPolygonsOnlyTileset.json ================================================ { "extras" : { "info": { "note": "Test file with MAXAR_extent extension containing only valid Polygon and MultiPolygon geometries" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "validPolygonsOnly.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "region": [-0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/validTilesetWithMaxarExtent.json ================================================ { "extras" : { "info": { "note": "Test file with valid MAXAR_extent extension" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "extent.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarExtent/validTilesetWithSpatialExtent.json ================================================ { "extras" : { "info": { "note": "Test file with valid MAXAR_extent extension and spatial containment" } }, "extensionsUsed": [ "MAXAR_extent" ], "extensions": { "MAXAR_extent": { "uri": "small_extent.geojson" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "region": [-0.017453292519943295, -0.017453292519943295, 0.017453292519943295, 0.017453292519943295, 0.0, 1000.0] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidBoundingBoxLength.json ================================================ { "extras" : { "info": { "note": "Test file with invalid boundingBox array length for MAXAR_grid extension validation" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "extensions": { "MAXAR_grid": { "boundingBox": [ 3425906.396465421, 500000.0000000012, 3546738.395635767, 694559.9877318252 ], "index": [5, 4], "level": 3 } } } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidBoundingBoxSemantics.json ================================================ { "extras" : { "info": { "note": "Test file with invalid boundingBox semantics (xmin > xmax)" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "boundingBox": [100.0, 50.0, 50.0, 100.0, 0.0, 10.0], "level": 5, "index": [2, 3] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidCenterLength.json ================================================ { "extras" : { "info": { "note": "Test file with invalid center array length for MAXAR_grid extension validation" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidCoordinateSystemType.json ================================================ { "extras" : { "info": { "note": "Test file with invalid coordinateSystem type (number instead of string)" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": 999, "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidCoordinateSystemValue.json ================================================ { "extras" : { "info": { "note": "Test file with invalid coordinateSystem value (invalid UTM pattern)" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM_INVALID", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidElevation.json ================================================ { "extras" : { "info": { "note": "Test file with invalid elevation value for MAXAR_grid extension validation" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "INVALID_ELEVATION" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidGridType.json ================================================ { "extras" : { "info": { "note": "Test file with invalid grid type for MAXAR_grid extension validation" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "invalid_type", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidIndexLength.json ================================================ { "extras" : { "info": { "note": "Test file with invalid index array length for MAXAR_grid extension validation" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "extensions": { "MAXAR_grid": { "boundingBox": [ 3425906.396465421, 500000.0000000012, 3546738.395635767, 694559.9877318252, -581.1745009114966, 445.7444586344063 ], "index": [5], "level": 3 } } } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidS2GridWithCenter.json ================================================ { "extras" : { "info": { "note": "Test file with invalid S2 grid that incorrectly includes center property" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "s2", "center": [100, 200] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidS2GridWithSize.json ================================================ { "extras" : { "info": { "note": "Test file with S2 grid type that incorrectly includes size property" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "s2", "size": [2088960.0, 2088960.0] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidS2GridWithSrs.json ================================================ { "extras" : { "info": { "note": "Test file with S2 grid type that incorrectly includes srs property" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "s2", "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidSizeLength.json ================================================ { "extras" : { "info": { "note": "Test file with invalid size array length for MAXAR_grid extension validation" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0, 1000.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidSrsReferenceSystem.json ================================================ { "extras" : { "info": { "note": "Test file with invalid SRS reference system for MAXAR_grid extension validation" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "INVALID_REFERENCE_SYSTEM", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/invalidTileLevel.json ================================================ { "extras" : { "info": { "note": "Test file with invalid tile level (negative value) for MAXAR_grid extension validation" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "extensions": { "MAXAR_grid": { "boundingBox": [ 3425906.396465421, 500000.0000000012, 3546738.395635767, 694559.9877318252, -581.1745009114966, 445.7444586344063 ], "index": [5, 4], "level": -1 } } } } ================================================ FILE: specs/data/extensions/maxarGrid/validS2Grid.json ================================================ { "extras" : { "info": { "note": "Test file with valid S2 grid type for MAXAR_grid extension validation" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "s2" } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/extensions/maxarGrid/validTilesetWithMaxarGrid.json ================================================ { "extras" : { "info": { "note": "The MAXAR_grid example has been taken from the specification README.md" } }, "extensionsUsed": [ "MAXAR_grid" ], "extensions": { "MAXAR_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "extensions": { "MAXAR_grid": { "boundingBox": [ 3425906.396465421, 500000.0000000012, 3546738.395635767, 694559.9877318252, -581.1745009114966, 445.7444586344063 ], "index": [ 5, 4 ], "level": 3 } } } } ================================================ FILE: specs/data/extensions/maxarGrid/validTilesetWithVriconGrid.json ================================================ { "extras" : { "info": { "note": "The VRICON_grid is a legacy name for MAXAR_grid. The example here has been taken from the MAXAR_grid specification README.md" } }, "extensionsUsed": [ "VRICON_grid" ], "extensions": { "VRICON_grid": { "type": "quad", "center": [3097202.3706942615, 500000.00000000122], "size": [2088960.0, 2088960.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "extensions": { "VRICON_grid": { "boundingBox": [ 3425906.396465421, 500000.0000000012, 3546738.395635767, 694559.9877318252, -581.1745009114966, 445.7444586344063 ], "index": [ 5, 4 ], "level": 3 } } } } ================================================ FILE: specs/data/extensions/vriconClass/validTilesetWithVriconClass.json ================================================ { "extras" : { "info": { "note": "The VRICON_class example has been taken from the specification README.md" } }, "extensionsUsed": [ "VRICON_class" ], "extensions": { "VRICON_class": { "geometry": [ { "name": "dsm", "class": 1 } ], "texture": [ { "name": "r3dm::cdm_difference", "class": 18 }, { "name": "r3dm::date_avg", "class": 98 }, { "name": "r3dm::date_first", "class": 96 }, { "name": "r3dm::date_last", "class": 97 }, { "name": "r3dm::image_count", "class": 32 }, { "name": "r3dm::ndvi", "class": 2314 }, { "name": "r3dm::ndvi_cnt", "class": 2317 }, { "name": "r3dm::ndvi_max", "class": 2315 }, { "name": "r3dm::ndvi_min", "class": 2316 }, { "name": "r3dm::security", "class": 48 }, { "name": "r3dm::uncertainty_ce90", "class": 49 }, { "name": "r3dm::uncertainty_le90", "class": 50 }, { "name": "r3dm::universal_mix", "class": 86 }, { "name": "texture", "class": 1 } ] } }, "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/gltfExtensions/FeatureIdAttributeAndPropertyTableFeatureIdNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "FeatureIdAttributeAndPropertyTableSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class", "properties" : { "example_VEC3_FLOAT32" : { "name" : "Example VEC3 FLOAT32 property", "description" : "An example property, with type VEC3, with component type FLOAT32", "type" : "VEC3", "componentType" : "FLOAT32" } } } } }, "propertyTables" : [ { "name" : "Example property table", "class" : "exampleMetadataClass", "count" : 4, "properties" : { "example_VEC3_FLOAT32" : { "values" : 4 } } } ] } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5120, "count" : 16, "type" : "SCALAR", "max" : [ 123 ], "min" : [ -123 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/hQAAAIUAAACFAAAAhQAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAewAAAHsAAAB7AAAAewAAAA==", "byteLength" : 496 }, { "uri" : "data:application/gltf-buffer;base64,AAAAAM3MzD3NzEw+AACAP83MjD+amZk/AAAAQGZmBkDNzAxAAABAQGZmRkDNzExA", "byteLength" : 48 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 48 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0, "propertyTable" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/FeatureIdAttributeAndPropertyTableWithValueNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "FeatureIdAttributeAndPropertyTableSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class", "properties" : { "example_VEC3_FLOAT32" : { "name" : "Example VEC3 FLOAT32 property", "description" : "An example property, with type VEC3, with component type FLOAT32", "type" : "VEC3", "componentType" : "FLOAT32", "max": [ 3.0, 3.0, 3.0 ] } } } } }, "propertyTables" : [ { "name" : "Example property table", "class" : "exampleMetadataClass", "count" : 4, "properties" : { "example_VEC3_FLOAT32" : { "values" : 4 } } } ] } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 }, { "uri" : "data:application/gltf-buffer;base64,AAAAAM3MzD3NzEw+AACAP83MjD+amZk/AAAAQGZmBkDNzAxAAABAQGZmRkDNzExA", "byteLength" : 48 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 48 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0, "propertyTable" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/FeatureIdAttributePropertyTableInvalidValue.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "FeatureIdAttributeAndPropertyTableSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class", "properties" : { "example_VEC3_FLOAT32" : { "name" : "Example VEC3 FLOAT32 property", "description" : "An example property, with type VEC3, with component type FLOAT32", "type" : "VEC3", "componentType" : "FLOAT32" } } } } }, "propertyTables" : [ { "name" : "Example property table", "class" : "exampleMetadataClass", "count" : 4, "properties" : { "example_VEC3_FLOAT32" : { "values" : 4 } } } ] } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 }, { "uri" : "data:application/gltf-buffer;base64,AAAAAM3MzD3NzEw+AACAP83MjD+amZk/AAAAQGZmBkDNzAxAAABAQGZmRkDNzExA", "byteLength" : 48 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 48 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0, "propertyTable" : 12345 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/FeatureIdAttributePropertyTableWithoutPropertyTables.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "FeatureIdAttributeAndPropertyTableSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class", "properties" : { "example_VEC3_FLOAT32" : { "name" : "Example VEC3 FLOAT32 property", "description" : "An example property, with type VEC3, with component type FLOAT32", "type" : "VEC3", "componentType" : "FLOAT32" } } } } } } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 }, { "uri" : "data:application/gltf-buffer;base64,AAAAAM3MzD3NzEw+AACAP83MjD+amZk/AAAAQGZmBkDNzAxAAABAQGZmRkDNzExA", "byteLength" : 48 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 48 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0, "propertyTable" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/FeatureIdAttributePropertyTableWithoutStructuralMetadata.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 }, { "uri" : "data:application/gltf-buffer;base64,AAAAAM3MzD3NzEw+AACAP83MjD+amZk/AAAAQGZmBkDNzAxAAABAQGZmRkDNzExA", "byteLength" : 48 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 48 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0, "propertyTable" : 12345 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/FeatureIdTextureAndPropertyTableFeatureIdNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "FeatureIdTextureAndPropertyTableSchema", "classes" : { "buildingComponents" : { "name" : "Building components", "properties" : { "component" : { "name" : "Component", "type" : "STRING" }, "yearBuilt" : { "name" : "Year Built", "type" : "SCALAR", "componentType" : "INT16" } } } } }, "propertyTables" : [ { "name" : "Example property table", "class" : "buildingComponents", "count" : 4, "properties" : { "component" : { "values" : 4, "stringOffsets" : 5 }, "yearBuilt" : { "values" : 6 } } } ] } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 }, { "uri" : "data:application/gltf-buffer;base64,V2FsbERvb3JSb29mV2luZG93AAAAAAAABAAAAAgAAAAMAAAAEgAAAKgHzAfBB9IH", "byteLength" : 48 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 18 }, { "buffer" : 1, "byteOffset" : 20, "byteLength" : 20 }, { "buffer" : 1, "byteOffset" : 40, "byteLength" : 8 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABgSURBVDhPpczLEYAgDADR0IfctP/KtAWcZUYGlU8S9rDHJ+e2p5WErSAZIC9SAPIgL4CsyA8gC9IESIt0AdIgQ4BmyBSgEaICqIeoAWohJoC+iBmgGnEB9CCBibMrHnIDWhGma1gYMlcAAAAASUVORK5CYII=", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 2, "texture" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "propertyTable" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/ValidFeatureIdAttributeAndPropertyTable.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "FeatureIdAttributeAndPropertyTableSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class", "properties" : { "example_VEC3_FLOAT32" : { "name" : "Example VEC3 FLOAT32 property", "description" : "An example property, with type VEC3, with component type FLOAT32", "type" : "VEC3", "componentType" : "FLOAT32" } } } } }, "propertyTables" : [ { "name" : "Example property table", "class" : "exampleMetadataClass", "count" : 4, "properties" : { "example_VEC3_FLOAT32" : { "values" : 4 } } } ] } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 }, { "uri" : "data:application/gltf-buffer;base64,AAAAAM3MzD3NzEw+AACAP83MjD+amZk/AAAAQGZmBkDNzAxAAABAQGZmRkDNzExA", "byteLength" : 48 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 48 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0, "propertyTable" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/ValidFeatureIdTextureAndPropertyTable.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "FeatureIdTextureAndPropertyTableSchema", "classes" : { "buildingComponents" : { "name" : "Building components", "properties" : { "component" : { "name" : "Component", "type" : "STRING" }, "yearBuilt" : { "name" : "Year Built", "type" : "SCALAR", "componentType" : "INT16" } } } } }, "propertyTables" : [ { "name" : "Example property table", "class" : "buildingComponents", "count" : 4, "properties" : { "component" : { "values" : 4, "stringOffsets" : 5 }, "yearBuilt" : { "values" : 6 } } } ] } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 }, { "uri" : "data:application/gltf-buffer;base64,V2FsbERvb3JSb29mV2luZG93AAAAAAAABAAAAAgAAAAMAAAAEgAAAKgHzAfBB9IH", "byteLength" : 48 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 18 }, { "buffer" : 1, "byteOffset" : 20, "byteLength" : 20 }, { "buffer" : 1, "byteOffset" : 40, "byteLength" : 8 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "propertyTable" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ValidGltfGpmLocal.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ValidMeshPrimitiveGpmLocal.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointDirectAdjustmentParamsInvalidElementType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, "Not a number", 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointDirectAdjustmentParamsInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointDirectAdjustmentParamsInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : "Not an array" } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointDirectAdjustmentParamsMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointDirectPositionInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointDirectPositionInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : "Not an array", "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointDirectPositionMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectAdjustmentParamsInvalidElementType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, "Not a number", 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectAdjustmentParamsInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectAdjustmentParamsInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : "Not an array", "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectAdjustmentParamsMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectCovarianceInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectCovarianceMatrixInvalidElementType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, "Not a number", 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectCovarianceMatrixInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : "Not an array" } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectCovarianceMatrixMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectPositionInvalidElementType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, "Not a number", 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectPositionInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectPositionInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : "Not an array", "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointIndirectPositionMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointsDirectInvalidElementType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ "Not an object", { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointsDirectInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointsDirectInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : "Not an array", "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointsIndirectInvalidElementType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ "Not an object", { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointsIndirectInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/anchorPointsIndirectInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : "Not an array", "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupGroupFlagsElementInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, "Not a boolean", true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupGroupFlagsInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupGroupFlagsInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : "Not an array", "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupGroupFlagsMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupParamsInvalidElementType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ "Not an object", { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupParamsInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupParamsInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : "Not an array" } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupParamsMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupRotationThetasInvalidElementType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, "Not a number", 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupRotationThetasInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.9, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupRotationThetasInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : "Not an array", "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/correlationGroupRotationThetasMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/covarianceDirectUpperTriangleElementInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, "NOT_A_NUMBER", 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/covarianceDirectUpperTriangleInconsistentLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/covarianceDirectUpperTriangleInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "covarianceDirectUpperTriangle" : [] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/directAnchorPointsDirectMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/directCovarianceDirectUpperTriangleMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/directWithAnchorPointsIndirect.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsIndirect" : [], "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/directWithIntraTileCorrelationGroups.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Direct", "anchorPointsDirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ] } ], "covarianceDirectUpperTriangle" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/indirectAnchorPointsIndirectMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/indirectIntraTileCorrelationGroupsMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/indirectWithAnchorPointsDirect.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsDirect" : [], "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/indirectWithCovarianceDirectUpperTriangle.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "covarianceDirectUpperTriangle" : [], "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/intraTileCorrelationGroupsInvalidElementType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ "Not an object", { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/intraTileCorrelationGroupsInvalidLength.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] }, { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] }, { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] }, { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/intraTileCorrelationGroupsInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : "Not an array" } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeMetadataMaxInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": "Not a number" }, "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeMetadataMinInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": "Not a number", "max": 16.0 }, "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeMetadataSourceInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": 123.456, "min": 0.0, "max": 16.0 }, "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeMetadataSourceInvalidValue.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "NOT_A_VALID_SOURCE", "min": 0.0, "max": 16.0 }, "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureIndexInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": "Not a number", "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureIndexInvalidValue.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": 123.456, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureNoDataInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": 0, "noData": "Not a number", "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureNoDataInvalidValue.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": 0, "noData": 123.456, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureOffsetInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": 0, "noData": 255, "offset": "Not a number", "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureScaleInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": 0, "noData": 255, "offset": 0.0, "scale": "Not a number", "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureTexCoordInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": "Not a number" } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureTexCoordInvalidValue.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 12345 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureTraitsInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "traits": "Not an object", "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTextureTraitsMissing.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ { "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTexturesInvalidElementType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [ "Not an object", { "traits": { "source": "SIGZ", "min": 0.0, "max": 16.0 }, "index": 0, "noData": 255, "offset": 0.0, "scale": 0.06274509803921569, "texCoord": 0 } ] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTexturesInvalidLength.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": [] } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/ppeTexturesInvalidType.gltf ================================================ { "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 6, "type": "SCALAR", "max": [3], "min": [0] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 4, "type": "VEC3", "max": [1.0, 1.0, 0.0], "min": [0.0, 0.0, 0.0] }, { "bufferView": 1, "byteOffset": 48, "componentType": 5126, "count": 4, "type": "VEC3", "max": [0.0, 0.0, 1.0], "min": [0.0, 0.0, 1.0] }, { "bufferView": 1, "byteOffset": 96, "componentType": 5126, "count": 4, "type": "VEC2", "max": [1.0, 1.0], "min": [0.0, 0.0] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA", "byteLength": 156 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 12, "target": 34963 }, { "buffer": 0, "byteOffset": 12, "byteLength": 144, "byteStride": 12, "target": 34962 } ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVR42hXMUwCWBwBA0b8Wlo1lLHNt2a4tLZtbrdZatm1jWcu2bSxrtWq1Zds438O5jzcUCoU+hSEsXxCO8EQgIl8SichEISrRiE4MQjElFrGJQ1ziEZ8EJOQrEpGYJCQlGcmDQQpJSSpS8zVpSEs60pOBjGQiM1nISrZgkF2+IQff8h05yUVu8pCXfOSnAAUpROFgUESKUozilKAkpShNGcryPT9QjvJUoGIwqCQ/UpkqVKUa1alBTWpRmzrUpR71aRAMGkojGtOEn/iZpjTjF5rTgl9pyW+04vdg0Fra0JZ2tKcDHelEZ7rQlW50pwc96RUMeksf+tKP/gxgIIMYzBCGMozhjGAko4LBaBnDWMYxnglMZBJ/MJkpTGUa05nBzGAwS2Yzh7n8yTzms4CFLGIxS1jKMpazIhislFWsZg1rWcd6NrCRTWxmC1vZxnZ2BIOdsovd7GEv+9jPAQ5yiMMc4Sh/cYzjweCEnOQUpznDWc5xngv8zUUu8Q+XucLVYPCvXOM6//E/N7jJLW5zh7vc4z4PeMijYPBYnvCUZzznBS95xWve8JZ3vOcDH/nEZ7gvfpBCxLDKAAAAAElFTkSuQmCC", "mimeType": "image/png" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 1, "NORMAL": 2, "TEXCOORD_0": 3 }, "indices": 0, "mode": 4, "extensions": { "NGA_gpm_local": { "ppeTextures": "Not an array" } } } ] } ], "nodes": [ { "mesh": 0 } ], "samplers": [ { "magFilter": 9728, "minFilter": 9728, "wrapS": 33071, "wrapT": 33071 } ], "scene": 0, "scenes": [ { "nodes": [0] } ], "textures": [ { "sampler": 0, "source": 0 } ], "extensionsUsed": ["NGA_gpm_local"] } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfAInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : "Not a number", "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfAInvalidValueA.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 0.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfAInvalidValueB.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.1, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfAMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfAlphaInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : "Not a number", "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfAlphaInvalidValueA.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : -0.1, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfAlphaInvalidValueB.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 1.0, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfAlphaMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfBetaInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : "Not a number", "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfBetaInvalidValueA.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : -0.1, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfBetaInvalidValueB.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 10.1, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfBetaMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfTInvalidType.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : "Not a number" }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfTInvalidValue.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 0.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/spdcfTMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : "Indirect", "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/storageTypeInvalidValue.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "storageType" : 12345, "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/gpmLocal/storageTypeMissing.gltf ================================================ { "asset" : { "version" : "2.0" }, "extensionsUsed" : [ "NGA_gpm_local" ], "extensions" : { "NGA_gpm_local" : { "anchorPointsIndirect" : [ { "position" : [ 12.34, 23.45, 34.56 ], "adjustmentParams" : [ 0.1, 0.2, 0.3 ], "covarianceMatrix" : [ 0.1833647900304413, -0.093582914309524, 0.4550734755685732, 0.0572007221435672, -0.18392374133036396, 0.27486040919852534 ] } ], "intraTileCorrelationGroups" : [ { "groupFlags" : [ true, true, true ], "rotationThetas" : [ 0.1, 0.2, 0.3 ], "params" : [ { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 }, { "A" : 1.0, "alpha" : 0.99, "beta" : 0.0, "T" : 10000.0 } ] } ] } } } ================================================ FILE: specs/data/gltfExtensions/instanceFeatures/InstanceFeaturesFeatureIdAttributeInvalidValue.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "GpuInstancesMetadataSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class", "properties" : { "example_STRING" : { "name" : "Example STRING property", "description" : "An example property, with component type STRING", "type" : "STRING" } } } } }, "propertyTables" : [ { "name" : "Example property table", "class" : "exampleMetadataClass", "count" : 10, "properties" : { "example_STRING" : { "values" : 7, "stringOffsets" : 8 } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata", "EXT_mesh_gpu_instancing", "EXT_instance_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5125, "count" : 36, "type" : "SCALAR", "max" : [ 23 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 24, "type" : "VEC3", "max" : [ 1.0, 1.0, 1.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 24, "type" : "VEC3", "max" : [ 1.0, 1.0, 1.0 ], "min" : [ -1.0, -1.0, -1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 10, "type" : "VEC3", "max" : [ 10.0, 10.0, 10.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5126, "count" : 10, "type" : "VEC4", "max" : [ 0.733, 0.462, 0.191, 1.0 ], "min" : [ 0.0, 0.0, 0.0, 0.462 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5126, "count" : 10, "type" : "VEC3", "max" : [ 2.0, 2.0, 2.0 ], "min" : [ 1.0, 1.0, 1.0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5123, "count" : 10, "type" : "SCALAR", "max" : [ 9 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAAAAAIAAAABAAAAAAAAAAMAAAACAAAABAAAAAYAAAAFAAAABAAAAAcAAAAGAAAACAAAAAoAAAAJAAAACAAAAAsAAAAKAAAADAAAAA4AAAANAAAADAAAAA8AAAAOAAAAEAAAABIAAAARAAAAEAAAABMAAAASAAAAFAAAABYAAAAVAAAAFAAAABcAAAAWAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAgD8AAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAACAPwAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAA", "byteLength" : 720 }, { "uri" : "data:application/gltf-buffer;base64,AAAAAAAAAAAAAAAA5DiOP+Q4jj/kOI4/5DgOQOQ4DkDkOA5AVlVVQFZVVUBWVVVA5DiOQOQ4jkDkOI5AHcexQB3HsUAdx7FAVlXVQFZV1UBWVdVAjuP4QI7j+ECO4/hA5DgOQeQ4DkHkOA5BAAAgQQAAIEEAACBBAAAAAAAAAAAAAAAAAACAP92ZzD0Q9YA9B0HVPHcffj/QGUs+AAMAPrywUz3rhHg/HXaWPuWqPT4f05w9Y0VvP3UqxT6+ing+IIHNPZiDYj+d+vA+w+KXPqEr+z1ub1I/DaEMP/RFsT6bkxI+REU/P9m0Hj+hD8g+H2slPgpNKT/WdC4/P+rbPqHVNT462RA/46U7P0SL7D6BlUM+RIvsPgAAgD8AAIA/AACAP+Q4jj/kOI4/5DiOP8dxnD/HcZw/x3GcP6uqqj+rqqo/q6qqP47juD+O47g/juO4P3Icxz9yHMc/chzHP1ZV1T9WVdU/VlXVPzmO4z85juM/OY7jPxzH8T8cx/E/HMfxPwAAAEAAAABAAAAAQAkACAAHAAYABQAEAAMAAgABAAAA", "byteLength" : 420 }, { "uri" : "data:application/gltf-buffer;base64,emVyb29uZXR3b3RocmVlZm91cmZpdmVzaXhzZXZlbmVpZ2h0bmluZQAAAAAEAAAABwAAAAoAAAAPAAAAEwAAABcAAAAaAAAAHwAAACQAAAAoAAAA", "byteLength" : 84 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 144, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 144, "byteLength" : 288, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 288, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 120 }, { "buffer" : 1, "byteOffset" : 120, "byteLength" : 160 }, { "buffer" : 1, "byteOffset" : 280, "byteLength" : 120 }, { "buffer" : 1, "byteOffset" : 400, "byteLength" : 20 }, { "buffer" : 2, "byteOffset" : 0, "byteLength" : 40 }, { "buffer" : 2, "byteOffset" : 40, "byteLength" : 44 } ], "meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1, "NORMAL" : 2 }, "indices" : 0, "mode" : 4 } ] } ], "nodes" : [ { "extensions" : { "EXT_mesh_gpu_instancing" : { "attributes" : { "TRANSLATION" : 3, "ROTATION" : 4, "SCALE" : 5, "_FEATURE_ID_0" : 6 } }, "EXT_instance_features" : { "featureIds" : [ { "featureCount" : 10, "attribute" : 12345, "propertyTable" : 0 } ] } }, "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/instanceFeatures/InstanceFeaturesWithoutMeshGpuInstancing.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "GpuInstancesMetadataSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class", "properties" : { "example_STRING" : { "name" : "Example STRING property", "description" : "An example property, with component type STRING", "type" : "STRING" } } } } }, "propertyTables" : [ { "name" : "Example property table", "class" : "exampleMetadataClass", "count" : 10, "properties" : { "example_STRING" : { "values" : 7, "stringOffsets" : 8 } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata", "EXT_mesh_gpu_instancing", "EXT_instance_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5125, "count" : 36, "type" : "SCALAR", "max" : [ 23 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 24, "type" : "VEC3", "max" : [ 1.0, 1.0, 1.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 24, "type" : "VEC3", "max" : [ 1.0, 1.0, 1.0 ], "min" : [ -1.0, -1.0, -1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 10, "type" : "VEC3", "max" : [ 10.0, 10.0, 10.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5126, "count" : 10, "type" : "VEC4", "max" : [ 0.733, 0.462, 0.191, 1.0 ], "min" : [ 0.0, 0.0, 0.0, 0.462 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5126, "count" : 10, "type" : "VEC3", "max" : [ 2.0, 2.0, 2.0 ], "min" : [ 1.0, 1.0, 1.0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5123, "count" : 10, "type" : "SCALAR", "max" : [ 9 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAAAAAIAAAABAAAAAAAAAAMAAAACAAAABAAAAAYAAAAFAAAABAAAAAcAAAAGAAAACAAAAAoAAAAJAAAACAAAAAsAAAAKAAAADAAAAA4AAAANAAAADAAAAA8AAAAOAAAAEAAAABIAAAARAAAAEAAAABMAAAASAAAAFAAAABYAAAAVAAAAFAAAABcAAAAWAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAgD8AAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAACAPwAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAA", "byteLength" : 720 }, { "uri" : "data:application/gltf-buffer;base64,AAAAAAAAAAAAAAAA5DiOP+Q4jj/kOI4/5DgOQOQ4DkDkOA5AVlVVQFZVVUBWVVVA5DiOQOQ4jkDkOI5AHcexQB3HsUAdx7FAVlXVQFZV1UBWVdVAjuP4QI7j+ECO4/hA5DgOQeQ4DkHkOA5BAAAgQQAAIEEAACBBAAAAAAAAAAAAAAAAAACAP92ZzD0Q9YA9B0HVPHcffj/QGUs+AAMAPrywUz3rhHg/HXaWPuWqPT4f05w9Y0VvP3UqxT6+ing+IIHNPZiDYj+d+vA+w+KXPqEr+z1ub1I/DaEMP/RFsT6bkxI+REU/P9m0Hj+hD8g+H2slPgpNKT/WdC4/P+rbPqHVNT462RA/46U7P0SL7D6BlUM+RIvsPgAAgD8AAIA/AACAP+Q4jj/kOI4/5DiOP8dxnD/HcZw/x3GcP6uqqj+rqqo/q6qqP47juD+O47g/juO4P3Icxz9yHMc/chzHP1ZV1T9WVdU/VlXVPzmO4z85juM/OY7jPxzH8T8cx/E/HMfxPwAAAEAAAABAAAAAQAkACAAHAAYABQAEAAMAAgABAAAA", "byteLength" : 420 }, { "uri" : "data:application/gltf-buffer;base64,emVyb29uZXR3b3RocmVlZm91cmZpdmVzaXhzZXZlbmVpZ2h0bmluZQAAAAAEAAAABwAAAAoAAAAPAAAAEwAAABcAAAAaAAAAHwAAACQAAAAoAAAA", "byteLength" : 84 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 144, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 144, "byteLength" : 288, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 288, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 120 }, { "buffer" : 1, "byteOffset" : 120, "byteLength" : 160 }, { "buffer" : 1, "byteOffset" : 280, "byteLength" : 120 }, { "buffer" : 1, "byteOffset" : 400, "byteLength" : 20 }, { "buffer" : 2, "byteOffset" : 0, "byteLength" : 40 }, { "buffer" : 2, "byteOffset" : 40, "byteLength" : 44 } ], "meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1, "NORMAL" : 2 }, "indices" : 0, "mode" : 4 } ] } ], "nodes" : [ { "extensions" : { "EXT_instance_features" : { "featureIds" : [ { "featureCount" : 10, "attribute" : 0, "propertyTable" : 0 } ] } }, "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/instanceFeatures/ValidInstanceFeatures.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "GpuInstancesMetadataSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class", "properties" : { "example_STRING" : { "name" : "Example STRING property", "description" : "An example property, with component type STRING", "type" : "STRING" } } } } }, "propertyTables" : [ { "name" : "Example property table", "class" : "exampleMetadataClass", "count" : 10, "properties" : { "example_STRING" : { "values" : 7, "stringOffsets" : 8 } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata", "EXT_mesh_gpu_instancing", "EXT_instance_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5125, "count" : 36, "type" : "SCALAR", "max" : [ 23 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 24, "type" : "VEC3", "max" : [ 1.0, 1.0, 1.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 24, "type" : "VEC3", "max" : [ 1.0, 1.0, 1.0 ], "min" : [ -1.0, -1.0, -1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 10, "type" : "VEC3", "max" : [ 10.0, 10.0, 10.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5126, "count" : 10, "type" : "VEC4", "max" : [ 0.733, 0.462, 0.191, 1.0 ], "min" : [ 0.0, 0.0, 0.0, 0.462 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5126, "count" : 10, "type" : "VEC3", "max" : [ 2.0, 2.0, 2.0 ], "min" : [ 1.0, 1.0, 1.0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5123, "count" : 10, "type" : "SCALAR", "max" : [ 9 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAAAAAIAAAABAAAAAAAAAAMAAAACAAAABAAAAAYAAAAFAAAABAAAAAcAAAAGAAAACAAAAAoAAAAJAAAACAAAAAsAAAAKAAAADAAAAA4AAAANAAAADAAAAA8AAAAOAAAAEAAAABIAAAARAAAAEAAAABMAAAASAAAAFAAAABYAAAAVAAAAFAAAABcAAAAWAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAgD8AAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAIA/AAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAACAPwAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAA", "byteLength" : 720 }, { "uri" : "data:application/gltf-buffer;base64,AAAAAAAAAAAAAAAA5DiOP+Q4jj/kOI4/5DgOQOQ4DkDkOA5AVlVVQFZVVUBWVVVA5DiOQOQ4jkDkOI5AHcexQB3HsUAdx7FAVlXVQFZV1UBWVdVAjuP4QI7j+ECO4/hA5DgOQeQ4DkHkOA5BAAAgQQAAIEEAACBBAAAAAAAAAAAAAAAAAACAP92ZzD0Q9YA9B0HVPHcffj/QGUs+AAMAPrywUz3rhHg/HXaWPuWqPT4f05w9Y0VvP3UqxT6+ing+IIHNPZiDYj+d+vA+w+KXPqEr+z1ub1I/DaEMP/RFsT6bkxI+REU/P9m0Hj+hD8g+H2slPgpNKT/WdC4/P+rbPqHVNT462RA/46U7P0SL7D6BlUM+RIvsPgAAgD8AAIA/AACAP+Q4jj/kOI4/5DiOP8dxnD/HcZw/x3GcP6uqqj+rqqo/q6qqP47juD+O47g/juO4P3Icxz9yHMc/chzHP1ZV1T9WVdU/VlXVPzmO4z85juM/OY7jPxzH8T8cx/E/HMfxPwAAAEAAAABAAAAAQAkACAAHAAYABQAEAAMAAgABAAAA", "byteLength" : 420 }, { "uri" : "data:application/gltf-buffer;base64,emVyb29uZXR3b3RocmVlZm91cmZpdmVzaXhzZXZlbmVpZ2h0bmluZQAAAAAEAAAABwAAAAoAAAAPAAAAEwAAABcAAAAaAAAAHwAAACQAAAAoAAAA", "byteLength" : 84 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 144, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 144, "byteLength" : 288, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 288, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 120 }, { "buffer" : 1, "byteOffset" : 120, "byteLength" : 160 }, { "buffer" : 1, "byteOffset" : 280, "byteLength" : 120 }, { "buffer" : 1, "byteOffset" : 400, "byteLength" : 20 }, { "buffer" : 2, "byteOffset" : 0, "byteLength" : 40 }, { "buffer" : 2, "byteOffset" : 40, "byteLength" : 44 } ], "meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1, "NORMAL" : 2 }, "indices" : 0, "mode" : 4 } ] } ], "nodes" : [ { "extensions" : { "EXT_mesh_gpu_instancing" : { "attributes" : { "TRANSLATION" : 3, "ROTATION" : 4, "SCALE" : 5, "_FEATURE_ID_0" : 6 } }, "EXT_instance_features" : { "featureIds" : [ { "featureCount" : 10, "attribute" : 0, "propertyTable" : 0 } ] } }, "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidDutyWithSineWaveform.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "KHR_lights_punctual", "MAXAR_temporal_light_traits" ], "extensions": { "KHR_lights_punctual": { "lights": [ { "type": "point", "color": [1.0, 0.0, 0.0], "intensity": 20.0, "name": "Invalid Duty with Sine Light", "extensions": { "MAXAR_temporal_light_traits": { "flashing": { "waveform": "sine", "frequency": 2.0, "duty": 0.75 } } } } ] } }, "scenes": [ { "nodes": [0] } ], "nodes": [ { "name": "invalid_duty_sine_light", "extensions": { "KHR_lights_punctual": { "light": 0 } } } ] } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidDutyWithTriangleWaveform.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "KHR_lights_punctual", "MAXAR_temporal_light_traits" ], "extensions": { "KHR_lights_punctual": { "lights": [ { "type": "point", "color": [1.0, 0.0, 0.0], "intensity": 20.0, "name": "Invalid Duty with Triangle Light", "extensions": { "MAXAR_temporal_light_traits": { "flashing": { "waveform": "triangle", "frequency": 2.0, "duty": 0.3 } } } } ] } }, "scenes": [ { "nodes": [0] } ], "nodes": [ { "name": "invalid_duty_triangle_light", "extensions": { "KHR_lights_punctual": { "light": 0 } } } ] } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidMissingWaveform.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "KHR_lights_punctual", "MAXAR_temporal_light_traits" ], "extensions": { "KHR_lights_punctual": { "lights": [ { "type": "point", "color": [1.0, 0.0, 0.0], "intensity": 20.0, "name": "Invalid Flashing Light", "extensions": { "MAXAR_temporal_light_traits": { "flashing": { "frequency": 2.0 } } } } ] } }, "scenes": [ { "nodes": [0] } ], "nodes": [ { "name": "invalid_flashing_light", "extensions": { "KHR_lights_punctual": { "light": 0 } } } ] } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidUndeclaredExtension.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "KHR_lights_punctual" ], "extensions": { "KHR_lights_punctual": { "lights": [ { "type": "point", "color": [1.0, 0.0, 0.0], "intensity": 20.0, "name": "Undeclared Extension Light", "extensions": { "MAXAR_temporal_light_traits": { "flashing": { "waveform": "square", "frequency": 2.0 } } } } ] } }, "scenes": [ { "nodes": [0] } ], "nodes": [ { "name": "undeclared_extension_light", "extensions": { "KHR_lights_punctual": { "light": 0 } } } ] } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidWaveform.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "KHR_lights_punctual", "MAXAR_temporal_light_traits" ], "extensions": { "KHR_lights_punctual": { "lights": [ { "type": "point", "color": [1.0, 0.0, 0.0], "intensity": 20.0, "name": "Invalid Waveform Light", "extensions": { "MAXAR_temporal_light_traits": { "flashing": { "waveform": "invalid_waveform", "frequency": 2.0 } } } } ] } }, "scenes": [ { "nodes": [0] } ], "nodes": [ { "name": "invalid_waveform_light", "extensions": { "KHR_lights_punctual": { "light": 0 } } } ] } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/validDutyWithSquareWaveform.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "KHR_lights_punctual", "MAXAR_temporal_light_traits" ], "extensions": { "KHR_lights_punctual": { "lights": [ { "type": "point", "color": [1.0, 0.0, 0.0], "intensity": 20.0, "name": "Valid Duty with Square Light", "extensions": { "MAXAR_temporal_light_traits": { "flashing": { "waveform": "square", "frequency": 2.0, "duty": 0.8 } } } } ] } }, "scenes": [ { "nodes": [0] } ], "nodes": [ { "name": "valid_duty_square_light", "extensions": { "KHR_lights_punctual": { "light": 0 } } } ] } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/validTemporalLightTraits.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "KHR_lights_punctual", "MAXAR_temporal_light_traits" ], "extensions": { "KHR_lights_punctual": { "lights": [ { "type": "directional", "color": [1.0, 0.9, 0.7], "intensity": 3.0, "name": "Directional Light" }, { "type": "point", "color": [1.0, 0.0, 0.0], "intensity": 20.0, "range": 100.0, "name": "Flashing Point Light", "extensions": { "MAXAR_temporal_light_traits": { "flashing": { "waveform": "square", "frequency": 2.0, "duty": 0.75, "amplitudeOffset": 0.1, "amplitudeScale": 0.8, "phaseOffset": 0.5 } } } }, { "type": "spot", "color": [0.3, 0.7, 1.0], "intensity": 40.0, "spot": { "innerConeAngle": 0.785398163397448, "outerConeAngle": 1.57079632679 }, "name": "Flashing Spot Light", "extensions": { "MAXAR_temporal_light_traits": { "flashing": { "waveform": "sine", "frequency": 1.5 } } } } ] } }, "scenes": [ { "nodes": [0, 1, 2] } ], "nodes": [ { "name": "directional_light", "extensions": { "KHR_lights_punctual": { "light": 0 } } }, { "name": "flashing_point_light", "extensions": { "KHR_lights_punctual": { "light": 1 } }, "translation": [0, 22, 0] }, { "name": "flashing_spot_light", "extensions": { "KHR_lights_punctual": { "light": 2 } }, "translation": [10, 10, 10] } ] } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/validKhrLightsPunctual.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "KHR_lights_punctual" ], "extensions": { "KHR_lights_punctual": { "lights": [ { "type": "directional", "color": [1.0, 0.9, 0.7], "intensity": 3.0, "name": "Directional Light" }, { "type": "point", "color": [1.0, 0.0, 0.0], "intensity": 20.0, "range": 100.0, "name": "Point Light" }, { "type": "spot", "color": [0.3, 0.7, 1.0], "intensity": 40.0, "spot": { "innerConeAngle": 0.785398163397448, "outerConeAngle": 1.57079632679 }, "name": "Spot Light" } ] } }, "scenes": [ { "nodes": [0, 1, 2] } ], "nodes": [ { "name": "directional_light", "extensions": { "KHR_lights_punctual": { "light": 0 } } }, { "name": "point_light", "extensions": { "KHR_lights_punctual": { "light": 1 } }, "translation": [0, 22, 0] }, { "name": "spot_light", "extensions": { "KHR_lights_punctual": { "light": 2 } }, "translation": [10, 10, 10] } ] } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/validTilesetWithInvalidKhrLightsPunctual.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 1000, "root": { "boundingVolume": { "region": [ -1.3197004795898053, 0.6988582109, -1.3196595204101946, 0.6988897891, 0, 20 ] }, "geometricError": 0, "refine": "REPLACE", "content": { "uri": "./maxarTemporalLightTraits/invalidUndeclaredExtension.gltf" } } } ================================================ FILE: specs/data/gltfExtensions/khrLightsPunctual/validTilesetWithKhrLightsPunctual.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 1000, "root": { "boundingVolume": { "region": [ -1.3197004795898053, 0.6988582109, -1.3196595204101946, 0.6988897891, 0, 20 ] }, "geometricError": 0, "refine": "REPLACE", "content": { "uri": "validKhrLightsPunctual.gltf" } } } ================================================ FILE: specs/data/gltfExtensions/maxarImageOrtho/invalidCoordinateSystem.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "MAXAR_image_ortho" ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "extensions": { "MAXAR_image_ortho": { "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "INVALID_SYSTEM", "elevation": "ELLIPSOID" } } } } ] } ================================================ FILE: specs/data/gltfExtensions/maxarImageOrtho/invalidMissingSrs.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "MAXAR_image_ortho" ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "extensions": { "MAXAR_image_ortho": { "transform": [0.0, 8.1875, -8.1875, 0.0, 3542945.276954, 782027.09375] } } } ] } ================================================ FILE: specs/data/gltfExtensions/maxarImageOrtho/invalidTransformLength.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "MAXAR_image_ortho" ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "extensions": { "MAXAR_image_ortho": { "transform": [0.0, 8.1875, -8.1875, 0.0], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID" } } } } ] } ================================================ FILE: specs/data/gltfExtensions/maxarImageOrtho/validMaxarImageOrtho.gltf ================================================ { "asset": { "version": "2.0" }, "extensionsUsed": [ "MAXAR_image_ortho" ], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "extensions": { "MAXAR_image_ortho": { "transform": [0.0, 8.1875, -8.1875, 0.0, 3542945.276954, 782027.09375], "srs": { "referenceSystem": "ITRF2008", "epoch": "2005.0", "coordinateSystem": "UTM14N", "elevation": "ELLIPSOID", "axis": "NED", "unitHorizontal": "METER", "unitVertical": "METER" } } } } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/NodeExtensionMeshInvalidType.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Node extension mesh property has invalid type (string instead of integer)" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 24, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 24, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 36, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 288, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 288, "byteOffset": 288, "target": 34962 }, { "buffer": 0, "byteLength": 72, "byteOffset": 576, "target": 34963 } ], "buffers": [ { "byteLength": 648, "uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAQANABMAAQATAAcACQAGABIACQASABUAFwAUAA4AFwAOABEAEAAEAAoAEAAKABYABQACAAgABQAIAAsADwAMAAAADwAAAAMA" } ], "meshes": [ { "name": "Cube", "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "extensions": { "MAXAR_nonvisual_geometry": { "mesh": "invalid" } }, "name": "Test Node" } ], "scene": 0, "scenes": [ { "name": "Scene", "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/NodeExtensionMeshInvalidValue.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Node extension mesh property has invalid value (negative integer)" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 24, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 24, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 36, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 288, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 288, "byteOffset": 288, "target": 34962 }, { "buffer": 0, "byteLength": 72, "byteOffset": 576, "target": 34963 } ], "buffers": [ { "byteLength": 648, "uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAQANABMAAQATAAcACQAGABIACQASABUAFwAUAA4AFwAOABEAEAAEAAoAEAAKABYABQACAAgABQAIAAsADwAMAAAADwAAAAMA" } ], "meshes": [ { "name": "Cube", "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "extensions": { "MAXAR_nonvisual_geometry": { "mesh": -1 } }, "name": "Test Node" } ], "scene": 0, "scenes": [ { "name": "Scene", "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/NodeExtensionMeshMissing.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Node extension missing required mesh property" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 24, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 24, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 36, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 288, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 288, "byteOffset": 288, "target": 34962 }, { "buffer": 0, "byteLength": 72, "byteOffset": 576, "target": 34963 } ], "buffers": [ { "byteLength": 648, "uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAQANABMAAQATAAcACQAGABIACQASABUAFwAUAA4AFwAOABEAEAAEAAoAEAAKABYABQACAAgABQAIAAsADwAMAAAADwAAAAMA" } ], "meshes": [ { "name": "Cube", "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "extensions": { "MAXAR_nonvisual_geometry": {} }, "name": "Test Node" } ], "scene": 0, "scenes": [ { "name": "Scene", "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/NodeExtensionMeshNotFound.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Node extension mesh property references non-existent mesh" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 24, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 24, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 36, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 288, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 288, "byteOffset": 288, "target": 34962 }, { "buffer": 0, "byteLength": 72, "byteOffset": 576, "target": 34963 } ], "buffers": [ { "byteLength": 648, "uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAQANABMAAQATAAcACQAGABIACQASABUAFwAUAA4AFwAOABEAEAAEAAoAEAAKABYABQACAAgABQAIAAsADwAMAAAADwAAAAMA" } ], "meshes": [ { "name": "Cube", "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "extensions": { "MAXAR_nonvisual_geometry": { "mesh": 5 } }, "mesh": 0, "name": "Test Node" } ], "scene": 0, "scenes": [ { "name": "Scene", "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionShapeInvalidType.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Primitive extension shape property has invalid type (number instead of string)" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 48, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 48, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 84, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 576, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 576, "byteOffset": 576, "target": 34962 }, { "buffer": 0, "byteLength": 168, "byteOffset": 1152, "target": 34963 } ], "buffers": [ { "byteLength": 1320, "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/AACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACA8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/AACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACA8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgL8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgD8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgL8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgL8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgD8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgL8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AQAEAAoAAQAKAAcACAALABEACAARAA4ADQAQABcADQAXABQAEwAWABwAEwAcABkAGgAdACIAGgAiAB8AIAAjACgAIAAoACUADwAJAAMAAwAtACcAJwAhABsAGwAVAA8ADwADACcAJwAbAA8AJgApAC8AJgAvACwAKwAuAAUAKwAFAAIAKgAAAAYABgAMABIAEgAYAB4AHgAkACoAKgAGABIAEgAeACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "123", "type": "collision" } }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionShapeInvalidValue.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Primitive extension shape property has invalid enum value" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 48, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 48, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 84, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 576, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 576, "byteOffset": 576, "target": 34962 }, { "buffer": 0, "byteLength": 168, "byteOffset": 1152, "target": 34963 } ], "buffers": [ { "byteLength": 1320, "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/AACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACA8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/AACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACA8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgL8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgD8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgL8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgL8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgD8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgL8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AQAEAAoAAQAKAAcACAALABEACAARAA4ADQAQABcADQAXABQAEwAWABwAEwAcABkAGgAdACIAGgAiAB8AIAAjACgAIAAoACUADwAJAAMAAwAtACcAJwAhABsAGwAVAA8ADwADACcAJwAbAA8AJgApAC8AJgAvACwAKwAuAAUAKwAFAAIAKgAAAAYABgAMABIAEgAYAB4AHgAkACoAKgAGABIAEgAeACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "invalid_shape", "type": "collision" } }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionShapeMissing.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Primitive extension missing required shape property" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 48, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 48, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 84, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 576, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 576, "byteOffset": 576, "target": 34962 }, { "buffer": 0, "byteLength": 168, "byteOffset": 1152, "target": 34963 } ], "buffers": [ { "byteLength": 1320, "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/AACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACA8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/AACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACA8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgL8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgD8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgL8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgL8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgD8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgL8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AQAEAAoAAQAKAAcACAALABEACAARAA4ADQAQABcADQAXABQAEwAWABwAEwAcABkAGgAdACIAGgAiAB8AIAAjACgAIAAoACUADwAJAAMAAwAtACcAJwAhABsAGwAVAA8ADwADACcAJwAbAA8AJgApAC8AJgAvACwAKwAuAAUAKwAFAAIAKgAAAAYABgAMABIAEgAYAB4AHgAkACoAKgAGABIAEgAeACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "type": "collision" } }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionTypeEmpty.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Primitive extension type property is empty string" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 48, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 48, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 84, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 576, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 576, "byteOffset": 576, "target": 34962 }, { "buffer": 0, "byteLength": 168, "byteOffset": 1152, "target": 34963 } ], "buffers": [ { "byteLength": 1320, "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/AACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACA8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/AACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACA8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgL8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgD8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgL8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgL8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgD8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgL8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AQAEAAoAAQAKAAcACAALABEACAARAA4ADQAQABcADQAXABQAEwAWABwAEwAcABkAGgAdACIAGgAiAB8AIAAjACgAIAAoACUADwAJAAMAAwAtACcAJwAhABsAGwAVAA8ADwADACcAJwAbAA8AJgApAC8AJgAvACwAKwAuAAUAKwAFAAIAKgAAAAYABgAMABIAEgAYAB4AHgAkACoAKgAGABIAEgAeACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "volume", "type": "" } }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionTypeInvalidType.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Primitive extension type property has invalid type (number instead of string)" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 48, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 48, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 84, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 576, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 576, "byteOffset": 576, "target": 34962 }, { "buffer": 0, "byteLength": 168, "byteOffset": 1152, "target": 34963 } ], "buffers": [ { "byteLength": 1320, "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/AACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACA8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/AACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACA8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgL8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgD8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgL8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgL8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgD8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgL8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AQAEAAoAAQAKAAcACAALABEACAARAA4ADQAQABcADQAXABQAEwAWABwAEwAcABkAGgAdACIAGgAiAB8AIAAjACgAIAAoACUADwAJAAMAAwAtACcAJwAhABsAGwAVAA8ADwADACcAJwAbAA8AJgApAC8AJgAvACwAKwAuAAUAKwAFAAIAKgAAAAYABgAMABIAEgAYAB4AHgAkACoAKgAGABIAEgAeACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "volume", "type": 123 } }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionTypeMissing.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Valid primitive extension with volume shape and TRIANGLES mode" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 48, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 48, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 84, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 576, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 576, "byteOffset": 576, "target": 34962 }, { "buffer": 0, "byteLength": 168, "byteOffset": 1152, "target": 34963 } ], "buffers": [ { "byteLength": 1320, "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/AACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACA8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/AACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACA8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgL8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgD8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgL8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgL8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgD8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgL8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AQAEAAoAAQAKAAcACAALABEACAARAA4ADQAQABcADQAXABQAEwAWABwAEwAcABkAGgAdACIAGgAiAB8AIAAjACgAIAAoACUADwAJAAMAAwAtACcAJwAhABsAGwAVAA8ADwADACcAJwAbAA8AJgApAC8AJgAvACwAKwAuAAUAKwAFAAIAKgAAAAYABgAMABIAEgAYAB4AHgAkACoAKgAGABIAEgAeACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "volume" } }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ShapePathIncompatibleMode.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Path shape with incompatible primitive mode (TRIANGLES instead of LINES/LINE_LOOP/LINE_STRIP)" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 5, "max": [ 0.0, 5.0, 0.0 ], "min": [ 0.0, 0.0, 0.0 ], "normalized": false, "type": "VEC3" } ], "bufferViews": [ { "buffer": 0, "byteLength": 60, "byteOffset": 0, "target": 34962 } ], "buffers": [ { "byteLength": 60, "uri": "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAgEAAAAAAAAAAAAAAoEAAAAAA" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "path", "type": "ladder" } }, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ShapePointsIncompatibleMode.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Points shape with incompatible primitive mode (TRIANGLES instead of POINTS)" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 2, "max": [ 2.0, 1.0, 1.0 ], "min": [ 1.0, 1.0, 1.0 ], "normalized": false, "type": "VEC3" } ], "bufferViews": [ { "buffer": 0, "byteLength": 24, "byteOffset": 0, "target": 34962 } ], "buffers": [ { "byteLength": 24, "uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIA/AAAAQAAAgD8AAIA/" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "points", "type": "trigger" } }, "mode": 3 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ShapeSurfaceIncompatibleMode.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Surface shape with incompatible primitive mode (POINTS instead of TRIANGLES/TRIANGLE_STRIP/TRIANGLE_FAN)" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 44, "max": [ 3.7761683464050293, 0.0, 1.0 ], "min": [ -3.7761683464050293, 0.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 44, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 180, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 528, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 528, "byteOffset": 528, "target": 34962 }, { "buffer": 0, "byteLength": 360, "byteOffset": 1056, "target": 34963 } ], "buffers": [ { "byteLength": 1416, "uri": "data:application/octet-stream;base64,vqxxwAAAAAAAAIA//1ZBwAAAAAAAAIA/PwERwAAAAAAAAIA//lbBvwAAAAAAAIA//lZBvwAAAAAAAIA/AAAAAAAAAAAAAIA/AVdBPwAAAAAAAIA//lbBPwAAAAAAAIA/PwERQAAAAAAAAIA/AFdBQAAAAAAAAIA/vqxxQAAAAAAAAIA/vqxxwAAAAACqqqo+/1ZBwAAAAACqqqo+PwERwAAAAACqqqo+/lbBvwAAAACqqqo+/lZBvwAAAACqqqo+AAAAAAAAAACqqqo+AVdBPwAAAACqqqo+/lbBPwAAAACqqqo+PwERQAAAAACqqqo+AFdBQAAAAACqqqo+vqxxQAAAAACqqqo+vqxxwAAAAACsqqq+/1ZBwAAAAACsqqq+PwERwAAAAACsqqq+/lbBvwAAAACsqqq+/lZBvwAAAACsqqq+AAAAAAAAAACsqqq+AVdBPwAAAACsqqq+/lbBPwAAAACsqqq+PwERQAAAAACsqqq+AFdBQAAAAACsqqq+vqxxQAAAAACsqqq+vqxxwAAAAAAAAIC//1ZBwAAAAAAAAIC/PwERwAAAAAAAAIC//lbBvwAAAAAAAIC//lZBvwAAAAAAAIC/AAAAAAAAAAAAAIC/AVdBPwAAAAAAAIC//lbBPwAAAAAAAIC/PwERQAAAAAAAAIC/AFdBQAAAAAAAAIC/vqxxQAAAAAAAAIC/AAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAABAAwAAAAMAAsAAQACAA0AAQANAAwAAgADAA4AAgAOAA0AAwAEAA8AAwAPAA4ABAAFABAABAAQAA8ABQAGABEABQARABAABgAHABIABgASABEABwAIABMABwATABIACAAJABQACAAUABMACQAKABUACQAVABQACwAMABcACwAXABYADAANABgADAAYABcADQAOABkADQAZABgADgAPABoADgAaABkADwAQABsADwAbABoAEAARABwAEAAcABsAEQASAB0AEQAdABwAEgATAB4AEgAeAB0AEwAUAB8AEwAfAB4AFAAVACAAFAAgAB8AFgAXACIAFgAiACEAFwAYACMAFwAjACIAGAAZACQAGAAkACMAGQAaACUAGQAlACQAGgAbACYAGgAmACUAGwAcACcAGwAnACYAHAAdACgAHAAoACcAHQAeACkAHQApACgAHgAfACoAHgAqACkAHwAgACsAHwArACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "surface", "type": "roadway" } }, "indices": 2, "mode": 0 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ShapeVolumeIncompatibleMode.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Volume shape with incompatible primitive mode (TRIANGLE_FAN instead of TRIANGLES/TRIANGLE_STRIP)" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 48, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 48, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 84, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 576, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 576, "byteOffset": 576, "target": 34962 }, { "buffer": 0, "byteLength": 168, "byteOffset": 1152, "target": 34963 } ], "buffers": [ { "byteLength": 1320, "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/AACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACA8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/AACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACA8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgL8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgD8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgL8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgL8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgD8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgL8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AQAEAAoAAQAKAAcACAALABEACAARAA4ADQAQABcADQAXABQAEwAWABwAEwAcABkAGgAdACIAGgAiAB8AIAAjACgAIAAoACUADwAJAAMAAwAtACcAJwAhABsAGwAVAA8ADwADACcAJwAbAA8AJgApAC8AJgAvACwAKwAuAAUAKwAFAAIAKgAAAAYABgAMABIAEgAYAB4AHgAkACoAKgAGABIAEgAeACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "volume", "type": "collision" } }, "indices": 2, "mode": 3 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ValidComplexExample.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Complex example with node extension and multiple primitive extensions" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 184, "max": [ 3.001398801803589, 1.6538207530975342, 2.018735885620117 ], "min": [ -1.0170875787734985, 0.0, -3.4930524826049805 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 184, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 306, "normalized": false, "type": "SCALAR" }, { "bufferView": 3, "byteOffset": 0, "componentType": 5126, "count": 4, "max": [ 3.012540578842163, 0.0, -2.0416343212127686 ], "min": [ 1.012540578842163, 0.0, -3.4089105129241943 ], "normalized": false, "type": "VEC3" }, { "bufferView": 4, "byteOffset": 0, "componentType": 5123, "count": 6, "normalized": false, "type": "SCALAR" }, { "bufferView": 5, "byteOffset": 0, "componentType": 5126, "count": 34, "max": [ 1.0345865488052368, 1.6568093299865723, 2.018935441970825 ], "min": [ -1.0179169178009033, 0.00039082765579223633, -3.5035672187805176 ], "normalized": false, "type": "VEC3" }, { "bufferView": 6, "byteOffset": 0, "componentType": 5123, "count": 60, "normalized": false, "type": "SCALAR" }, { "bufferView": 7, "byteOffset": 0, "componentType": 5126, "count": 1, "max": [ 1.25, 0.5, 0.0 ], "min": [ 1.25, 0.5, 0.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 8, "byteOffset": 0, "componentType": 5126, "count": 3, "max": [ 0.0, 1.649999976158142, 2.049999952316284 ], "min": [ 0.0, 0.0, 1.5499999523162842 ], "normalized": false, "type": "VEC3" } ], "bufferViews": [ { "buffer": 0, "byteLength": 2208, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 2208, "byteOffset": 2208, "target": 34962 }, { "buffer": 0, "byteLength": 612, "byteOffset": 4416, "target": 34963 }, { "buffer": 0, "byteLength": 48, "byteOffset": 5028, "target": 34962 }, { "buffer": 0, "byteLength": 12, "byteOffset": 5124, "target": 34963 }, { "buffer": 0, "byteLength": 408, "byteOffset": 5136, "target": 34962 }, { "buffer": 0, "byteLength": 120, "byteOffset": 5952, "target": 34963 }, { "buffer": 0, "byteLength": 12, "byteOffset": 6072, "target": 34962 }, { "buffer": 0, "byteLength": 36, "byteOffset": 6084, "target": 34962 } ], "buffers": [ { "byteLength": 6120, "uri": "data:application/octet-stream;base64,AACAvwAAAADNlPs/AACAvwAAAADNlPs/AACAvwAAAADNlPs/AACAPwAAAADNlPs/AACAPwAAAADNlPs/AACAPwAAAADNlPs/AACAvwAAAADNlPu/AACAvwAAAADNlPu/sw5fv9SJBz3MYATAsw5fv9SJBz3MYATAsw5fv9SJBz3MYATAAACAP2ffmj+RCV3AAACAP2ffmj+RCV3AAACAP2ffmj+RCV3AAACAv2ffmj+RCV3AAACAv2ffmj+RCV3AAACAv2ffmj+RCV3Asw5fv9SJBz0rc1bAsw5fv9SJBz0rc1bAsw5fv9SJBz0rc1bAAACAvwAAAACRCV3AAACAvwAAAACRCV3AAACAvwAAAACRCV3AAACAv2ffmj/NlPs/AACAv2ffmj/NlPs/AACAv2ffmj/NlPs/AACAv2ffmj/NlPs/Al4Ov2aw0z/Ow8I/Al4Ov2aw0z/Ow8I/Al4Ov2aw0z/Ow8I/AACAP2ffmj/NlPs/AACAP2ffmj/NlPs/AACAP2ffmj/NlPs/AACAP2ffmj/NlPs/Al4OP2aw0z/Ow8I/Al4OP2aw0z/Ow8I/Al4OP2aw0z/Ow8I/Al4Ov2aw0z/Ow8K/Al4Ov2aw0z/Ow8K/Al4Ov2aw0z/Ow8K/AACAv2ffmj/NlPu/AACAv2ffmj/NlPu/AACAv2ffmj/NlPu/AACAv2ffmj/NlPu/AACAP2ffmj/NlPu/AACAP2ffmj/NlPu/AACAP2ffmj/NlPu/AACAP2ffmj/NlPu/Al4OP2aw0z/Ow8K/Al4OP2aw0z/Ow8K/Al4OP2aw0z/Ow8K/AACAv/ZPjD+RCV3AAACAv/ZPjD+RCV3AAACAv/ZPjD+RCV3AAACAv/ZPjD+RCV3Asw5fv1plbD8rc1bAsw5fv1plbD8rc1bAsw5fv1plbD8rc1bAAACAv/ZPjD/NlPu/AACAv/ZPjD/NlPu/AACAv/ZPjD/NlPs/AACAv/ZPjD/NlPs/AACAv/ZPjD/NlPs/AACAv/ZPjD/NlPs/AACAP/ZPjD/NlPs/AACAP/ZPjD/NlPs/AACAP/ZPjD/NlPs/AACAP/ZPjD/NlPs/sw5fv1plbD/MYATAsw5fv1plbD/MYATAsw5fv1plbD/MYATA7S+CP66Xkz8sjl/A7S+CP66Xkz8sjl/A7S+CP66Xkz8sjl/A7S+CP66Xkz8sjl/A7S+Cv66Xkz/4MgFA7S+Cv66Xkz/4MgFA7S+Cv66Xkz/4MgFA7S+Cv66Xkz/4MgFA7S+CP66Xkz/4MgFA7S+CP66Xkz/4MgFA7S+CP66Xkz/4MgFA7S+CP66Xkz/4MgFA7S+CP66Xkz+4XP2/7S+CP66Xkz+4XP2/7S+Cv66Xkz8sjl/A7S+Cv66Xkz8sjl/A7S+Cv66Xkz8sjl/A7S+Cv66Xkz8sjl/A7S+Cv66Xkz+4XP2/7S+Cv66Xkz+4XP2/AACAPwAAAADNlPu/AACAPwAAAADNlPu/AACAPwAAAADNlPu/AACAPwAAAACRCV3AAACAPwAAAACRCV3AAACAPwAAAACRCV3AAACAP/ZPjD+RCV3AAACAP/ZPjD+RCV3AAACAP/ZPjD+RCV3AAACAP/ZPjD+RCV3AAACAP/ZPjD/NlPu/AACAP/ZPjD/NlPu/AACAP/ZPjD/NlPu/AACAPwAAAADNlPu/AACAPwAAAADNlPu/AACAPwAAAADNlPu/AACAPwAAAACRCV3AAACAPwAAAACRCV3AAACAPwAAAACRCV3AAACAP/ZPjD+RCV3AAACAP/ZPjD+RCV3AAACAP/ZPjD+RCV3AAACAP/ZPjD/NlPu/AACAP/ZPjD/NlPu/AACAP/ZPjD/NlPu/1y2APwAAAAA+UQDA6xZAQAAAAAA+UQDA1y2APwAAAAAchVzA6xZAQAAAAAAchVzAao9/PwAAAABGBso+ao9/PwAAAABGBso+ao9/PwAAAABGBso+fvu9PwAAAABGBso+fvu9PwAAAABGBso+fvu9PwAAAABGBso+ao9/PwAAAABGBsq+ao9/PwAAAABGBsq+ao9/PwAAAABGBsq+fvu9PwAAAABGBsq+fvu9PwAAAABGBsq+fvu9PwAAAABGBsq+ao9/P8jxrD1GBsq+ao9/P8jxrD1GBsq+ao9/P8jxrD1GBsq+ao9/P8jxrD1GBso+ao9/P8jxrD1GBso+ao9/P8jxrD1GBso+fvu9P8jxrD1GBso+fvu9P8jxrD1GBso+fvu9P8jxrD1GBso+fvu9P8jxrD1GBsq+fvu9P8jxrD1GBsq+fvu9P8jxrD1GBsq+0sB/PwxRsj3M4UQ+0sB/PwxRsj3M4UQ+0sB/PwxRsj3M4UQ+0sB/Pwr2ED/M4UQ+0sB/Pwr2ED/M4UQ+0sB/Pwr2ED/M4UQ+0sB/PwxRsj1YAIy90sB/PwxRsj1YAIy90sB/PwxRsj1YAIy90sB/Pwr2ED9YAIy90sB/Pwr2ED9YAIy90sB/Pwr2ED9YAIy9tXaCPxiX1j3GvjI+tXaCPxiX1j3GvjI+tXaCPxiX1j3GvjI+tXaCP0htDD/GvjI+tXaCP0htDD/GvjI+tXaCP0htDD/GvjI+tXaCPxiX1j2YdE+9tXaCPxiX1j2YdE+9tXaCPxiX1j2YdE+9tXaCP0htDD+YdE+9tXaCP0htDD+YdE+9tXaCP0htDD+YdE+9E0SEPwr2ED9YAIy9E0SEPwr2ED9YAIy9E0SEPwr2ED9YAIy9E0SEPwr2ED9YAIy9E0SEPwxRsj1YAIy9E0SEPwxRsj1YAIy9E0SEPwxRsj1YAIy9E0SEPwxRsj1YAIy9E0SEPwxRsj3M4UQ+E0SEPwxRsj3M4UQ+E0SEPwxRsj3M4UQ+E0SEPwxRsj3M4UQ+E0SEPwr2ED/M4UQ+E0SEPwr2ED/M4UQ+E0SEPwr2ED/M4UQ+E0SEPwr2ED/M4UQ+AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAMwGRPLz1fz8AAAAAXN5gPQAAAAAqnX+/AACAPwAAAAAAAAAAAAAAAKOjET8aiVK/AAAAAAAAgD8AAAAAES11PyhOkz4AAAAAAAAAAKOjET8aiVK/AAAAAAAAgD8AAAAAES11vyhOkz4AAAAAMwGRPLz1fz8AAAAAXN5gPQAAAAAqnX8/AACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAIL7Lj9+3Do/AAAAAPQENT/0BDU/9AQ1v/QENT8AAAAAES11vyhOkz4AAAAAAAAAAPQENT/0BDU/AAAAAAAAgD8AAAAA9AQ1v/QENT8AAAAAAAAAAIL7Lj9+3Do/AAAAAPQENT/0BDU/9AQ1P/QENT8AAAAAES11PyhOkz4AAAAAAAAAAPQENT/0BDU/AAAAAAAAgD8AAAAA9AQ1P/QENT8AAAAAAAAAAPQENT/0BDW/AAAAAAAAgD8AAAAA9AQ1v/QENT8AAAAAAAAAAPQENT/0BDW/AAAAAAAAgD8AAAAA9AQ1v/QENT8AAAAAES11vyhOkz4AAAAAAAAAAPQENT/0BDW/AAAAAAAAgD8AAAAA9AQ1P/QENT8AAAAAES11PyhOkz4AAAAAAAAAAPQENT/0BDW/AAAAAAAAgD8AAAAA9AQ1P/QENT8AAAAAAAAAAAAAAAAAAIC/AAAAAKOjEb8aiVK/ES11vyhOk74AAAAAAACAvwAAAAAAAAAAXN5gPQAAAAAqnX8/izS8PbDqfr8AAAAAAACAPwAAAAAAAAAAES11vyhOk74AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAIL7Lr9+3Do/ES11vyhOk74AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAIL7Lr9+3Do/ES11PyhOk74AAAAAAACAPwAAAAAAAAAAXN5gPQAAAAAqnX+/izS8PbDqfr8AAAAAAACAPwAAAAAAAAAAAAAAAKOjET8aiVK/AAAAAKOjEb8aiVK/ES11PyhOkz4AAAAAES11PyhOk74AAAAAAAAAAIL7Lj9+3Do/AAAAAIL7Lr9+3Do/ES11vyhOkz4AAAAAES11vyhOk74AAAAAAAAAAIL7Lj9+3Do/AAAAAIL7Lr9+3Do/ES11PyhOkz4AAAAAES11PyhOk74AAAAAES11PyhOkz4AAAAAES11PyhOk74AAAAAAAAAAKOjET8aiVK/AAAAAKOjEb8aiVK/ES11vyhOkz4AAAAAES11vyhOk74AAAAAES11vyhOkz4AAAAAES11vyhOk74AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAAAAAKOjEb8aiVK/ES11PyhOk74AAAAAAAAAAAAAgD8AAAAAES11PyhOk74AAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAMwGRPLz1fz8AAAAAXN5gPQAAAAAqnX+/AAAAAAAAgD8AAAAAMwGRPLz1fz8AAAAAXN5gPQAAAAAqnX8/AAAAAAAAgD8AAAAAXN5gPQAAAAAqnX8/izS8PbDqfr8AAAAAAAAAAAAAgD8AAAAAXN5gPQAAAAAqnX+/izS8PbDqfr8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAu2RIPwAAAABhTh+/u2RIP2FOHz8AAAAAAACAPwAAAAAAAAAAu2RIPwAAAABhTh+/u2RIP2FOH78AAAAAAACAPwAAAAAAAAAAu2RIPwAAAABhTh8/u2RIP2FOHz8AAAAAAACAPwAAAAAAAAAAu2RIPwAAAABhTh8/u2RIP2FOH78AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAu2RIPwAAAABhTh8/u2RIP2FOH78AAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAu2RIPwAAAABhTh8/u2RIP2FOHz8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAu2RIPwAAAABhTh+/u2RIP2FOHz8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAu2RIPwAAAABhTh+/u2RIP2FOH78AAAAAAQAGAFwAAQBcAAQARwBVAA4ARwAOAAsAXAAGABUAXAAVAGAARgAKABMARgATADkAKQAtAAwAKQAMAA8AKgAZAB0AKgAdACcAGAAfACIAGAAiABsAIAAuADIAIAAyACQALAAoACUALAAlADAAWQBNABoAWQAaACsAHAAjADEAHAAxACYASwBPAB4ASwAeABcAUQBTAC8AUQAvACEAWQArABAAWQAQAFcABwA7ADYABwA2ABYABQBdAGcABQBnAEMAAAADAEAAAABAADwABwACAD8ABwA/ADsAVABmAGQAVABkAEoAXgAUADMAXgAzAGEALwBTAEkALwBJAA0AOgBaAFgAOgBYADUAQgBmAFQAQgBUAFIAPQBBAFAAPQBQAEwAOgA+AE4AOgBOAFoAYwA0AFYAYwBWAEgAawBoAFsAawBbAF8AbgBrAF8AbgBfAGIAaABxAGUAaABlAFsAcQBuAGIAcQBiAGUAEQAIAGkAEQBpAGwANwASAG0ANwBtAG8ACQBEAHIACQByAGoARQA4AHAARQBwAHMAdAB1AHcAdAB3AHYAeQB/AIIAeQCCAHwAiACLAI4AiACOAIUAeAB7AIoAeACKAIcAfQCDAI8AfQCPAIwAgAB6AIkAgACJAIYAgQB+AIQAgQCEAI0AkgCVAJsAkgCbAJgAlgCZAKgAlgCoAKwApACnAKEApAChAJ4AsAC0AJMAsACTAJAAlwCtALEAlwCxAJEAqQCaAJQAqQCUALUApQCiAK4ApQCuAKoAowCdALMAowCzAK8AoACmAKsAoACrALcAnACfALYAnAC2ALIA7pqBPwAAAAAjqgLAd81AQAAAAAAjqgLA7pqBPwAAAACXK1rAd81AQAAAAACXK1rAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAABAAMAAAADAAIAGkuCvwDYzTk9NgFAGkuCvwDYzTk9NgFAGkuCvwDYzTk9NgFAGkuCv1QS1D89NgFAGkuCv1QS1D89NgFAGkuCv1QS1D89NgFAGkuCvwDozDlyOmDAGkuCvwDozDlyOmDAGkuCvwDozDlyOmDAGkuCv501mj9yOmDAGkuCv501mj9yOmDAGkuCv501mj9yOmDAD22EPwDYzTk9NgFAD22EPwDYzTk9NgFAD22EPwDYzTk9NgFAD22EP1QS1D89NgFAD22EP1QS1D89NgFAD22EP1QS1D89NgFAVW2EPwDozDlyOmDAVW2EPwDozDlyOmDAVW2EPwDozDlyOmDAVW2EP541mj9yOmDAVW2EP541mj9yOmDAVW2EP541mj9yOmDAGkuCv1QS1D8l2ce/GkuCv1QS1D8l2ce/GkuCv1QS1D8l2ce/GkuCvwDYzTkl2ce/GkuCvwDYzTkl2ce/D22EPwDYzTkl2ce/D22EPwDYzTkl2ce/D22EP1QS1D8l2ce/D22EP1QS1D8l2ce/D22EP1QS1D8l2ce/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAN9VeT8BImi+AACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAN9VeT8BImi+AACAPwAAAAAAAAAAAAAAAN9VeT8BImi+AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAN9VeT8BImi+AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAgAFABoAAgAaABwABgAJABUABgAVABIAHgAhABEAHgARAA4ADAAPAAMADAADAAAAGwAdAA0AGwANAAEAIAAZAAQAIAAEABAACwAIABwACwAcABoABwATAB0ABwAdABsAFgAKABgAFgAYAB8AFAAXACEAFAAhAB4AAACgPwAAAD8AAAAAAAAAAAAAAAAzMwNAAAAAAJqZmT8zMwNAAAAAADMz0z9mZsY/" } ], "meshes": [ { "name": "Visual Building mesh", "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "mode": 4 } ] }, { "name": "Nonvisual Building Mesh", "primitives": [ { "attributes": { "POSITION": 3 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "surface", "type": "roadway" } }, "indices": 4, "mode": 4 }, { "attributes": { "POSITION": 5 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "volume", "type": "collision" } }, "indices": 6, "mode": 4 }, { "attributes": { "POSITION": 7 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "points", "type": "trigger" } }, "mode": 0 }, { "attributes": { "POSITION": 8 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "path", "type": "ladder" } }, "mode": 3 } ] } ], "nodes": [ { "extensions": { "MAXAR_nonvisual_geometry": { "mesh": 1 } }, "mesh": 0, "name": "Visual Building" } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ValidNodeExtension.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Valid node extension referencing existing mesh" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 240, "max": [ 0.9510578513145447, 1.0, 0.9999999403953552 ], "min": [ -0.9510578513145447, -1.0, -0.9999999403953552 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 240, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 240, "normalized": false, "type": "SCALAR" }, { "bufferView": 3, "byteOffset": 0, "componentType": 5126, "count": 24, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 4, "byteOffset": 0, "componentType": 5123, "count": 36, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 2880, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 2880, "byteOffset": 2880, "target": 34962 }, { "buffer": 0, "byteLength": 480, "byteOffset": 5760, "target": 34963 }, { "buffer": 0, "byteLength": 288, "byteOffset": 6240, "target": 34962 }, { "buffer": 0, "byteLength": 72, "byteOffset": 6816, "target": 34963 } ], "buffers": [ { "byteLength": 6888, "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAVD45P/X55L7vlQY/VD45P/X55L7vlQY/VD45P/X55L7vlQY/VD45P/X55L7vlQY/VD45P/X55L7vlQY/u4KNvgD65L4mxFk/u4KNvgD65L4mxFk/u4KNvgD65L4mxFk/u4KNvgD65L4mxFk/u4KNvgD65L4mxFk/Hvlkv3L55L4AAACAHvlkv3L55L4AAACAHvlkv3L55L4AAACAHvlkv3L55L4AAACAHvlkv3L55L4AAACAu4KNvgD65L4mxFm/u4KNvgD65L4mxFm/u4KNvgD65L4mxFm/u4KNvgD65L4mxFm/u4KNvgD65L4mxFm/VD45P/X55L7vlQa/VD45P/X55L7vlQa/VD45P/X55L7vlQa/VD45P/X55L7vlQa/VD45P/X55L7vlQa/u4KNPgD65D4mxFk/u4KNPgD65D4mxFk/u4KNPgD65D4mxFk/u4KNPgD65D4mxFk/u4KNPgD65D4mxFk/VD45v/X55D7vlQY/VD45v/X55D7vlQY/VD45v/X55D7vlQY/VD45v/X55D7vlQY/VD45v/X55D7vlQY/VD45v/X55D7vlQa/VD45v/X55D7vlQa/VD45v/X55D7vlQa/VD45v/X55D7vlQa/VD45v/X55D7vlQa/u4KNPgD65D4mxFm/u4KNPgD65D4mxFm/u4KNPgD65D4mxFm/u4KNPgD65D4mxFm/u4KNPgD65D4mxFm/HvlkP3L55D4AAACAHvlkP3L55D4AAACAHvlkP3L55D4AAACAHvlkP3L55D4AAACAHvlkP3L55D4AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAwFomvn3EWb9h//8+wFomvn3EWb9h//8+wFomvn3EWb9h//8+wFomvn3EWb9h//8+wFomvn3EWb9h//8+wFomvn3EWb9h//8+5cPZPnnEWb++Np4+5cPZPnnEWb++Np4+5cPZPnnEWb++Np4+5cPZPnnEWb++Np4+5cPZPnnEWb++Np4+5cPZPnnEWb++Np4+vpaGPr6WBr9jG08/vpaGPr6WBr9jG08/vpaGPr6WBr9jG08/vpaGPr6WBr9jG08/vpaGPr6WBr9jG08/vpaGPr6WBr9jG08/D8RZP6GWBr8AAACAD8RZP6GWBr8AAACAD8RZP6GWBr8AAACAD8RZP6GWBr8AAACAD8RZP6GWBr8AAACAD8RZP6GWBr8AAACA5cPZPnnEWb++Np6+5cPZPnnEWb++Np6+5cPZPnnEWb++Np6+5cPZPnnEWb++Np6+5cPZPnnEWb++Np6+5cPZPnnEWb++Np6+OpYGv0/EWb8AAACAOpYGv0/EWb8AAACAOpYGv0/EWb8AAACAOpYGv0/EWb8AAACAOpYGv0/EWb8AAACAOpYGv0/EWb8AAACALi0wv6aWBr+Z//8+Li0wv6aWBr+Z//8+Li0wv6aWBr+Z//8+Li0wv6aWBr+Z//8+Li0wv6aWBr+Z//8+Li0wv6aWBr+Z//8+wFomvn3EWb9h//++wFomvn3EWb9h//++wFomvn3EWb9h//++wFomvn3EWb9h//++wFomvn3EWb9h//++wFomvn3EWb9h//++Li0wv6aWBr+Z//++Li0wv6aWBr+Z//++Li0wv6aWBr+Z//++Li0wv6aWBr+Z//++Li0wv6aWBr+Z//++Li0wv6aWBr+Z//++vpaGPr6WBr9jG0+/vpaGPr6WBr9jG0+/vpaGPr6WBr9jG0+/vpaGPr6WBr9jG0+/vpaGPr6WBr9jG0+/vpaGPr6WBr9jG0+/h3hzPwAAAADnNp4+h3hzPwAAAADnNp4+h3hzPwAAAADnNp4+h3hzPwAAAADnNp4+h3hzPwAAAADnNp4+h3hzPwAAAADnNp4+h3hzPwAAAADnNp6+h3hzPwAAAADnNp6+h3hzPwAAAADnNp6+h3hzPwAAAADnNp6+h3hzPwAAAADnNp6+h3hzPwAAAADnNp6+AAAAAAAAAAD//38/AAAAAAAAAAD//38/AAAAAAAAAAD//38/AAAAAAAAAAD//38/AAAAAAAAAAD//38/AAAAAAAAAAD//38/HnkWPwAAAAC4G08/HnkWPwAAAAC4G08/HnkWPwAAAAC4G08/HnkWPwAAAAC4G08/HnkWPwAAAAC4G08/HnkWPwAAAAC4G08/h3hzvwAAAADnNp4+h3hzvwAAAADnNp4+h3hzvwAAAADnNp4+h3hzvwAAAADnNp4+h3hzvwAAAADnNp4+h3hzvwAAAADnNp4+HnkWvwAAAAC4G08/HnkWvwAAAAC4G08/HnkWvwAAAAC4G08/HnkWvwAAAAC4G08/HnkWvwAAAAC4G08/HnkWvwAAAAC4G08/HnkWvwAAAAC4G0+/HnkWvwAAAAC4G0+/HnkWvwAAAAC4G0+/HnkWvwAAAAC4G0+/HnkWvwAAAAC4G0+/HnkWvwAAAAC4G0+/h3hzvwAAAADnNp6+h3hzvwAAAADnNp6+h3hzvwAAAADnNp6+h3hzvwAAAADnNp6+h3hzvwAAAADnNp6+h3hzvwAAAADnNp6+HnkWPwAAAAC4G0+/HnkWPwAAAAC4G0+/HnkWPwAAAAC4G0+/HnkWPwAAAAC4G0+/HnkWPwAAAAC4G0+/HnkWPwAAAAC4G0+/AAAAAAAAAAD//3+/AAAAAAAAAAD//3+/AAAAAAAAAAD//3+/AAAAAAAAAAD//3+/AAAAAAAAAAD//3+/AAAAAAAAAAD//3+/Li0wP6aWBj+Z//8+Li0wP6aWBj+Z//8+Li0wP6aWBj+Z//8+Li0wP6aWBj+Z//8+Li0wP6aWBj+Z//8+Li0wP6aWBj+Z//8+vpaGvr6WBj9jG08/vpaGvr6WBj9jG08/vpaGvr6WBj9jG08/vpaGvr6WBj9jG08/vpaGvr6WBj9jG08/vpaGvr6WBj9jG08/D8RZv6GWBj8AAACAD8RZv6GWBj8AAACAD8RZv6GWBj8AAACAD8RZv6GWBj8AAACAD8RZv6GWBj8AAACAD8RZv6GWBj8AAACAvpaGvr6WBj9jG0+/vpaGvr6WBj9jG0+/vpaGvr6WBj9jG0+/vpaGvr6WBj9jG0+/vpaGvr6WBj9jG0+/vpaGvr6WBj9jG0+/Li0wP6aWBj+Z//++Li0wP6aWBj+Z//++Li0wP6aWBj+Z//++Li0wP6aWBj+Z//++Li0wP6aWBj+Z//++Li0wP6aWBj+Z//++wFomPnzEWT9h//8+wFomPnzEWT9h//8+wFomPnzEWT9h//8+wFomPnzEWT9h//8+wFomPnzEWT9h//8+wFomPnzEWT9h//8+OpYGP0/EWT8AAACAOpYGP0/EWT8AAACAOpYGP0/EWT8AAACAOpYGP0/EWT8AAACAOpYGP0/EWT8AAACAOpYGP0/EWT8AAACA5cPZvnnEWT++Np4+5cPZvnnEWT++Np4+5cPZvnnEWT++Np4+5cPZvnnEWT++Np4+5cPZvnnEWT++Np4+5cPZvnnEWT++Np4+5cPZvnnEWT++Np6+5cPZvnnEWT++Np6+5cPZvnnEWT++Np6+5cPZvnnEWT++Np6+5cPZvnnEWT++Np6+5cPZvnnEWT++Np6+wFomPnzEWT9h//++wFomPnzEWT9h//++wFomPnzEWT9h//++wFomPnzEWT9h//++wFomPnzEWT9h//++wFomPnzEWT9h//++AbjRPUWKcb9+VaE+AbjRPUWKcb9+VaG+M6GpPrSKcb8AAAAAoDiJvo6Lcb9fYUc+oDiJvo6Lcb9fYUe++U7xPrBlKb+ARhU/+tkIPz8oqb4rIkc/b0EzPz1mKb8pOIk+knhNPyWeAL4KRxU/sK1nP+cpqb4RN4k+hljKPOoqqb5AinE/j7EdvYNkKb+bsD8/QfucvsOdAL4binE/JV3RvqJmKb824CA/aBgTv4Ypqb6asD8/tFk5v6xmKb80YUc+tFk5v6xmKb80YUe+2sJjv8wpqb5qVKE+2sJjv8wpqb5qVKG+C/l9v6qcAL4AAAAAhljKPOoqqb5AinG/j7EdvYNkKb+bsD+/QfucvsOdAL4binG/JV3RvqJmKb824CC/aBgTv4Ypqb6asD+/+U7xPrBlKb+ARhW/+tkIPz8oqb4rIke/b0EzPz1mKb8pOIm+knhNPyWeAL4KRxW/sK1nP+cpqb4RN4m+j7EdPYNkKT+bsD8/QfucPsOdAD4binE/JV3RPqJmKT824CA/aBgTP4YpqT6asD8/hljKvOoqqT5AinE/+U7xvrBlKT+ARhU/+tkIvz8oqT4rIkc/b0Ezvz1mKT8pOIk+knhNvyWeAD4KRxU/sK1nv+cpqT4RN4k++U7xvrBlKT+ARhW/+tkIvz8oqT4rIke/b0Ezvz1mKT8pOIm+knhNvyWeAD4KRxW/sK1nv+cpqT4RN4m+j7EdPYNkKT+bsD+/QfucPsOdAD4binG/JV3RPqJmKT824CC/aBgTP4YpqT6asD+/hljKvOoqqT5AinG/tFk5P6xmKT80YUc+tFk5P6xmKT80YUe+2sJjP8wpqT5qVKE+2sJjP8wpqT5qVKG+C/l9P6qcAD4AAAAAoDiJPo6LcT9fYUc+oDiJPo6LcT9fYUe+AbjRvUWKcT9+VaE+AbjRvUWKcT9+VaG+M6GpvrSKcT8AAAAAAbjRPUWKcb9+VaE+yxlAPgRxS7+cyRM/j7EdvYNkKb+bsD8/oDiJvo6Lcb9fYUc+JV3RvqJmKb824CA/YXD7vpZwS7+0rbY+AbjRPUWKcb9+VaE+yxlAPgRxS7+cyRM/M6GpPrSKcb8AAAAA+U7xPrBlKb+ARhU/jWgbP2BuS78AAAAAb0EzPz1mKb8pOIk+hljKPOoqqb5AinE/yxlAPgRxS7+cyRM/pWObPlcZQL6lJm8/+U7xPrBlKb+ARhU/+tkIPz8oqb4rIkc/j7EdvYNkKb+bsD8/jWgbP2BuS78AAAAAb0EzPz1mKb8pOIk+b0EzPz1mKb8pOIm+sK1nP+cpqb4RN4k+sK1nP+cpqb4RN4m+V3R7P2ocQL4AAAAAAbjRPUWKcb9+VaG+yxlAPgRxS7+cyRO/M6GpPrSKcb8AAAAA+U7xPrBlKb+ARhW/jWgbP2BuS78AAAAAb0EzPz1mKb8pOIm+oDiJvo6Lcb9fYUc+oDiJvo6Lcb9fYUe+YXD7vpZwS7+0rbY+YXD7vpZwS7+0rba+tFk5v6xmKb80YUc+tFk5v6xmKb80YUe+JV3RvqJmKb824CA/YXD7vpZwS7+0rbY+aBgTv4Ypqb6asD8/tFk5v6xmKb80YUc+BHFLv8sZQL6cyRM/2sJjv8wpqb5qVKE+AbjRPUWKcb9+VaG+yxlAPgRxS7+cyRO/j7EdvYNkKb+bsD+/oDiJvo6Lcb9fYUe+JV3RvqJmKb824CC/YXD7vpZwS7+0rba+JV3RvqJmKb824CC/YXD7vpZwS7+0rba+aBgTv4Ypqb6asD+/tFk5v6xmKb80YUe+BHFLv8sZQL6cyRO/2sJjv8wpqb5qVKG+hljKPOoqqb5AinG/yxlAPgRxS7+cyRO/pWObPlcZQL6lJm+/+U7xPrBlKb+ARhW/+tkIPz8oqb4rIke/j7EdvYNkKb+bsD+/BHFLP8sZQD6cyRM/knhNPyWeAL4KRxU/2sJjP8wpqT5qVKE+sK1nP+cpqb4RN4k+V3R7P2ocQL4AAAAAC/l9P6qcAD4AAAAABHFLP8sZQD6cyRO/knhNPyWeAL4KRxW/2sJjP8wpqT5qVKG+sK1nP+cpqb4RN4m+V3R7P2ocQL4AAAAAC/l9P6qcAD4AAAAAhljKPOoqqb5AinE/pWObPlcZQL6lJm8/QfucPsOdAD4binE/hljKvOoqqT5AinE/pWObvlcZQD6lJm8/QfucvsOdAL4binE/pWObPlcZQL6lJm8/QfucPsOdAD4binE/+tkIPz8oqb4rIkc/aBgTP4YpqT6asD8/BHFLP8sZQD6cyRM/knhNPyWeAL4KRxU/BHFLv8sZQL6cyRM/knhNvyWeAD4KRxU/2sJjv8wpqb5qVKE+sK1nv+cpqT4RN4k+V3R7v2ocQD4AAAAAC/l9v6qcAL4AAAAApWObvlcZQD6lJm8/QfucvsOdAL4binE/+tkIvz8oqT4rIkc/aBgTv4Ypqb6asD8/BHFLv8sZQL6cyRM/knhNvyWeAD4KRxU/pWObvlcZQD6lJm+/QfucvsOdAL4binG/+tkIvz8oqT4rIke/aBgTv4Ypqb6asD+/BHFLv8sZQL6cyRO/knhNvyWeAD4KRxW/BHFLv8sZQL6cyRO/knhNvyWeAD4KRxW/2sJjv8wpqb5qVKG+sK1nv+cpqT4RN4m+V3R7v2ocQD4AAAAAC/l9v6qcAL4AAAAApWObPlcZQL6lJm+/QfucPsOdAD4binG/+tkIPz8oqb4rIke/aBgTP4YpqT6asD+/BHFLP8sZQD6cyRO/knhNPyWeAL4KRxW/hljKPOoqqb5AinG/pWObPlcZQL6lJm+/QfucPsOdAD4binG/hljKvOoqqT5AinG/pWObvlcZQD6lJm+/QfucvsOdAL4binG/JV3RPqJmKT824CA/YXD7PpZwSz+0rbY+aBgTP4YpqT6asD8/tFk5P6xmKT80YUc+BHFLP8sZQD6cyRM/2sJjP8wpqT5qVKE+j7EdPYNkKT+bsD8/hljKvOoqqT5AinE/yxlAvgRxSz+cyRM/pWObvlcZQD6lJm8/+U7xvrBlKT+ARhU/+tkIvz8oqT4rIkc/jWgbv2BuSz8AAAAAb0Ezvz1mKT8pOIk+b0Ezvz1mKT8pOIm+sK1nv+cpqT4RN4k+sK1nv+cpqT4RN4m+V3R7v2ocQD4AAAAAj7EdPYNkKT+bsD+/hljKvOoqqT5AinG/yxlAvgRxSz+cyRO/pWObvlcZQD6lJm+/+U7xvrBlKT+ARhW/+tkIvz8oqT4rIke/JV3RPqJmKT824CC/YXD7PpZwSz+0rba+aBgTP4YpqT6asD+/tFk5P6xmKT80YUe+BHFLP8sZQD6cyRO/2sJjP8wpqT5qVKG+j7EdPYNkKT+bsD8/oDiJPo6LcT9fYUc+JV3RPqJmKT824CA/YXD7PpZwSz+0rbY+AbjRvUWKcT9+VaE+yxlAvgRxSz+cyRM/oDiJPo6LcT9fYUc+oDiJPo6LcT9fYUe+YXD7PpZwSz+0rbY+YXD7PpZwSz+0rba+tFk5P6xmKT80YUc+tFk5P6xmKT80YUe+AbjRvUWKcT9+VaE+yxlAvgRxSz+cyRM/M6GpvrSKcT8AAAAA+U7xvrBlKT+ARhU/jWgbv2BuSz8AAAAAb0Ezvz1mKT8pOIk+AbjRvUWKcT9+VaG+yxlAvgRxSz+cyRO/M6GpvrSKcT8AAAAA+U7xvrBlKT+ARhW/jWgbv2BuSz8AAAAAb0Ezvz1mKT8pOIm+j7EdPYNkKT+bsD+/oDiJPo6LcT9fYUe+JV3RPqJmKT824CC/YXD7PpZwSz+0rba+AbjRvUWKcT9+VaG+yxlAvgRxSz+cyRO/AABCADwABwBHAE8AAwA/AFoABABbAGkAAQBmAFQACQBRAHsACgBIAIQAEQBlAJIAGABuAJ8AGgB2AKoACAB5AI8ADACJAJcAEwCVAKcAFgCdALMAHACtAH8AIAC0ANQAIwC+AOEAKgDCAOkALQDGAOoAMwDPAN0A2QDrADgA2wDNAO0AzAAvAOwA7gDkADoA7wDIAOUAygAoAOcA5gDgADsA6ADAAOIAwQAlAOMA3gDWADkA3wC8ANcAugAeANIA0wDYADcA1QC1ANoAtwAyANwAgADRADUAfgCsANAAqwAwAM4AsQDHADEAsgCcAMkAngApAMsApQDEACwApgCUAMUAkwAnAMMAmAC/ACQAlgCIAL0AhwAiALsAjQC2ACEAjgB4ALgAegA0ALkAqQCwAC4AqAB0AK8AcgAUAK4AoQCjACsAoABwAKIAcQASAKQAkQCbACYAkABkAJoAYgAOAJkAhgCLAB8AhQBKAIoATAAGAIwAfQCDADYAfABTAIIAUgAdAIEAVwB1ABkAVQBnAHMAaAAVAHcAagBsABcAawBdAG0AXwAQAG8AXgBjAA8AXABBAGEAQAANAGAAUABZABsATgBGAFgARAACAFYAPgBNAAsAPQBDAEkARQAFAEsAAACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAgAFAAsAAgALAAgABgAJABUABgAVABIAFAAXABEAFAARAA4ADAAPAAMADAADAAAABwATAA0ABwANAAEAFgAKAAQAFgAEABAA" } ], "meshes": [ { "name": "Visual Mesh", "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "mode": 4 } ] }, { "name": "Nonvisual Mesh", "primitives": [ { "attributes": { "POSITION": 3 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "surface", "type": "collision" } }, "indices": 4, "mode": 4 } ] } ], "nodes": [ { "extensions": { "MAXAR_nonvisual_geometry": { "mesh": 1 } }, "mesh": 0, "name": "Icosphere" } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ValidPrimitiveExtensionPath.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Valid primitive extension with path shape and LINE_STRIP mode" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 5, "max": [ 0.0, 5.0, 0.0 ], "min": [ 0.0, 0.0, 0.0 ], "normalized": false, "type": "VEC3" } ], "bufferViews": [ { "buffer": 0, "byteLength": 60, "byteOffset": 0, "target": 34962 } ], "buffers": [ { "byteLength": 60, "uri": "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAgEAAAAAAAAAAAAAAoEAAAAAA" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "path", "type": "ladder" } }, "mode": 3 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ValidPrimitiveExtensionPoints.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Valid primitive extension with points shape and POINTS mode" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 2, "max": [ 2.0, 1.0, 1.0 ], "min": [ 1.0, 1.0, 1.0 ], "normalized": false, "type": "VEC3" } ], "bufferViews": [ { "buffer": 0, "byteLength": 24, "byteOffset": 0, "target": 34962 } ], "buffers": [ { "byteLength": 24, "uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIA/AAAAQAAAgD8AAIA/" } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "points", "type": "trigger" } }, "mode": 0 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ValidPrimitiveExtensionSurface.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Valid primitive extension with surface shape and TRIANGLES mode" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 44, "max": [ 3.7761683464050293, 0.0, 1.0 ], "min": [ -3.7761683464050293, 0.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 44, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 180, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 528, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 528, "byteOffset": 528, "target": 34962 }, { "buffer": 0, "byteLength": 360, "byteOffset": 1056, "target": 34963 } ], "buffers": [ { "byteLength": 1416, "uri": "data:application/octet-stream;base64,vqxxwAAAAAAAAIA//1ZBwAAAAAAAAIA/PwERwAAAAAAAAIA//lbBvwAAAAAAAIA//lZBvwAAAAAAAIA/AAAAAAAAAAAAAIA/AVdBPwAAAAAAAIA//lbBPwAAAAAAAIA/PwERQAAAAAAAAIA/AFdBQAAAAAAAAIA/vqxxQAAAAAAAAIA/vqxxwAAAAACqqqo+/1ZBwAAAAACqqqo+PwERwAAAAACqqqo+/lbBvwAAAACqqqo+/lZBvwAAAACqqqo+AAAAAAAAAACqqqo+AVdBPwAAAACqqqo+/lbBPwAAAACqqqo+PwERQAAAAACqqqo+AFdBQAAAAACqqqo+vqxxQAAAAACqqqo+vqxxwAAAAACsqqq+/1ZBwAAAAACsqqq+PwERwAAAAACsqqq+/lbBvwAAAACsqqq+/lZBvwAAAACsqqq+AAAAAAAAAACsqqq+AVdBPwAAAACsqqq+/lbBPwAAAACsqqq+PwERQAAAAACsqqq+AFdBQAAAAACsqqq+vqxxQAAAAACsqqq+vqxxwAAAAAAAAIC//1ZBwAAAAAAAAIC/PwERwAAAAAAAAIC//lbBvwAAAAAAAIC//lZBvwAAAAAAAIC/AAAAAAAAAAAAAIC/AVdBPwAAAAAAAIC//lbBPwAAAAAAAIC/PwERQAAAAAAAAIC/AFdBQAAAAAAAAIC/vqxxQAAAAAAAAIC/AAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAABAAwAAAAMAAsAAQACAA0AAQANAAwAAgADAA4AAgAOAA0AAwAEAA8AAwAPAA4ABAAFABAABAAQAA8ABQAGABEABQARABAABgAHABIABgASABEABwAIABMABwATABIACAAJABQACAAUABMACQAKABUACQAVABQACwAMABcACwAXABYADAANABgADAAYABcADQAOABkADQAZABgADgAPABoADgAaABkADwAQABsADwAbABoAEAARABwAEAAcABsAEQASAB0AEQAdABwAEgATAB4AEgAeAB0AEwAUAB8AEwAfAB4AFAAVACAAFAAgAB8AFgAXACIAFgAiACEAFwAYACMAFwAjACIAGAAZACQAGAAkACMAGQAaACUAGQAlACQAGgAbACYAGgAmACUAGwAcACcAGwAnACYAHAAdACgAHAAoACcAHQAeACkAHQApACgAHgAfACoAHgAqACkAHwAgACsAHwArACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "surface", "type": "roadway" } }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/maxarNonvisualGeometry/ValidPrimitiveExtensionVolume.gltf ================================================ { "asset": { "version": "2.0" }, "extras": { "info": { "note": "Valid primitive extension with volume shape and TRIANGLES mode" } }, "extensionsUsed": [ "MAXAR_nonvisual_geometry" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5126, "count": 48, "max": [ 1.0, 1.0, 1.0 ], "min": [ -1.0, -1.0, -1.0 ], "normalized": false, "type": "VEC3" }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 48, "normalized": false, "type": "VEC3" }, { "bufferView": 2, "byteOffset": 0, "componentType": 5123, "count": 84, "normalized": false, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteLength": 576, "byteOffset": 0, "target": 34962 }, { "buffer": 0, "byteLength": 576, "byteOffset": 576, "target": 34962 }, { "buffer": 0, "byteLength": 168, "byteOffset": 1152, "target": 34963 } ], "buffers": [ { "byteLength": 1320, "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgL8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/AAAAAAAAgD8AAIC/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgL/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/8wQ1PwAAgD/zBDW/AACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgL8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACAAACAPwAAgD8AAACA8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgL/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/8wQ1PwAAgD/zBDU/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIA/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgL/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/8wQ1vwAAgD/zBDU/AACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgL8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACAAACAvwAAgD8AAACA8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgL/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/8wQ1vwAAgD/zBDW/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y//O/DvgAAAAAug2y/AAAAAAAAgL8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2y/LoNsPwAAAAD878O+AAAAAAAAgL8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgD8AAAAALoNsPwAAAAD878M+LoNsPwAAAAD878O+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w/LoNsPwAAAAD878M+AAAAAAAAgL8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgD8AAAAA/O/DPgAAAAAug2w//O/DvgAAAAAug2w/AAAAAAAAgL8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2w/LoNsvwAAAAD878M+AAAAAAAAgL8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgD8AAAAALoNsvwAAAAD878M+LoNsvwAAAAD878O+AAAAAAAAgL8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AAAAAAAAgD8AAAAA/O/DvgAAAAAug2y/LoNsvwAAAAD878O+AQAEAAoAAQAKAAcACAALABEACAARAA4ADQAQABcADQAXABQAEwAWABwAEwAcABkAGgAdACIAGgAiAB8AIAAjACgAIAAoACUADwAJAAMAAwAtACcAJwAhABsAGwAVAA8ADwADACcAJwAbAA8AJgApAC8AJgAvACwAKwAuAAUAKwAFAAIAKgAAAAYABgAMABIAEgAYAB4AHgAkACoAKgAGABIAEgAeACoA" } ], "meshes": [ { "primitives": [ { "attributes": { "NORMAL": 1, "POSITION": 0 }, "extensions": { "MAXAR_nonvisual_geometry": { "shape": "volume", "type": "collision" } }, "indices": 2, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeAccessorNormalized.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ], "normalized": true } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeAccessorNotScalar.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 2 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeAttributeInvalidType.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : "NOT_A_NUMBER" } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeAttributeInvalidValue.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 12345 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountInvalidType.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : "NOT_AN_INTEGER", "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountInvalidValue.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : -12345, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountMismatch.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 1, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountMismatchForNullFeatureId.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 2, "attribute" : 0, "nullFeatureId": 1 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountMissing.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeLabelInvalidType.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "label": 12345, "featureCount" : 4, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeLabelInvalidValue.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "label": "NOT:A:VALID/IDENTIFIER", "featureCount" : 4, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeNullFeatureIdInvalidType.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "nullFeatureId": "NOT_A_NUMBER", "featureCount" : 4, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeNullFeatureIdInvalidValue.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "nullFeatureId": -12345, "featureCount" : 4, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureFeatureCountMismatch.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 1, "texture" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureSamplerInvalidFilterMode.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9729, "minFilter" : 9729 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureChannelsInvalidElementType.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 0, "channels" : [0, "NOT_A_NUMBER"] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureChannelsInvalidType.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 0, "channels" : "NOT_AN_ARRAY" } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureChannelsTooManyChannels.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 0, "channels" : [0, 4, 1] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureChannelsTooManyElements.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 0, "channels" : [0, 1, 0, 1, 0, 1] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureImageDataInvalid.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,THIS_IS_NOT_VALID_IMAGE_DATA________________________________________________________________________________________________", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureIndexInvalidType.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : "NOT_A_NUMBER", "texCoord" : 0, "channels" : [ 0 ] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureIndexInvalidValue.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 12345, "texCoord" : 0, "channels" : [ 0 ] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureInvalidType.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : "NOT_AN_OBJECT" } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureTexCoordInvalidType.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : "NOT_A_NUMBER", "channels" : [ 0 ] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureTexCoordInvalidValue.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 12345, "channels" : [ 0 ] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/README.md ================================================ The files in this directory are used for the specs for the `EXT_mesh_features` validation. The valid files have been taken from https://github.com/CesiumGS/3d-tiles-samples/tree/a256d9f68df15bbfc75ea3891f52c72a36d04202/glTF/EXT_mesh_features The `ValidFeatureIdTexture.glb` and `ValidFeatureIdAttributeDefault/` are intended for basic tests of binary- and default (non-embedded) glTF assets. The `ValidFeatureIdAttributeWithByteStride.glb` was created from the original `ValidFeatureIdAttribute.gltf` by reading it with glTF-Transform and writing it as binary glTF, which happens to write all attributes in an interleaved way, causing a byte stride to be inserted. The other files (starting with `FeatureIdTexture*` or `FeatureIdAttribute*`) have been edited to cause validation errors (with the error indicated by their file name, as far as reasonably possible). ================================================ FILE: specs/data/gltfExtensions/meshFeatures/ValidFeatureIdAttribute.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/ValidFeatureIdAttributeDefault/ValidFeatureIdAttributeDefault.gltf ================================================ { "extensionsUsed": [ "EXT_mesh_features" ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "componentType": 5123, "count": 24, "type": "SCALAR", "max": [ 15 ], "min": [ 0 ] }, { "bufferView": 1, "byteOffset": 0, "componentType": 5126, "count": 16, "type": "VEC3", "max": [ 1, 1, 0 ], "min": [ 0, 0, 0 ] }, { "bufferView": 2, "byteOffset": 0, "componentType": 5126, "count": 16, "type": "VEC3", "max": [ 0, 0, 1 ], "min": [ 0, 0, 1 ] }, { "bufferView": 3, "byteOffset": 0, "componentType": 5121, "count": 16, "type": "SCALAR", "max": [ 3 ], "min": [ 0 ] } ], "asset": { "generator": "JglTF from https://github.com/javagl/JglTF", "version": "2.0" }, "buffers": [ { "uri": "ValidFeatureIdAttributeDefault_data.bin", "byteLength": 496 } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 48, "target": 34963 }, { "buffer": 0, "byteOffset": 48, "byteLength": 192, "target": 34962 }, { "buffer": 0, "byteOffset": 240, "byteLength": 192, "target": 34962 }, { "buffer": 0, "byteOffset": 432, "byteLength": 64, "byteStride": 4, "target": 34962 } ], "materials": [ { "pbrMetallicRoughness": { "baseColorFactor": [ 0.5, 1, 0.5, 1 ], "metallicFactor": 0, "roughnessFactor": 1 }, "alphaMode": "OPAQUE", "doubleSided": true } ], "meshes": [ { "primitives": [ { "extensions": { "EXT_mesh_features": { "featureIds": [ { "featureCount": 4, "attribute": 0 } ] } }, "attributes": { "POSITION": 1, "NORMAL": 2, "_FEATURE_ID_0": 3 }, "indices": 0, "material": 0, "mode": 4 } ] } ], "nodes": [ { "mesh": 0 } ], "scene": 0, "scenes": [ { "nodes": [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/ValidFeatureIdAttributeWithLargerFeatureCount.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 123, "attribute" : 0 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/ValidFeatureIdAttributeWithNullFeatureId.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==", "byteLength" : 496 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 3, "attribute" : 0, "nullFeatureId": 2 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/ValidFeatureIdTexture.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/meshFeatures/ValidFeatureIdTextureUsingDefaultChannels.gltf ================================================ { "extensionsUsed" : [ "EXT_mesh_features" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAJElEQVR42mNgYmBgoAQzDLwBgwcwY8FDzIDBDRiR8KgBNDAAAOKBAKByX2jMAAAAAElFTkSuQmCC", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "texture" : { "index" : 1, "texCoord" : 0 } } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/ExtensionInMeshPrimitiveWithoutTopLevelObject.gltf ================================================ { "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyArray.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32", "array": true }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyInvalidComponentType.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType": "FLOAT64" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyInvalidEnumValueType.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType": "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "valueType": "INT64", "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyMaxNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32", "max": 0.7 }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } }, { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyMinNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32", "min": 0.3 }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } }, { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyString.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "STRING" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesMeshPrimitivePropertyAttributesInvalidElementType.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0, "NOT_A_NUMBER" ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesMeshPrimitivePropertyAttributesInvalidElementValue.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0, 12345 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesMeshPrimitivePropertyAttributesInvalidLength.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesMeshPrimitivePropertyAttributesInvalidType.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : "NOT_A_NUMBER" } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyInvalidAttribute.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "THIS_ATTRIBUTE_DOES_NOT_EXIST" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyMaxMismatch.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY", "max": 0.3 }, "classification" : { "attribute" : "_CLASSIFICATION" } } }, { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyMaxNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY", "max": 0.2 }, "classification" : { "attribute" : "_CLASSIFICATION" } } }, { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyMinMismatch.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY", "min": 0.2 }, "classification" : { "attribute" : "_CLASSIFICATION" } } }, { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyMinNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY", "min": 0.3 }, "classification" : { "attribute" : "_CLASSIFICATION" } } }, { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 1 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureClassPropertyMaxNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8", "max": 23 }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureClassPropertyMinNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8", "min": 14 }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureClassPropertyWithOffsetScaleMinNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true, "offset": 100.0, "scale": 1000.0, "min": 151 } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureEnumsInvalidEnumValue.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "PropertyTextureEnumsSchemaId", "classes" : { "propertyTextureEnumsClass" : { "name" : "Property texture example enum properties", "properties" : { "enumProperty" : { "name" : "Example enum property", "type" : "ENUM", "enumType" : "exampleEnum", "noData" : "NO_DATA_ENUM_VALUE", "default" : "DEFAULT_ENUM_VALUE" }, "enumArrayProperty" : { "name" : "Example enum array property", "type" : "ENUM", "enumType" : "exampleEnum", "array" : true, "count" : 2, "noData" : [ "NO_DATA_ENUM_VALUE", "NO_DATA_ENUM_VALUE" ], "default" : [ "DEFAULT_ENUM_VALUE", "DEFAULT_ENUM_VALUE" ] } } } }, "enums" : { "exampleEnum" : { "valueType": "UINT8", "values" : [ { "name" : "NO_DATA_ENUM_VALUE", "value" : 255 }, { "name" : "EXAMPLE_ENUM_VALUE_A", "value" : 0 }, { "name" : "EXAMPLE_ENUM_VALUE_B", "value" : 1 }, { "name" : "EXAMPLE_ENUM_VALUE_C", "value" : 2 }, { "name" : "DEFAULT_ENUM_VALUE", "value" : 3 } ] } } }, "propertyTextures" : [ { "class" : "propertyTextureEnumsClass", "properties" : { "enumProperty" : { "index" : 0, "texCoord" : 0, "channels" : [ 0 ] }, "enumArrayProperty" : { "index" : 0, "texCoord" : 0, "channels" : [ 1, 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAGUlEQVR42mP4/5/hPwMTAwNDSgpDCpBmAgA21QQw4gn1GgAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 0.5, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureInvalidPropertyTypeA.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "STRING" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureInvalidPropertyTypeB.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8", "array": true }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTextureTexCoordInvalidValue.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 12345, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTexturesInvalidElementType.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [0, "NOT_A_NUMBER"] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTexturesInvalidElementValue.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [0, 12345] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTexturesInvalidLength.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTexturesInvalidType.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : "NOT_AN_ARRAY" } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyChannelsSizeMismatch.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT16", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyIndexInvalidType.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : "NOT_A_NUMBER", "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyIndexInvalidValue.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 12345, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexCoordDefault.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexCoordInvalidValue.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord": 12345, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexturePropertyMaxMismatch.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ], "max": 29 }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexturePropertyMaxNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ], "max": 23 }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexturePropertyMinMismatch.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ], "min": 9 }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexturePropertyMinNotInRange.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ], "min": 14 }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/README.md ================================================ The files in this directory are used for the specs for the `EXT_structural_metadata` validation. The valid files have been taken from https://github.com/CesiumGS/3d-tiles-samples/tree/a256d9f68df15bbfc75ea3891f52c72a36d04202/glTF/EXT_structural_metadata except for the following ones, which have been created dedicatedly for these tests: - `ValidPropertyAttributes.gltf` - `ValidPropertyTextureEnums.gltf` The files that cause issues have been created by modifying these files This mostly happened manually, with the exception of certain invalid values in property textures, that have been written out in this form by the generator. Note that some parts of the validation specs are not covered here, because they are covered by the main 3D Tiles Validator specs. Particularly: - Validation of the metadata schema is covered with `./specs/data/schemas/` - Validation of the property tables is covered with `./specs/data/subtrees/subtreePropertyTables*.json` ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/StructuralMetadataMissingSchema.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "propertyTables" : [ { "name" : "First example property table", "class" : "exampleMetadataClassA", "count" : 4, "properties" : { "example_FLOAT32" : { "values" : 5 }, "example_INT64" : { "values" : 6 } } }, { "name" : "Second example property table", "class" : "exampleMetadataClassB", "count" : 4, "properties" : { "example_UINT16" : { "values" : 7 }, "example_FLOAT64" : { "values" : 8 } } } ] } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AwAAAAMAAAADAAAAAwAAAAIAAAACAAAAAgAAAAIAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAACAAAAAgAAAAIAAAACAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA=", "byteLength" : 560 }, { "uri" : "data:application/gltf-buffer;base64,zcyMP83MDEAzM1NAzcyMQIfWEgAAAAAAzsojAAAAAAAVvzQAAAAAAFKzRQAAAAAA", "byteLength" : 48 }, { "uri" : "data:application/gltf-buffer;base64,OTCgWweHbrKHiJtTycDzP9GSx9PywwJAX2HB/YCnC0Da5sb0hEUSQA==", "byteLength" : 40 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 496, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 16 }, { "buffer" : 1, "byteOffset" : 16, "byteLength" : 32 }, { "buffer" : 2, "byteOffset" : 0, "byteLength" : 8 }, { "buffer" : 2, "byteOffset" : 8, "byteLength" : 32 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0, "propertyTable" : 0 }, { "featureCount" : 4, "attribute" : 1, "propertyTable" : 1 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3, "_FEATURE_ID_1" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/StructuralMetadataSchemaAndSchemaUri.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schemaUri": "uriToCreateValidationError.json", "schema" : { "id": "MultipleClassesSchema", "classes" : { "exampleMetadataClassA" : { "name" : "Example metadata class A", "description" : "First example metadata class", "properties" : { "example_FLOAT32" : { "name" : "Example FLOAT32 property", "description" : "An example property, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "example_INT64" : { "name" : "Example INT64 property", "description" : "An example property, with component type INT64", "type" : "SCALAR", "componentType" : "INT64" } } }, "exampleMetadataClassB" : { "name" : "Example metadata class B", "description" : "Second example metadata class", "properties" : { "example_UINT16" : { "name" : "Example UINT16 property", "description" : "An example property, with component type UINT16", "type" : "SCALAR", "componentType" : "UINT16" }, "example_FLOAT64" : { "name" : "Example FLOAT64 property", "description" : "An example property, with component type FLOAT64", "type" : "SCALAR", "componentType" : "FLOAT64" } } } }, "enums" : { "exampleEnumType" : { "values" : [ { "name" : "ExampleEnumValueA", "value" : 0 }, { "name" : "ExampleEnumValueB", "value" : 1 }, { "name" : "ExampleEnumValueC", "value" : 2 } ] } } }, "propertyTables" : [ { "name" : "First example property table", "class" : "exampleMetadataClassA", "count" : 4, "properties" : { "example_FLOAT32" : { "values" : 5 }, "example_INT64" : { "values" : 6 } } }, { "name" : "Second example property table", "class" : "exampleMetadataClassB", "count" : 4, "properties" : { "example_UINT16" : { "values" : 7 }, "example_FLOAT64" : { "values" : 8 } } } ] } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AwAAAAMAAAADAAAAAwAAAAIAAAACAAAAAgAAAAIAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAACAAAAAgAAAAIAAAACAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA=", "byteLength" : 560 }, { "uri" : "data:application/gltf-buffer;base64,zcyMP83MDEAzM1NAzcyMQIfWEgAAAAAAzsojAAAAAAAVvzQAAAAAAFKzRQAAAAAA", "byteLength" : 48 }, { "uri" : "data:application/gltf-buffer;base64,OTCgWweHbrKHiJtTycDzP9GSx9PywwJAX2HB/YCnC0Da5sb0hEUSQA==", "byteLength" : 40 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 496, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 16 }, { "buffer" : 1, "byteOffset" : 16, "byteLength" : 32 }, { "buffer" : 2, "byteOffset" : 0, "byteLength" : 8 }, { "buffer" : 2, "byteOffset" : 8, "byteLength" : 32 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0, "propertyTable" : 0 }, { "featureCount" : 4, "attribute" : 1, "propertyTable" : 1 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3, "_FEATURE_ID_1" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/ValidMultipleClasses.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "MultipleClassesSchema", "classes" : { "exampleMetadataClassA" : { "name" : "Example metadata class A", "description" : "First example metadata class", "properties" : { "example_FLOAT32" : { "name" : "Example FLOAT32 property", "description" : "An example property, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "example_INT64" : { "name" : "Example INT64 property", "description" : "An example property, with component type INT64", "type" : "SCALAR", "componentType" : "INT64" } } }, "exampleMetadataClassB" : { "name" : "Example metadata class B", "description" : "Second example metadata class", "properties" : { "example_UINT16" : { "name" : "Example UINT16 property", "description" : "An example property, with component type UINT16", "type" : "SCALAR", "componentType" : "UINT16" }, "example_FLOAT64" : { "name" : "Example FLOAT64 property", "description" : "An example property, with component type FLOAT64", "type" : "SCALAR", "componentType" : "FLOAT64" } } } }, "enums" : { "exampleEnumType" : { "values" : [ { "name" : "ExampleEnumValueA", "value" : 0 }, { "name" : "ExampleEnumValueB", "value" : 1 }, { "name" : "ExampleEnumValueC", "value" : 2 } ] } } }, "propertyTables" : [ { "name" : "First example property table", "class" : "exampleMetadataClassA", "count" : 4, "properties" : { "example_FLOAT32" : { "values" : 5 }, "example_INT64" : { "values" : 6 } } }, { "name" : "Second example property table", "class" : "exampleMetadataClassB", "count" : 4, "properties" : { "example_UINT16" : { "values" : 7 }, "example_FLOAT64" : { "values" : 8 } } } ] } }, "extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 24, "type" : "SCALAR", "max" : [ 15 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 16, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5121, "count" : 16, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AwAAAAMAAAADAAAAAwAAAAIAAAACAAAAAgAAAAIAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAACAAAAAgAAAAIAAAACAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA=", "byteLength" : 560 }, { "uri" : "data:application/gltf-buffer;base64,zcyMP83MDEAzM1NAzcyMQIfWEgAAAAAAzsojAAAAAAAVvzQAAAAAAFKzRQAAAAAA", "byteLength" : 48 }, { "uri" : "data:application/gltf-buffer;base64,OTCgWweHbrKHiJtTycDzP9GSx9PywwJAX2HB/YCnC0Da5sb0hEUSQA==", "byteLength" : 40 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 48, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 48, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 240, "byteLength" : 192, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 432, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 496, "byteLength" : 64, "byteStride" : 4, "target" : 34962 }, { "buffer" : 1, "byteOffset" : 0, "byteLength" : 16 }, { "buffer" : 1, "byteOffset" : 16, "byteLength" : 32 }, { "buffer" : 2, "byteOffset" : 0, "byteLength" : 8 }, { "buffer" : 2, "byteOffset" : 8, "byteLength" : 32 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_mesh_features" : { "featureIds" : [ { "featureCount" : 4, "attribute" : 0, "propertyTable" : 0 }, { "featureCount" : 4, "attribute" : 1, "propertyTable" : 1 } ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_FEATURE_ID_0" : 3, "_FEATURE_ID_1" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/ValidPropertyAttributes.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyAttributeSchema", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", "description" : "An example metadata class for property attributes", "properties" : { "intensity" : { "name" : "Example intensity property", "description" : "An example property for the intensity, with component type FLOAT32", "type" : "SCALAR", "componentType" : "FLOAT32" }, "classification" : { "name" : "Example classification property", "description" : "An example property for the classification, with the classificationEnumType", "type" : "ENUM", "enumType" : "classificationEnumType" } } } }, "enums" : { "classificationEnumType" : { "values" : [ { "name" : "ExampleClassificationA", "value" : 0 }, { "name" : "ExampleClassificationB", "value" : 1 }, { "name" : "ExampleClassificationC", "value" : 2 } ] } } }, "propertyAttributes" : [ { "class" : "exampleMetadataClass", "properties" : { "intensity" : { "attribute" : "_INTENSITY" }, "classification" : { "attribute" : "_CLASSIFICATION" } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 1.0, 0.0 ], "min" : [ -1.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.25 ], "min" : [ 0.25 ] }, { "bufferView" : 4, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 0 ], "min" : [ 0 ] }, { "bufferView" : 5, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 6, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 7, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 8, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.5 ], "min" : [ 0.5 ] }, { "bufferView" : 9, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 1 ], "min" : [ 1 ] }, { "bufferView" : 10, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 11, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 2.0, 1.0, 0.0 ], "min" : [ 1.0, 0.0, 0.0 ] }, { "bufferView" : 12, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 13, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "SCALAR", "max" : [ 0.75 ], "min" : [ 0.75 ] }, { "bufferView" : 14, "byteOffset" : 0, "componentType" : 5123, "count" : 4, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 2 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAACAvwAAAAAAAAAAAAAAAAAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPgAAgD4AAIA+AACAPgAAAAAAAAAAAAAAAAAAAAAAAAEAAgABAAMAAgAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAA/AAAAPwAAAD8AAAA/AQAAAAEAAAABAAAAAQAAAAAAAQACAAEAAwACAAAAgD8AAAAAAAAAAAAAAEAAAAAAAAAAAAAAgD8AAIA/AAAAAAAAAEAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAQD8AAEA/AABAPwAAQD8CAAAAAgAAAAIAAAACAAAA", "byteLength" : 420 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 124, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 140, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 152, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 200, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 248, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 264, "byteLength" : 16, "byteStride" : 4, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 280, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 292, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 340, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 388, "byteLength" : 16, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 404, "byteLength" : 16, "byteStride" : 4, "target" : 34962 } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "_INTENSITY" : 3, "_CLASSIFICATION" : 4 }, "indices" : 0, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 6, "NORMAL" : 7, "_INTENSITY" : 8, "_CLASSIFICATION" : 9 }, "indices" : 5, "material" : 0, "mode" : 4 }, { "extensions" : { "EXT_structural_metadata" : { "propertyAttributes" : [ 0 ] } }, "attributes" : { "POSITION" : 11, "NORMAL" : 12, "_INTENSITY" : 13, "_CLASSIFICATION" : 14 }, "indices" : 10, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/ValidPropertyTexture.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "SimplePropertyTextureSchema", "classes" : { "buildingComponents" : { "name" : "Building properties", "properties" : { "insideTemperature" : { "name" : "Inside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "outsideTemperature" : { "name" : "Outside Temperature", "type" : "SCALAR", "componentType" : "UINT8" }, "insulation" : { "name" : "Insulation Thickness", "type" : "SCALAR", "componentType" : "UINT8", "normalized" : true } } } } }, "propertyTextures" : [ { "class" : "buildingComponents", "properties" : { "insideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 0 ] }, "outsideTemperature" : { "index" : 1, "texCoord" : 0, "channels" : [ 1 ] }, "insulation" : { "index" : 1, "texCoord" : 0, "channels" : [ 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAIvklEQVR42u3csW5URxsG4BHBRRoklxROEQlSRCJCKShoXFJZiDSpQEqX2pYii8ZVlDZF7oNcAAURDREdpCEXQKoIlAKFEE3O4s0KoV17zxm8Z+Z8j6zvj6Nfj7Q663k968y8aXd3NxtjYk6a/U9OafDwPN+uFwA8LwA8QJ4XAO/Mw26+6Garm6vd/NbzBfA8X79fGQCXuvll/v1P3XzZ8wXwPF+/X+sjwL/zJBm6BeF5vk6/VgC8nG8nhr4Anufr9GsFwA/d/FzwAnier9OfGgC/d/NdwV8heZ6v158YAH908203/wx8ATzP1+1XBsDsL4hfdfNq4H+H5Hm+fr8yAD6Z/Z/vTZ8XwPN8/d5JQJ53EtAD5HkB4AHyfLwAMMboA5CgPO8jgAfI8wLAA+R5fQDuU/O8PgD3qXleH4D71DyvD8B9ap7XB+A+Nc/rA+B5Xh8Az/P6AHie1wfA87w+AJ7nHQXmeV4A8DyvD8AYow+A53kfAXieFwA8z+sD4HleHwDP8/oAeJ7XB8DzvD4Anuf1AfA8rw+A53l9ADzP6wPgeV4fAM/zjgLzPC8AeJ7XB2CMOaEPIBV88TzfrhcAPC8APECeFwDvfj3p5lI3W91c7eZhzxfA83z1fnUA3O7mx/n333fzdc8XwPN89X51AHzazd/z7//s5vOeL4Dn+er96gD4+JR/P+0F8DxfvV8dAOm9f9/q+QJ4nq/e2wHwvB3Akq/Punk5//6v+V8U+7wAnuer96sD4Jv5Xw///yvi7Z4vgOf56v3qAPh1/pfEj+bp8aTnC+B5vnrvJCDPOwnoAfK8APAAeT5eABhj9AFIUJ73EcAD5HkB4AHyfOAAcJ+a5/UBLE4SuU/N85Pz+gB4PrB3G5DnA3t9ADwf2NsB8LwdwJIv96l5fvJeHwDPB/b6AHg+sHcSkOedBPQAeV4AeIA8Hy8AjDH6AMZLsJQHD+83IN/6RwABIAB4ASAABABfSwBs8j7zkh/sK1dyfvw459evc370KOfLl/stoFB+7PePb9bX0Qew5Af76dOcb906/v7OnePF0GcBhfJjv398s76OPoA1trqz34QlW+hJ+7HfP75ZX8dtwBN+8M+dy/nu3Zzv3Ru2gEL4sd8/vllfRx/Aih/+8+dzfvEi5zdvcr55s/8CCuPHfv/4Zn31O4DZ3LiR8/Pnw7fQk/d+A/IffAewyfvM/gbw4f8G4D4830wfwJIf7GfPjv9T2Oz769dzvn+/3wIK5cd+//hmfR19AEt+sK9dO/5PYbPffA8e5HzxYr8FFMqP/f7xzXonAZ0E5J0EFAACgBcAAkAA8PECwBijD8AOwA6A9xFAAAgAXgAIAAHABw4AfQD6AHh9AGkT95n1AegD4Efx+gD0AfCBvT4AfQC824Bp3PvM+gD0AfCjeH0A+gB4O4A07n1mfwPQB8CP4vUB6APgA3t9APoA+MDeSUAnAXknAQWAAOAFgAAQAHy8ADDG6AOwA7AD4H0EEAACgBcAAkAA8IEDQB+APgBeH0DaxH1mfQD6APhRvD4AfQB8YK8PQB8A7zZgGvc+sz4AfQD8KF4fgD4A3g4gjXuf2d8A9AHwo3h9APoA+MBeH4A+AD6wdxLQSUDeSUABIAB4ASAABAAfLwCMMfoAJCjP+wjgAfK8APAAeT5wALhPzfP6ABYnidyn5vnJ+eQ+Nc/H9cltKp6P65P71Dwf19sB8LwdwJIv96l5fvI+uU/N83F9cp+a5+N6JwF53klAD5DnBYAHyPPxAsAYow9AgvK8jwAeIM8LAA+Q5wMHgPvUPK8PYHGSyH1qnp+c1wfA84G924A8H9jrA+D5wN4OgOftAJZ8uU/N85P3+gB4PrDXB8Dzgb2TgDzvJKAHyPMCwAPk+XgBYIzRByBB+UH+6Oho8NTgfQSwAHgBIAAsAF4ACIDjL/ep+TX9qsV1eHiYt7e3By/gTfnI758+AL7YL1tYBwcHeWdn5+2llCELeJM+8vunD4Av9ssW1oULF/Le3t7gBbxJH/n9cxuQL/bLFtb+/v7bfw5dwJv0kd8/fQB8sT9pgQ1dwJv0kd8/OwD+THYAzQeAPoDkPjW/lp9kAOgDSO5T82v5SQaAPoDkPjW/lp9kAOgDcBKOdxLQUWALgBcAAsAC4AXARAPAGKMPwG9A3g7ARwALgBcAAsAC4AVA4ABwH57XB6APYHGSyH14vkcA6ANI+gD4GF4fQLvebUC+2OsDaNfrA+CLvT6Adr0dAH8mOwB9AK3vANyH5/UBTP790wfAF3t9AO16fQB8sdcH0K53EpB3EtBJQAuAFwACwALgBUC8ADDG6APwG5C3A/ARwALgBYAAsAB4ARA4ANyH5/UB6ANYnCRyH57vEQD6AJI+AD6G1wfQrncbkC/2+gDa9foA+GKvD6BdbwfAn8kOQB9A6zsA9+F5fQCTf//0AfDFXh9Au14fAF/s9QG0650E5J0EdBLQAuAFgACwAHgBEC8AjDH6APwG5O0AfASwAHgBIAAsAF4ABA4A9+F5fQD6ABYnidyH53sEgD6ApA+Aj+H1AbTr3Qbki70+gHa9PgC+2OsDaNfbAfBnsgPQB9D6DsB9eF4fwOTfP30AfLHXB9Cu1wfAF3t9AO16JwF5JwGdBLQAeAEgACwAXgDECwBjjD4AvwF5OwAfASwAXgAIAAuAFwCBA8B9eF4fgD6AxUki9+H5HgGgDyDpA+BjeH0A7Xq3Aflirw+gXa8PgC/2+gDa9XYA/JnsAPQBtL4DcB+e1wcw+fdPHwBf7PUBtOv1AfDFXh9Au95JQN5JQCcBLQBeAAgAC4AXAPECwBijD8BvQN4OwEcAC4AXAALAAuAFQOAAcB+e1wegD2Bxksh9eL5HAOgDSPoA+BheH0C73m1AvtjrA2jX6wPgi70+gHa9HQB/JjsAfQCt7wDch+f1AUz+/dMHwBd7fQDten0AfLHXB9CudxKQdxLQSUALgBcAAsAC4AVAqPfvPyVxz6xUBN7bAAAAAElFTkSuQmCC", "mimeType" : "image/png" }, { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABLUlEQVR42mVSSxbDIAh0GzUxKZrmCF3n/oerIx9pupgHIswAGtblE7bIKN0vqSOyXSOjPLAtktv9sCFxmcXj7EgsFj8zN00yYxrBZZJBRYk2LdC4WCDUfAdab7bpDm1lCyBW+7lpDnyNS34gcTQRltTPbAeEdFjcSQ0X9EOhGPYjhgLA7xh3kjxEEpMj1qQj7iAzAYoPELzYtuwK02M06WywAFDfX1MdJEoOtSZ7Allz1mYmWZDNL0pNF6ezu9jsQJUcNK7qzbWvMdSYQ8Jo7KKK8/uo4dxreHe0/HgF2/IqBen/za+Di69Sf8cZz5jmk+hcuhdd2tWLz8IE5MbFnRWT+yyU5vZJRtAOqlvq6MDeOrstu0UidsoO0Ak9xGwE+67+34salNEBSCxX7Bexg0rbq6TFvwAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 1.0, 1.0, 1.0, 1.0 ], "baseColorTexture" : { "index" : 0, "texCoord" : 0 }, "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 }, { "sampler" : 0, "source" : 1 } ] } ================================================ FILE: specs/data/gltfExtensions/structuralMetadata/ValidPropertyTextureEnums.gltf ================================================ { "extensions" : { "EXT_structural_metadata" : { "schema" : { "id": "PropertyTextureEnumsSchemaId", "classes" : { "propertyTextureEnumsClass" : { "name" : "Property texture example enum properties", "properties" : { "enumProperty" : { "name" : "Example enum property", "type" : "ENUM", "enumType" : "exampleEnum", "noData" : "NO_DATA_ENUM_VALUE", "default" : "DEFAULT_ENUM_VALUE" }, "enumArrayProperty" : { "name" : "Example enum array property", "type" : "ENUM", "enumType" : "exampleEnum", "array" : true, "count" : 2, "noData" : [ "NO_DATA_ENUM_VALUE", "NO_DATA_ENUM_VALUE" ], "default" : [ "DEFAULT_ENUM_VALUE", "DEFAULT_ENUM_VALUE" ] } } } }, "enums" : { "exampleEnum" : { "valueType": "UINT8", "values" : [ { "name" : "NO_DATA_ENUM_VALUE", "value" : 255 }, { "name" : "EXAMPLE_ENUM_VALUE_A", "value" : 0 }, { "name" : "EXAMPLE_ENUM_VALUE_B", "value" : 1 }, { "name" : "EXAMPLE_ENUM_VALUE_C", "value" : 2 }, { "name" : "DEFAULT_ENUM_VALUE", "value" : 3 } ] } } }, "propertyTextures" : [ { "class" : "propertyTextureEnumsClass", "properties" : { "enumProperty" : { "index" : 0, "texCoord" : 0, "channels" : [ 0 ] }, "enumArrayProperty" : { "index" : 0, "texCoord" : 0, "channels" : [ 1, 2 ] } } } ] } }, "extensionsUsed" : [ "EXT_structural_metadata" ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 6, "type" : "SCALAR", "max" : [ 3 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] }, { "bufferView" : 2, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC3", "max" : [ 0.0, 0.0, 1.0 ], "min" : [ 0.0, 0.0, 1.0 ] }, { "bufferView" : 3, "byteOffset" : 0, "componentType" : 5126, "count" : 4, "type" : "VEC2", "max" : [ 1.0, 1.0 ], "min" : [ 0.0, 0.0 ] } ], "asset" : { "generator" : "JglTF from https://github.com/javagl/JglTF", "version" : "2.0" }, "buffers" : [ { "uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 140 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 12, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 12, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 60, "byteLength" : 48, "target" : 34962 }, { "buffer" : 0, "byteOffset" : 108, "byteLength" : 32, "target" : 34962 } ], "images" : [ { "uri" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAGUlEQVR42mP4/5/hPwMTAwMDIyMDI5BmAgAvGQMH5R702wAAAABJRU5ErkJggg==", "mimeType" : "image/png" } ], "materials" : [ { "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.5, 0.5, 0.5, 1.0 ], "metallicFactor" : 0.0, "roughnessFactor" : 1.0 }, "alphaMode" : "OPAQUE", "doubleSided" : true } ], "meshes" : [ { "primitives" : [ { "extensions" : { "EXT_structural_metadata" : { "propertyTextures" : [ 0 ] } }, "attributes" : { "POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3 }, "indices" : 0, "material" : 0, "mode" : 4 } ] } ], "nodes" : [ { "mesh" : 0 } ], "samplers" : [ { "magFilter" : 9728, "minFilter" : 9728 } ], "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "textures" : [ { "sampler" : 0, "source" : 0 } ] } ================================================ FILE: specs/data/propertyTables/propertiesInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": "NOT_AN_OBJECT" } ] } ================================================ FILE: specs/data/propertyTables/propertiesMinPropertiesMismatch.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": {} } ] } ================================================ FILE: specs/data/propertyTables/propertyArrayOffsetTypeInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_variable_length_INT8_SCALAR_array": { "values": 0, "arrayOffsets": 0, "arrayOffsetType": 12345 } } } ] } ================================================ FILE: specs/data/propertyTables/propertyArrayOffsetTypeInvalidValue.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_variable_length_INT8_SCALAR_array": { "values": 0, "arrayOffsets": 0, "arrayOffsetType": "FLOAT32" } } } ] } ================================================ FILE: specs/data/propertyTables/propertyArrayOffsetsInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_variable_length_INT8_SCALAR_array": { "values": 0, "arrayOffsets": "NOT_A_NUMBER" } } } ] } ================================================ FILE: specs/data/propertyTables/propertyArrayOffsetsInvalidValue.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_variable_length_INT8_SCALAR_array": { "values": 0, "arrayOffsets": 12345 } } } ] } ================================================ FILE: specs/data/propertyTables/propertyClassInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": 12345, "count": 1 } ] } ================================================ FILE: specs/data/propertyTables/propertyClassInvalidValue.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "INVALID_CLASS_NAME", "count": 1 } ] } ================================================ FILE: specs/data/propertyTables/propertyCountInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": "NOT_A_NUMBER" } ] } ================================================ FILE: specs/data/propertyTables/propertyCountInvalidValue.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": -12345 } ] } ================================================ FILE: specs/data/propertyTables/propertyIdInvalid.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "UNKNOWN_PROPERTY": { "values": 0 } } } ] } ================================================ FILE: specs/data/propertyTables/propertyStringOffsetTypeInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_STRING": { "values": 0, "stringOffsets": 0, "stringOffsetType": 12345 } } } ] } ================================================ FILE: specs/data/propertyTables/propertyStringOffsetTypeInvalidValue.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_STRING": { "values": 0, "stringOffsets": 0, "stringOffsetType": "FLOAT32" } } } ] } ================================================ FILE: specs/data/propertyTables/propertyStringOffsetsInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_STRING": { "values": 0, "stringOffsets": "NOT_A_NUMBER" } } } ] } ================================================ FILE: specs/data/propertyTables/propertyStringOffsetsInvalidValue.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_STRING": { "values": 0, "stringOffsets": 12345 } } } ] } ================================================ FILE: specs/data/propertyTables/propertyStringWithoutStringOffsets.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_STRING": { "values": 0 } } } ] } ================================================ FILE: specs/data/propertyTables/propertyValueMissing.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_INT8_SCALAR": { } } } ] } ================================================ FILE: specs/data/propertyTables/propertyValuesInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_INT8_SCALAR": { "values": "NOT_A_NUMBER" } } } ] } ================================================ FILE: specs/data/propertyTables/propertyVariableLengthArrayWithMin.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_variable_length_INT8_SCALAR_array": { "values": 0, "arrayOffsets": 1, "min": 123 } } } ] } ================================================ FILE: specs/data/propertyTables/propertyVariableLengthArrayWithOffset.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_variable_length_INT8_SCALAR_array": { "values": 0, "arrayOffsets": 1, "offset": 123 } } } ] } ================================================ FILE: specs/data/propertyTables/propertyVariableLengthArrayWithoutArrayOffsets.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "propertyTables": [ { "class": "fullMetadataClass", "count": 1, "properties": { "example_variable_length_INT8_SCALAR_array": { "values": 0 } } } ] } ================================================ FILE: specs/data/schemas/FullMetadataSchema.json ================================================ { "id": "FullMetadataSchemaId", "classes": { "fullMetadataClass": { "name": "Full example metadata class", "description": "An example metadata class with all property types", "properties": { "example_STRING": { "name": "Example STRING property", "description": "An example property, with type STRING", "type": "STRING", "array": false }, "example_variable_length_STRING_array": { "name": "Example variable-length STRING array property", "description": "An example variable length array property, with type STRING", "type": "STRING", "array": true }, "example_fixed_length_STRING_array": { "name": "Example fixed-length STRING array property", "description": "An example fixed length array property, with type STRING", "type": "STRING", "array": true, "count": 5 }, "example_BOOLEAN": { "name": "Example BOOLEAN property", "description": "An example property, with type BOOLEAN", "type": "BOOLEAN", "array": false }, "example_variable_length_BOOLEAN_array": { "name": "Example variable-length BOOLEAN array property", "description": "An example variable length array property, with type BOOLEAN", "type": "BOOLEAN", "array": true }, "example_fixed_length_BOOLEAN_array": { "name": "Example fixed-length BOOLEAN array property", "description": "An example fixed length array property, with type BOOLEAN", "type": "BOOLEAN", "array": true, "count": 5 }, "example_ENUM": { "name": "Example ENUM property", "description": "An example property, with type ENUM, enum type exampleEnumType", "type": "ENUM", "enumType": "exampleEnumType", "array": false }, "example_variable_length_ENUM_array": { "name": "Example variable-length ENUM array property", "description": "An example variable length array property, with type ENUM, enum type exampleEnumType", "type": "ENUM", "enumType": "exampleEnumType", "array": true }, "example_fixed_length_ENUM_array": { "name": "Example fixed-length ENUM array property", "description": "An example fixed length array property, with type ENUM, enum type exampleEnumType", "type": "ENUM", "enumType": "exampleEnumType", "array": true, "count": 5 }, "example_INT8_SCALAR": { "name": "Example SCALAR property with INT8 components", "description": "An example property, with type SCALAR, with component type INT8", "type": "SCALAR", "componentType": "INT8", "array": false, "normalized": false }, "example_variable_length_INT8_SCALAR_array": { "name": "Example variable-length SCALAR array property with INT8 components", "description": "An example variable length array property, with type SCALAR, with component type INT8", "type": "SCALAR", "componentType": "INT8", "array": true, "normalized": false }, "example_fixed_length_INT8_SCALAR_array": { "name": "Example fixed-length SCALAR array property with INT8 components", "description": "An example fixed length array property, with type SCALAR, with component type INT8", "type": "SCALAR", "componentType": "INT8", "array": true, "count": 5, "normalized": false }, "example_normalized_INT8_SCALAR": { "name": "Example SCALAR property with normalized INT8 components", "description": "An example property, with type SCALAR, with component type INT8, normalized", "type": "SCALAR", "componentType": "INT8", "array": false, "normalized": true }, "example_variable_length_normalized_INT8_SCALAR_array": { "name": "Example variable-length SCALAR array property with normalized INT8 components", "description": "An example variable length array property, with type SCALAR, with component type INT8, normalized", "type": "SCALAR", "componentType": "INT8", "array": true, "normalized": true }, "example_fixed_length_normalized_INT8_SCALAR_array": { "name": "Example fixed-length SCALAR array property with normalized INT8 components", "description": "An example fixed length array property, with type SCALAR, with component type INT8, normalized", "type": "SCALAR", "componentType": "INT8", "array": true, "count": 5, "normalized": true }, "example_UINT8_SCALAR": { "name": "Example SCALAR property with UINT8 components", "description": "An example property, with type SCALAR, with component type UINT8", "type": "SCALAR", "componentType": "UINT8", "array": false, "normalized": false }, "example_variable_length_UINT8_SCALAR_array": { "name": "Example variable-length SCALAR array property with UINT8 components", "description": "An example variable length array property, with type SCALAR, with component type UINT8", "type": "SCALAR", "componentType": "UINT8", "array": true, "normalized": false }, "example_fixed_length_UINT8_SCALAR_array": { "name": "Example fixed-length SCALAR array property with UINT8 components", "description": "An example fixed length array property, with type SCALAR, with component type UINT8", "type": "SCALAR", "componentType": "UINT8", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT8_SCALAR": { "name": "Example SCALAR property with normalized UINT8 components", "description": "An example property, with type SCALAR, with component type UINT8, normalized", "type": "SCALAR", "componentType": "UINT8", "array": false, "normalized": true }, "example_variable_length_normalized_UINT8_SCALAR_array": { "name": "Example variable-length SCALAR array property with normalized UINT8 components", "description": "An example variable length array property, with type SCALAR, with component type UINT8, normalized", "type": "SCALAR", "componentType": "UINT8", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT8_SCALAR_array": { "name": "Example fixed-length SCALAR array property with normalized UINT8 components", "description": "An example fixed length array property, with type SCALAR, with component type UINT8, normalized", "type": "SCALAR", "componentType": "UINT8", "array": true, "count": 5, "normalized": true }, "example_INT16_SCALAR": { "name": "Example SCALAR property with INT16 components", "description": "An example property, with type SCALAR, with component type INT16", "type": "SCALAR", "componentType": "INT16", "array": false, "normalized": false }, "example_variable_length_INT16_SCALAR_array": { "name": "Example variable-length SCALAR array property with INT16 components", "description": "An example variable length array property, with type SCALAR, with component type INT16", "type": "SCALAR", "componentType": "INT16", "array": true, "normalized": false }, "example_fixed_length_INT16_SCALAR_array": { "name": "Example fixed-length SCALAR array property with INT16 components", "description": "An example fixed length array property, with type SCALAR, with component type INT16", "type": "SCALAR", "componentType": "INT16", "array": true, "count": 5, "normalized": false }, "example_normalized_INT16_SCALAR": { "name": "Example SCALAR property with normalized INT16 components", "description": "An example property, with type SCALAR, with component type INT16, normalized", "type": "SCALAR", "componentType": "INT16", "array": false, "normalized": true }, "example_variable_length_normalized_INT16_SCALAR_array": { "name": "Example variable-length SCALAR array property with normalized INT16 components", "description": "An example variable length array property, with type SCALAR, with component type INT16, normalized", "type": "SCALAR", "componentType": "INT16", "array": true, "normalized": true }, "example_fixed_length_normalized_INT16_SCALAR_array": { "name": "Example fixed-length SCALAR array property with normalized INT16 components", "description": "An example fixed length array property, with type SCALAR, with component type INT16, normalized", "type": "SCALAR", "componentType": "INT16", "array": true, "count": 5, "normalized": true }, "example_UINT16_SCALAR": { "name": "Example SCALAR property with UINT16 components", "description": "An example property, with type SCALAR, with component type UINT16", "type": "SCALAR", "componentType": "UINT16", "array": false, "normalized": false }, "example_variable_length_UINT16_SCALAR_array": { "name": "Example variable-length SCALAR array property with UINT16 components", "description": "An example variable length array property, with type SCALAR, with component type UINT16", "type": "SCALAR", "componentType": "UINT16", "array": true, "normalized": false }, "example_fixed_length_UINT16_SCALAR_array": { "name": "Example fixed-length SCALAR array property with UINT16 components", "description": "An example fixed length array property, with type SCALAR, with component type UINT16", "type": "SCALAR", "componentType": "UINT16", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT16_SCALAR": { "name": "Example SCALAR property with normalized UINT16 components", "description": "An example property, with type SCALAR, with component type UINT16, normalized", "type": "SCALAR", "componentType": "UINT16", "array": false, "normalized": true }, "example_variable_length_normalized_UINT16_SCALAR_array": { "name": "Example variable-length SCALAR array property with normalized UINT16 components", "description": "An example variable length array property, with type SCALAR, with component type UINT16, normalized", "type": "SCALAR", "componentType": "UINT16", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT16_SCALAR_array": { "name": "Example fixed-length SCALAR array property with normalized UINT16 components", "description": "An example fixed length array property, with type SCALAR, with component type UINT16, normalized", "type": "SCALAR", "componentType": "UINT16", "array": true, "count": 5, "normalized": true }, "example_INT32_SCALAR": { "name": "Example SCALAR property with INT32 components", "description": "An example property, with type SCALAR, with component type INT32", "type": "SCALAR", "componentType": "INT32", "array": false, "normalized": false }, "example_variable_length_INT32_SCALAR_array": { "name": "Example variable-length SCALAR array property with INT32 components", "description": "An example variable length array property, with type SCALAR, with component type INT32", "type": "SCALAR", "componentType": "INT32", "array": true, "normalized": false }, "example_fixed_length_INT32_SCALAR_array": { "name": "Example fixed-length SCALAR array property with INT32 components", "description": "An example fixed length array property, with type SCALAR, with component type INT32", "type": "SCALAR", "componentType": "INT32", "array": true, "count": 5, "normalized": false }, "example_normalized_INT32_SCALAR": { "name": "Example SCALAR property with normalized INT32 components", "description": "An example property, with type SCALAR, with component type INT32, normalized", "type": "SCALAR", "componentType": "INT32", "array": false, "normalized": true }, "example_variable_length_normalized_INT32_SCALAR_array": { "name": "Example variable-length SCALAR array property with normalized INT32 components", "description": "An example variable length array property, with type SCALAR, with component type INT32, normalized", "type": "SCALAR", "componentType": "INT32", "array": true, "normalized": true }, "example_fixed_length_normalized_INT32_SCALAR_array": { "name": "Example fixed-length SCALAR array property with normalized INT32 components", "description": "An example fixed length array property, with type SCALAR, with component type INT32, normalized", "type": "SCALAR", "componentType": "INT32", "array": true, "count": 5, "normalized": true }, "example_UINT32_SCALAR": { "name": "Example SCALAR property with UINT32 components", "description": "An example property, with type SCALAR, with component type UINT32", "type": "SCALAR", "componentType": "UINT32", "array": false, "normalized": false }, "example_variable_length_UINT32_SCALAR_array": { "name": "Example variable-length SCALAR array property with UINT32 components", "description": "An example variable length array property, with type SCALAR, with component type UINT32", "type": "SCALAR", "componentType": "UINT32", "array": true, "normalized": false }, "example_fixed_length_UINT32_SCALAR_array": { "name": "Example fixed-length SCALAR array property with UINT32 components", "description": "An example fixed length array property, with type SCALAR, with component type UINT32", "type": "SCALAR", "componentType": "UINT32", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT32_SCALAR": { "name": "Example SCALAR property with normalized UINT32 components", "description": "An example property, with type SCALAR, with component type UINT32, normalized", "type": "SCALAR", "componentType": "UINT32", "array": false, "normalized": true }, "example_variable_length_normalized_UINT32_SCALAR_array": { "name": "Example variable-length SCALAR array property with normalized UINT32 components", "description": "An example variable length array property, with type SCALAR, with component type UINT32, normalized", "type": "SCALAR", "componentType": "UINT32", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT32_SCALAR_array": { "name": "Example fixed-length SCALAR array property with normalized UINT32 components", "description": "An example fixed length array property, with type SCALAR, with component type UINT32, normalized", "type": "SCALAR", "componentType": "UINT32", "array": true, "count": 5, "normalized": true }, "example_INT64_SCALAR": { "name": "Example SCALAR property with INT64 components", "description": "An example property, with type SCALAR, with component type INT64", "type": "SCALAR", "componentType": "INT64", "array": false, "normalized": false }, "example_variable_length_INT64_SCALAR_array": { "name": "Example variable-length SCALAR array property with INT64 components", "description": "An example variable length array property, with type SCALAR, with component type INT64", "type": "SCALAR", "componentType": "INT64", "array": true, "normalized": false }, "example_fixed_length_INT64_SCALAR_array": { "name": "Example fixed-length SCALAR array property with INT64 components", "description": "An example fixed length array property, with type SCALAR, with component type INT64", "type": "SCALAR", "componentType": "INT64", "array": true, "count": 5, "normalized": false }, "example_normalized_INT64_SCALAR": { "name": "Example SCALAR property with normalized INT64 components", "description": "An example property, with type SCALAR, with component type INT64, normalized", "type": "SCALAR", "componentType": "INT64", "array": false, "normalized": true }, "example_variable_length_normalized_INT64_SCALAR_array": { "name": "Example variable-length SCALAR array property with normalized INT64 components", "description": "An example variable length array property, with type SCALAR, with component type INT64, normalized", "type": "SCALAR", "componentType": "INT64", "array": true, "normalized": true }, "example_fixed_length_normalized_INT64_SCALAR_array": { "name": "Example fixed-length SCALAR array property with normalized INT64 components", "description": "An example fixed length array property, with type SCALAR, with component type INT64, normalized", "type": "SCALAR", "componentType": "INT64", "array": true, "count": 5, "normalized": true }, "example_UINT64_SCALAR": { "name": "Example SCALAR property with UINT64 components", "description": "An example property, with type SCALAR, with component type UINT64", "type": "SCALAR", "componentType": "UINT64", "array": false, "normalized": false }, "example_variable_length_UINT64_SCALAR_array": { "name": "Example variable-length SCALAR array property with UINT64 components", "description": "An example variable length array property, with type SCALAR, with component type UINT64", "type": "SCALAR", "componentType": "UINT64", "array": true, "normalized": false }, "example_fixed_length_UINT64_SCALAR_array": { "name": "Example fixed-length SCALAR array property with UINT64 components", "description": "An example fixed length array property, with type SCALAR, with component type UINT64", "type": "SCALAR", "componentType": "UINT64", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT64_SCALAR": { "name": "Example SCALAR property with normalized UINT64 components", "description": "An example property, with type SCALAR, with component type UINT64, normalized", "type": "SCALAR", "componentType": "UINT64", "array": false, "normalized": true }, "example_variable_length_normalized_UINT64_SCALAR_array": { "name": "Example variable-length SCALAR array property with normalized UINT64 components", "description": "An example variable length array property, with type SCALAR, with component type UINT64, normalized", "type": "SCALAR", "componentType": "UINT64", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT64_SCALAR_array": { "name": "Example fixed-length SCALAR array property with normalized UINT64 components", "description": "An example fixed length array property, with type SCALAR, with component type UINT64, normalized", "type": "SCALAR", "componentType": "UINT64", "array": true, "count": 5, "normalized": true }, "example_FLOAT32_SCALAR": { "name": "Example SCALAR property with FLOAT32 components", "description": "An example property, with type SCALAR, with component type FLOAT32", "type": "SCALAR", "componentType": "FLOAT32", "array": false, "normalized": false }, "example_variable_length_FLOAT32_SCALAR_array": { "name": "Example variable-length SCALAR array property with FLOAT32 components", "description": "An example variable length array property, with type SCALAR, with component type FLOAT32", "type": "SCALAR", "componentType": "FLOAT32", "array": true, "normalized": false }, "example_fixed_length_FLOAT32_SCALAR_array": { "name": "Example fixed-length SCALAR array property with FLOAT32 components", "description": "An example fixed length array property, with type SCALAR, with component type FLOAT32", "type": "SCALAR", "componentType": "FLOAT32", "array": true, "count": 5, "normalized": false }, "example_FLOAT64_SCALAR": { "name": "Example SCALAR property with FLOAT64 components", "description": "An example property, with type SCALAR, with component type FLOAT64", "type": "SCALAR", "componentType": "FLOAT64", "array": false, "normalized": false }, "example_variable_length_FLOAT64_SCALAR_array": { "name": "Example variable-length SCALAR array property with FLOAT64 components", "description": "An example variable length array property, with type SCALAR, with component type FLOAT64", "type": "SCALAR", "componentType": "FLOAT64", "array": true, "normalized": false }, "example_fixed_length_FLOAT64_SCALAR_array": { "name": "Example fixed-length SCALAR array property with FLOAT64 components", "description": "An example fixed length array property, with type SCALAR, with component type FLOAT64", "type": "SCALAR", "componentType": "FLOAT64", "array": true, "count": 5, "normalized": false }, "example_INT8_VEC2": { "name": "Example VEC2 property with INT8 components", "description": "An example property, with type VEC2, with component type INT8", "type": "VEC2", "componentType": "INT8", "array": false, "normalized": false }, "example_variable_length_INT8_VEC2_array": { "name": "Example variable-length VEC2 array property with INT8 components", "description": "An example variable length array property, with type VEC2, with component type INT8", "type": "VEC2", "componentType": "INT8", "array": true, "normalized": false }, "example_fixed_length_INT8_VEC2_array": { "name": "Example fixed-length VEC2 array property with INT8 components", "description": "An example fixed length array property, with type VEC2, with component type INT8", "type": "VEC2", "componentType": "INT8", "array": true, "count": 5, "normalized": false }, "example_normalized_INT8_VEC2": { "name": "Example VEC2 property with normalized INT8 components", "description": "An example property, with type VEC2, with component type INT8, normalized", "type": "VEC2", "componentType": "INT8", "array": false, "normalized": true }, "example_variable_length_normalized_INT8_VEC2_array": { "name": "Example variable-length VEC2 array property with normalized INT8 components", "description": "An example variable length array property, with type VEC2, with component type INT8, normalized", "type": "VEC2", "componentType": "INT8", "array": true, "normalized": true }, "example_fixed_length_normalized_INT8_VEC2_array": { "name": "Example fixed-length VEC2 array property with normalized INT8 components", "description": "An example fixed length array property, with type VEC2, with component type INT8, normalized", "type": "VEC2", "componentType": "INT8", "array": true, "count": 5, "normalized": true }, "example_UINT8_VEC2": { "name": "Example VEC2 property with UINT8 components", "description": "An example property, with type VEC2, with component type UINT8", "type": "VEC2", "componentType": "UINT8", "array": false, "normalized": false }, "example_variable_length_UINT8_VEC2_array": { "name": "Example variable-length VEC2 array property with UINT8 components", "description": "An example variable length array property, with type VEC2, with component type UINT8", "type": "VEC2", "componentType": "UINT8", "array": true, "normalized": false }, "example_fixed_length_UINT8_VEC2_array": { "name": "Example fixed-length VEC2 array property with UINT8 components", "description": "An example fixed length array property, with type VEC2, with component type UINT8", "type": "VEC2", "componentType": "UINT8", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT8_VEC2": { "name": "Example VEC2 property with normalized UINT8 components", "description": "An example property, with type VEC2, with component type UINT8, normalized", "type": "VEC2", "componentType": "UINT8", "array": false, "normalized": true }, "example_variable_length_normalized_UINT8_VEC2_array": { "name": "Example variable-length VEC2 array property with normalized UINT8 components", "description": "An example variable length array property, with type VEC2, with component type UINT8, normalized", "type": "VEC2", "componentType": "UINT8", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT8_VEC2_array": { "name": "Example fixed-length VEC2 array property with normalized UINT8 components", "description": "An example fixed length array property, with type VEC2, with component type UINT8, normalized", "type": "VEC2", "componentType": "UINT8", "array": true, "count": 5, "normalized": true }, "example_INT16_VEC2": { "name": "Example VEC2 property with INT16 components", "description": "An example property, with type VEC2, with component type INT16", "type": "VEC2", "componentType": "INT16", "array": false, "normalized": false }, "example_variable_length_INT16_VEC2_array": { "name": "Example variable-length VEC2 array property with INT16 components", "description": "An example variable length array property, with type VEC2, with component type INT16", "type": "VEC2", "componentType": "INT16", "array": true, "normalized": false }, "example_fixed_length_INT16_VEC2_array": { "name": "Example fixed-length VEC2 array property with INT16 components", "description": "An example fixed length array property, with type VEC2, with component type INT16", "type": "VEC2", "componentType": "INT16", "array": true, "count": 5, "normalized": false }, "example_normalized_INT16_VEC2": { "name": "Example VEC2 property with normalized INT16 components", "description": "An example property, with type VEC2, with component type INT16, normalized", "type": "VEC2", "componentType": "INT16", "array": false, "normalized": true }, "example_variable_length_normalized_INT16_VEC2_array": { "name": "Example variable-length VEC2 array property with normalized INT16 components", "description": "An example variable length array property, with type VEC2, with component type INT16, normalized", "type": "VEC2", "componentType": "INT16", "array": true, "normalized": true }, "example_fixed_length_normalized_INT16_VEC2_array": { "name": "Example fixed-length VEC2 array property with normalized INT16 components", "description": "An example fixed length array property, with type VEC2, with component type INT16, normalized", "type": "VEC2", "componentType": "INT16", "array": true, "count": 5, "normalized": true }, "example_UINT16_VEC2": { "name": "Example VEC2 property with UINT16 components", "description": "An example property, with type VEC2, with component type UINT16", "type": "VEC2", "componentType": "UINT16", "array": false, "normalized": false }, "example_variable_length_UINT16_VEC2_array": { "name": "Example variable-length VEC2 array property with UINT16 components", "description": "An example variable length array property, with type VEC2, with component type UINT16", "type": "VEC2", "componentType": "UINT16", "array": true, "normalized": false }, "example_fixed_length_UINT16_VEC2_array": { "name": "Example fixed-length VEC2 array property with UINT16 components", "description": "An example fixed length array property, with type VEC2, with component type UINT16", "type": "VEC2", "componentType": "UINT16", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT16_VEC2": { "name": "Example VEC2 property with normalized UINT16 components", "description": "An example property, with type VEC2, with component type UINT16, normalized", "type": "VEC2", "componentType": "UINT16", "array": false, "normalized": true }, "example_variable_length_normalized_UINT16_VEC2_array": { "name": "Example variable-length VEC2 array property with normalized UINT16 components", "description": "An example variable length array property, with type VEC2, with component type UINT16, normalized", "type": "VEC2", "componentType": "UINT16", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT16_VEC2_array": { "name": "Example fixed-length VEC2 array property with normalized UINT16 components", "description": "An example fixed length array property, with type VEC2, with component type UINT16, normalized", "type": "VEC2", "componentType": "UINT16", "array": true, "count": 5, "normalized": true }, "example_INT32_VEC2": { "name": "Example VEC2 property with INT32 components", "description": "An example property, with type VEC2, with component type INT32", "type": "VEC2", "componentType": "INT32", "array": false, "normalized": false }, "example_variable_length_INT32_VEC2_array": { "name": "Example variable-length VEC2 array property with INT32 components", "description": "An example variable length array property, with type VEC2, with component type INT32", "type": "VEC2", "componentType": "INT32", "array": true, "normalized": false }, "example_fixed_length_INT32_VEC2_array": { "name": "Example fixed-length VEC2 array property with INT32 components", "description": "An example fixed length array property, with type VEC2, with component type INT32", "type": "VEC2", "componentType": "INT32", "array": true, "count": 5, "normalized": false }, "example_normalized_INT32_VEC2": { "name": "Example VEC2 property with normalized INT32 components", "description": "An example property, with type VEC2, with component type INT32, normalized", "type": "VEC2", "componentType": "INT32", "array": false, "normalized": true }, "example_variable_length_normalized_INT32_VEC2_array": { "name": "Example variable-length VEC2 array property with normalized INT32 components", "description": "An example variable length array property, with type VEC2, with component type INT32, normalized", "type": "VEC2", "componentType": "INT32", "array": true, "normalized": true }, "example_fixed_length_normalized_INT32_VEC2_array": { "name": "Example fixed-length VEC2 array property with normalized INT32 components", "description": "An example fixed length array property, with type VEC2, with component type INT32, normalized", "type": "VEC2", "componentType": "INT32", "array": true, "count": 5, "normalized": true }, "example_UINT32_VEC2": { "name": "Example VEC2 property with UINT32 components", "description": "An example property, with type VEC2, with component type UINT32", "type": "VEC2", "componentType": "UINT32", "array": false, "normalized": false }, "example_variable_length_UINT32_VEC2_array": { "name": "Example variable-length VEC2 array property with UINT32 components", "description": "An example variable length array property, with type VEC2, with component type UINT32", "type": "VEC2", "componentType": "UINT32", "array": true, "normalized": false }, "example_fixed_length_UINT32_VEC2_array": { "name": "Example fixed-length VEC2 array property with UINT32 components", "description": "An example fixed length array property, with type VEC2, with component type UINT32", "type": "VEC2", "componentType": "UINT32", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT32_VEC2": { "name": "Example VEC2 property with normalized UINT32 components", "description": "An example property, with type VEC2, with component type UINT32, normalized", "type": "VEC2", "componentType": "UINT32", "array": false, "normalized": true }, "example_variable_length_normalized_UINT32_VEC2_array": { "name": "Example variable-length VEC2 array property with normalized UINT32 components", "description": "An example variable length array property, with type VEC2, with component type UINT32, normalized", "type": "VEC2", "componentType": "UINT32", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT32_VEC2_array": { "name": "Example fixed-length VEC2 array property with normalized UINT32 components", "description": "An example fixed length array property, with type VEC2, with component type UINT32, normalized", "type": "VEC2", "componentType": "UINT32", "array": true, "count": 5, "normalized": true }, "example_INT64_VEC2": { "name": "Example VEC2 property with INT64 components", "description": "An example property, with type VEC2, with component type INT64", "type": "VEC2", "componentType": "INT64", "array": false, "normalized": false }, "example_variable_length_INT64_VEC2_array": { "name": "Example variable-length VEC2 array property with INT64 components", "description": "An example variable length array property, with type VEC2, with component type INT64", "type": "VEC2", "componentType": "INT64", "array": true, "normalized": false }, "example_fixed_length_INT64_VEC2_array": { "name": "Example fixed-length VEC2 array property with INT64 components", "description": "An example fixed length array property, with type VEC2, with component type INT64", "type": "VEC2", "componentType": "INT64", "array": true, "count": 5, "normalized": false }, "example_normalized_INT64_VEC2": { "name": "Example VEC2 property with normalized INT64 components", "description": "An example property, with type VEC2, with component type INT64, normalized", "type": "VEC2", "componentType": "INT64", "array": false, "normalized": true }, "example_variable_length_normalized_INT64_VEC2_array": { "name": "Example variable-length VEC2 array property with normalized INT64 components", "description": "An example variable length array property, with type VEC2, with component type INT64, normalized", "type": "VEC2", "componentType": "INT64", "array": true, "normalized": true }, "example_fixed_length_normalized_INT64_VEC2_array": { "name": "Example fixed-length VEC2 array property with normalized INT64 components", "description": "An example fixed length array property, with type VEC2, with component type INT64, normalized", "type": "VEC2", "componentType": "INT64", "array": true, "count": 5, "normalized": true }, "example_UINT64_VEC2": { "name": "Example VEC2 property with UINT64 components", "description": "An example property, with type VEC2, with component type UINT64", "type": "VEC2", "componentType": "UINT64", "array": false, "normalized": false }, "example_variable_length_UINT64_VEC2_array": { "name": "Example variable-length VEC2 array property with UINT64 components", "description": "An example variable length array property, with type VEC2, with component type UINT64", "type": "VEC2", "componentType": "UINT64", "array": true, "normalized": false }, "example_fixed_length_UINT64_VEC2_array": { "name": "Example fixed-length VEC2 array property with UINT64 components", "description": "An example fixed length array property, with type VEC2, with component type UINT64", "type": "VEC2", "componentType": "UINT64", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT64_VEC2": { "name": "Example VEC2 property with normalized UINT64 components", "description": "An example property, with type VEC2, with component type UINT64, normalized", "type": "VEC2", "componentType": "UINT64", "array": false, "normalized": true }, "example_variable_length_normalized_UINT64_VEC2_array": { "name": "Example variable-length VEC2 array property with normalized UINT64 components", "description": "An example variable length array property, with type VEC2, with component type UINT64, normalized", "type": "VEC2", "componentType": "UINT64", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT64_VEC2_array": { "name": "Example fixed-length VEC2 array property with normalized UINT64 components", "description": "An example fixed length array property, with type VEC2, with component type UINT64, normalized", "type": "VEC2", "componentType": "UINT64", "array": true, "count": 5, "normalized": true }, "example_FLOAT32_VEC2": { "name": "Example VEC2 property with FLOAT32 components", "description": "An example property, with type VEC2, with component type FLOAT32", "type": "VEC2", "componentType": "FLOAT32", "array": false, "normalized": false }, "example_variable_length_FLOAT32_VEC2_array": { "name": "Example variable-length VEC2 array property with FLOAT32 components", "description": "An example variable length array property, with type VEC2, with component type FLOAT32", "type": "VEC2", "componentType": "FLOAT32", "array": true, "normalized": false }, "example_fixed_length_FLOAT32_VEC2_array": { "name": "Example fixed-length VEC2 array property with FLOAT32 components", "description": "An example fixed length array property, with type VEC2, with component type FLOAT32", "type": "VEC2", "componentType": "FLOAT32", "array": true, "count": 5, "normalized": false }, "example_FLOAT64_VEC2": { "name": "Example VEC2 property with FLOAT64 components", "description": "An example property, with type VEC2, with component type FLOAT64", "type": "VEC2", "componentType": "FLOAT64", "array": false, "normalized": false }, "example_variable_length_FLOAT64_VEC2_array": { "name": "Example variable-length VEC2 array property with FLOAT64 components", "description": "An example variable length array property, with type VEC2, with component type FLOAT64", "type": "VEC2", "componentType": "FLOAT64", "array": true, "normalized": false }, "example_fixed_length_FLOAT64_VEC2_array": { "name": "Example fixed-length VEC2 array property with FLOAT64 components", "description": "An example fixed length array property, with type VEC2, with component type FLOAT64", "type": "VEC2", "componentType": "FLOAT64", "array": true, "count": 5, "normalized": false }, "example_INT8_VEC3": { "name": "Example VEC3 property with INT8 components", "description": "An example property, with type VEC3, with component type INT8", "type": "VEC3", "componentType": "INT8", "array": false, "normalized": false }, "example_variable_length_INT8_VEC3_array": { "name": "Example variable-length VEC3 array property with INT8 components", "description": "An example variable length array property, with type VEC3, with component type INT8", "type": "VEC3", "componentType": "INT8", "array": true, "normalized": false }, "example_fixed_length_INT8_VEC3_array": { "name": "Example fixed-length VEC3 array property with INT8 components", "description": "An example fixed length array property, with type VEC3, with component type INT8", "type": "VEC3", "componentType": "INT8", "array": true, "count": 5, "normalized": false }, "example_normalized_INT8_VEC3": { "name": "Example VEC3 property with normalized INT8 components", "description": "An example property, with type VEC3, with component type INT8, normalized", "type": "VEC3", "componentType": "INT8", "array": false, "normalized": true }, "example_variable_length_normalized_INT8_VEC3_array": { "name": "Example variable-length VEC3 array property with normalized INT8 components", "description": "An example variable length array property, with type VEC3, with component type INT8, normalized", "type": "VEC3", "componentType": "INT8", "array": true, "normalized": true }, "example_fixed_length_normalized_INT8_VEC3_array": { "name": "Example fixed-length VEC3 array property with normalized INT8 components", "description": "An example fixed length array property, with type VEC3, with component type INT8, normalized", "type": "VEC3", "componentType": "INT8", "array": true, "count": 5, "normalized": true }, "example_UINT8_VEC3": { "name": "Example VEC3 property with UINT8 components", "description": "An example property, with type VEC3, with component type UINT8", "type": "VEC3", "componentType": "UINT8", "array": false, "normalized": false }, "example_variable_length_UINT8_VEC3_array": { "name": "Example variable-length VEC3 array property with UINT8 components", "description": "An example variable length array property, with type VEC3, with component type UINT8", "type": "VEC3", "componentType": "UINT8", "array": true, "normalized": false }, "example_fixed_length_UINT8_VEC3_array": { "name": "Example fixed-length VEC3 array property with UINT8 components", "description": "An example fixed length array property, with type VEC3, with component type UINT8", "type": "VEC3", "componentType": "UINT8", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT8_VEC3": { "name": "Example VEC3 property with normalized UINT8 components", "description": "An example property, with type VEC3, with component type UINT8, normalized", "type": "VEC3", "componentType": "UINT8", "array": false, "normalized": true }, "example_variable_length_normalized_UINT8_VEC3_array": { "name": "Example variable-length VEC3 array property with normalized UINT8 components", "description": "An example variable length array property, with type VEC3, with component type UINT8, normalized", "type": "VEC3", "componentType": "UINT8", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT8_VEC3_array": { "name": "Example fixed-length VEC3 array property with normalized UINT8 components", "description": "An example fixed length array property, with type VEC3, with component type UINT8, normalized", "type": "VEC3", "componentType": "UINT8", "array": true, "count": 5, "normalized": true }, "example_INT16_VEC3": { "name": "Example VEC3 property with INT16 components", "description": "An example property, with type VEC3, with component type INT16", "type": "VEC3", "componentType": "INT16", "array": false, "normalized": false }, "example_variable_length_INT16_VEC3_array": { "name": "Example variable-length VEC3 array property with INT16 components", "description": "An example variable length array property, with type VEC3, with component type INT16", "type": "VEC3", "componentType": "INT16", "array": true, "normalized": false }, "example_fixed_length_INT16_VEC3_array": { "name": "Example fixed-length VEC3 array property with INT16 components", "description": "An example fixed length array property, with type VEC3, with component type INT16", "type": "VEC3", "componentType": "INT16", "array": true, "count": 5, "normalized": false }, "example_normalized_INT16_VEC3": { "name": "Example VEC3 property with normalized INT16 components", "description": "An example property, with type VEC3, with component type INT16, normalized", "type": "VEC3", "componentType": "INT16", "array": false, "normalized": true }, "example_variable_length_normalized_INT16_VEC3_array": { "name": "Example variable-length VEC3 array property with normalized INT16 components", "description": "An example variable length array property, with type VEC3, with component type INT16, normalized", "type": "VEC3", "componentType": "INT16", "array": true, "normalized": true }, "example_fixed_length_normalized_INT16_VEC3_array": { "name": "Example fixed-length VEC3 array property with normalized INT16 components", "description": "An example fixed length array property, with type VEC3, with component type INT16, normalized", "type": "VEC3", "componentType": "INT16", "array": true, "count": 5, "normalized": true }, "example_UINT16_VEC3": { "name": "Example VEC3 property with UINT16 components", "description": "An example property, with type VEC3, with component type UINT16", "type": "VEC3", "componentType": "UINT16", "array": false, "normalized": false }, "example_variable_length_UINT16_VEC3_array": { "name": "Example variable-length VEC3 array property with UINT16 components", "description": "An example variable length array property, with type VEC3, with component type UINT16", "type": "VEC3", "componentType": "UINT16", "array": true, "normalized": false }, "example_fixed_length_UINT16_VEC3_array": { "name": "Example fixed-length VEC3 array property with UINT16 components", "description": "An example fixed length array property, with type VEC3, with component type UINT16", "type": "VEC3", "componentType": "UINT16", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT16_VEC3": { "name": "Example VEC3 property with normalized UINT16 components", "description": "An example property, with type VEC3, with component type UINT16, normalized", "type": "VEC3", "componentType": "UINT16", "array": false, "normalized": true }, "example_variable_length_normalized_UINT16_VEC3_array": { "name": "Example variable-length VEC3 array property with normalized UINT16 components", "description": "An example variable length array property, with type VEC3, with component type UINT16, normalized", "type": "VEC3", "componentType": "UINT16", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT16_VEC3_array": { "name": "Example fixed-length VEC3 array property with normalized UINT16 components", "description": "An example fixed length array property, with type VEC3, with component type UINT16, normalized", "type": "VEC3", "componentType": "UINT16", "array": true, "count": 5, "normalized": true }, "example_INT32_VEC3": { "name": "Example VEC3 property with INT32 components", "description": "An example property, with type VEC3, with component type INT32", "type": "VEC3", "componentType": "INT32", "array": false, "normalized": false }, "example_variable_length_INT32_VEC3_array": { "name": "Example variable-length VEC3 array property with INT32 components", "description": "An example variable length array property, with type VEC3, with component type INT32", "type": "VEC3", "componentType": "INT32", "array": true, "normalized": false }, "example_fixed_length_INT32_VEC3_array": { "name": "Example fixed-length VEC3 array property with INT32 components", "description": "An example fixed length array property, with type VEC3, with component type INT32", "type": "VEC3", "componentType": "INT32", "array": true, "count": 5, "normalized": false }, "example_normalized_INT32_VEC3": { "name": "Example VEC3 property with normalized INT32 components", "description": "An example property, with type VEC3, with component type INT32, normalized", "type": "VEC3", "componentType": "INT32", "array": false, "normalized": true }, "example_variable_length_normalized_INT32_VEC3_array": { "name": "Example variable-length VEC3 array property with normalized INT32 components", "description": "An example variable length array property, with type VEC3, with component type INT32, normalized", "type": "VEC3", "componentType": "INT32", "array": true, "normalized": true }, "example_fixed_length_normalized_INT32_VEC3_array": { "name": "Example fixed-length VEC3 array property with normalized INT32 components", "description": "An example fixed length array property, with type VEC3, with component type INT32, normalized", "type": "VEC3", "componentType": "INT32", "array": true, "count": 5, "normalized": true }, "example_UINT32_VEC3": { "name": "Example VEC3 property with UINT32 components", "description": "An example property, with type VEC3, with component type UINT32", "type": "VEC3", "componentType": "UINT32", "array": false, "normalized": false }, "example_variable_length_UINT32_VEC3_array": { "name": "Example variable-length VEC3 array property with UINT32 components", "description": "An example variable length array property, with type VEC3, with component type UINT32", "type": "VEC3", "componentType": "UINT32", "array": true, "normalized": false }, "example_fixed_length_UINT32_VEC3_array": { "name": "Example fixed-length VEC3 array property with UINT32 components", "description": "An example fixed length array property, with type VEC3, with component type UINT32", "type": "VEC3", "componentType": "UINT32", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT32_VEC3": { "name": "Example VEC3 property with normalized UINT32 components", "description": "An example property, with type VEC3, with component type UINT32, normalized", "type": "VEC3", "componentType": "UINT32", "array": false, "normalized": true }, "example_variable_length_normalized_UINT32_VEC3_array": { "name": "Example variable-length VEC3 array property with normalized UINT32 components", "description": "An example variable length array property, with type VEC3, with component type UINT32, normalized", "type": "VEC3", "componentType": "UINT32", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT32_VEC3_array": { "name": "Example fixed-length VEC3 array property with normalized UINT32 components", "description": "An example fixed length array property, with type VEC3, with component type UINT32, normalized", "type": "VEC3", "componentType": "UINT32", "array": true, "count": 5, "normalized": true }, "example_INT64_VEC3": { "name": "Example VEC3 property with INT64 components", "description": "An example property, with type VEC3, with component type INT64", "type": "VEC3", "componentType": "INT64", "array": false, "normalized": false }, "example_variable_length_INT64_VEC3_array": { "name": "Example variable-length VEC3 array property with INT64 components", "description": "An example variable length array property, with type VEC3, with component type INT64", "type": "VEC3", "componentType": "INT64", "array": true, "normalized": false }, "example_fixed_length_INT64_VEC3_array": { "name": "Example fixed-length VEC3 array property with INT64 components", "description": "An example fixed length array property, with type VEC3, with component type INT64", "type": "VEC3", "componentType": "INT64", "array": true, "count": 5, "normalized": false }, "example_normalized_INT64_VEC3": { "name": "Example VEC3 property with normalized INT64 components", "description": "An example property, with type VEC3, with component type INT64, normalized", "type": "VEC3", "componentType": "INT64", "array": false, "normalized": true }, "example_variable_length_normalized_INT64_VEC3_array": { "name": "Example variable-length VEC3 array property with normalized INT64 components", "description": "An example variable length array property, with type VEC3, with component type INT64, normalized", "type": "VEC3", "componentType": "INT64", "array": true, "normalized": true }, "example_fixed_length_normalized_INT64_VEC3_array": { "name": "Example fixed-length VEC3 array property with normalized INT64 components", "description": "An example fixed length array property, with type VEC3, with component type INT64, normalized", "type": "VEC3", "componentType": "INT64", "array": true, "count": 5, "normalized": true }, "example_UINT64_VEC3": { "name": "Example VEC3 property with UINT64 components", "description": "An example property, with type VEC3, with component type UINT64", "type": "VEC3", "componentType": "UINT64", "array": false, "normalized": false }, "example_variable_length_UINT64_VEC3_array": { "name": "Example variable-length VEC3 array property with UINT64 components", "description": "An example variable length array property, with type VEC3, with component type UINT64", "type": "VEC3", "componentType": "UINT64", "array": true, "normalized": false }, "example_fixed_length_UINT64_VEC3_array": { "name": "Example fixed-length VEC3 array property with UINT64 components", "description": "An example fixed length array property, with type VEC3, with component type UINT64", "type": "VEC3", "componentType": "UINT64", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT64_VEC3": { "name": "Example VEC3 property with normalized UINT64 components", "description": "An example property, with type VEC3, with component type UINT64, normalized", "type": "VEC3", "componentType": "UINT64", "array": false, "normalized": true }, "example_variable_length_normalized_UINT64_VEC3_array": { "name": "Example variable-length VEC3 array property with normalized UINT64 components", "description": "An example variable length array property, with type VEC3, with component type UINT64, normalized", "type": "VEC3", "componentType": "UINT64", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT64_VEC3_array": { "name": "Example fixed-length VEC3 array property with normalized UINT64 components", "description": "An example fixed length array property, with type VEC3, with component type UINT64, normalized", "type": "VEC3", "componentType": "UINT64", "array": true, "count": 5, "normalized": true }, "example_FLOAT32_VEC3": { "name": "Example VEC3 property with FLOAT32 components", "description": "An example property, with type VEC3, with component type FLOAT32", "type": "VEC3", "componentType": "FLOAT32", "array": false, "normalized": false }, "example_variable_length_FLOAT32_VEC3_array": { "name": "Example variable-length VEC3 array property with FLOAT32 components", "description": "An example variable length array property, with type VEC3, with component type FLOAT32", "type": "VEC3", "componentType": "FLOAT32", "array": true, "normalized": false }, "example_fixed_length_FLOAT32_VEC3_array": { "name": "Example fixed-length VEC3 array property with FLOAT32 components", "description": "An example fixed length array property, with type VEC3, with component type FLOAT32", "type": "VEC3", "componentType": "FLOAT32", "array": true, "count": 5, "normalized": false }, "example_FLOAT64_VEC3": { "name": "Example VEC3 property with FLOAT64 components", "description": "An example property, with type VEC3, with component type FLOAT64", "type": "VEC3", "componentType": "FLOAT64", "array": false, "normalized": false }, "example_variable_length_FLOAT64_VEC3_array": { "name": "Example variable-length VEC3 array property with FLOAT64 components", "description": "An example variable length array property, with type VEC3, with component type FLOAT64", "type": "VEC3", "componentType": "FLOAT64", "array": true, "normalized": false }, "example_fixed_length_FLOAT64_VEC3_array": { "name": "Example fixed-length VEC3 array property with FLOAT64 components", "description": "An example fixed length array property, with type VEC3, with component type FLOAT64", "type": "VEC3", "componentType": "FLOAT64", "array": true, "count": 5, "normalized": false }, "example_INT8_VEC4": { "name": "Example VEC4 property with INT8 components", "description": "An example property, with type VEC4, with component type INT8", "type": "VEC4", "componentType": "INT8", "array": false, "normalized": false }, "example_variable_length_INT8_VEC4_array": { "name": "Example variable-length VEC4 array property with INT8 components", "description": "An example variable length array property, with type VEC4, with component type INT8", "type": "VEC4", "componentType": "INT8", "array": true, "normalized": false }, "example_fixed_length_INT8_VEC4_array": { "name": "Example fixed-length VEC4 array property with INT8 components", "description": "An example fixed length array property, with type VEC4, with component type INT8", "type": "VEC4", "componentType": "INT8", "array": true, "count": 5, "normalized": false }, "example_normalized_INT8_VEC4": { "name": "Example VEC4 property with normalized INT8 components", "description": "An example property, with type VEC4, with component type INT8, normalized", "type": "VEC4", "componentType": "INT8", "array": false, "normalized": true }, "example_variable_length_normalized_INT8_VEC4_array": { "name": "Example variable-length VEC4 array property with normalized INT8 components", "description": "An example variable length array property, with type VEC4, with component type INT8, normalized", "type": "VEC4", "componentType": "INT8", "array": true, "normalized": true }, "example_fixed_length_normalized_INT8_VEC4_array": { "name": "Example fixed-length VEC4 array property with normalized INT8 components", "description": "An example fixed length array property, with type VEC4, with component type INT8, normalized", "type": "VEC4", "componentType": "INT8", "array": true, "count": 5, "normalized": true }, "example_UINT8_VEC4": { "name": "Example VEC4 property with UINT8 components", "description": "An example property, with type VEC4, with component type UINT8", "type": "VEC4", "componentType": "UINT8", "array": false, "normalized": false }, "example_variable_length_UINT8_VEC4_array": { "name": "Example variable-length VEC4 array property with UINT8 components", "description": "An example variable length array property, with type VEC4, with component type UINT8", "type": "VEC4", "componentType": "UINT8", "array": true, "normalized": false }, "example_fixed_length_UINT8_VEC4_array": { "name": "Example fixed-length VEC4 array property with UINT8 components", "description": "An example fixed length array property, with type VEC4, with component type UINT8", "type": "VEC4", "componentType": "UINT8", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT8_VEC4": { "name": "Example VEC4 property with normalized UINT8 components", "description": "An example property, with type VEC4, with component type UINT8, normalized", "type": "VEC4", "componentType": "UINT8", "array": false, "normalized": true }, "example_variable_length_normalized_UINT8_VEC4_array": { "name": "Example variable-length VEC4 array property with normalized UINT8 components", "description": "An example variable length array property, with type VEC4, with component type UINT8, normalized", "type": "VEC4", "componentType": "UINT8", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT8_VEC4_array": { "name": "Example fixed-length VEC4 array property with normalized UINT8 components", "description": "An example fixed length array property, with type VEC4, with component type UINT8, normalized", "type": "VEC4", "componentType": "UINT8", "array": true, "count": 5, "normalized": true }, "example_INT16_VEC4": { "name": "Example VEC4 property with INT16 components", "description": "An example property, with type VEC4, with component type INT16", "type": "VEC4", "componentType": "INT16", "array": false, "normalized": false }, "example_variable_length_INT16_VEC4_array": { "name": "Example variable-length VEC4 array property with INT16 components", "description": "An example variable length array property, with type VEC4, with component type INT16", "type": "VEC4", "componentType": "INT16", "array": true, "normalized": false }, "example_fixed_length_INT16_VEC4_array": { "name": "Example fixed-length VEC4 array property with INT16 components", "description": "An example fixed length array property, with type VEC4, with component type INT16", "type": "VEC4", "componentType": "INT16", "array": true, "count": 5, "normalized": false }, "example_normalized_INT16_VEC4": { "name": "Example VEC4 property with normalized INT16 components", "description": "An example property, with type VEC4, with component type INT16, normalized", "type": "VEC4", "componentType": "INT16", "array": false, "normalized": true }, "example_variable_length_normalized_INT16_VEC4_array": { "name": "Example variable-length VEC4 array property with normalized INT16 components", "description": "An example variable length array property, with type VEC4, with component type INT16, normalized", "type": "VEC4", "componentType": "INT16", "array": true, "normalized": true }, "example_fixed_length_normalized_INT16_VEC4_array": { "name": "Example fixed-length VEC4 array property with normalized INT16 components", "description": "An example fixed length array property, with type VEC4, with component type INT16, normalized", "type": "VEC4", "componentType": "INT16", "array": true, "count": 5, "normalized": true }, "example_UINT16_VEC4": { "name": "Example VEC4 property with UINT16 components", "description": "An example property, with type VEC4, with component type UINT16", "type": "VEC4", "componentType": "UINT16", "array": false, "normalized": false }, "example_variable_length_UINT16_VEC4_array": { "name": "Example variable-length VEC4 array property with UINT16 components", "description": "An example variable length array property, with type VEC4, with component type UINT16", "type": "VEC4", "componentType": "UINT16", "array": true, "normalized": false }, "example_fixed_length_UINT16_VEC4_array": { "name": "Example fixed-length VEC4 array property with UINT16 components", "description": "An example fixed length array property, with type VEC4, with component type UINT16", "type": "VEC4", "componentType": "UINT16", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT16_VEC4": { "name": "Example VEC4 property with normalized UINT16 components", "description": "An example property, with type VEC4, with component type UINT16, normalized", "type": "VEC4", "componentType": "UINT16", "array": false, "normalized": true }, "example_variable_length_normalized_UINT16_VEC4_array": { "name": "Example variable-length VEC4 array property with normalized UINT16 components", "description": "An example variable length array property, with type VEC4, with component type UINT16, normalized", "type": "VEC4", "componentType": "UINT16", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT16_VEC4_array": { "name": "Example fixed-length VEC4 array property with normalized UINT16 components", "description": "An example fixed length array property, with type VEC4, with component type UINT16, normalized", "type": "VEC4", "componentType": "UINT16", "array": true, "count": 5, "normalized": true }, "example_INT32_VEC4": { "name": "Example VEC4 property with INT32 components", "description": "An example property, with type VEC4, with component type INT32", "type": "VEC4", "componentType": "INT32", "array": false, "normalized": false }, "example_variable_length_INT32_VEC4_array": { "name": "Example variable-length VEC4 array property with INT32 components", "description": "An example variable length array property, with type VEC4, with component type INT32", "type": "VEC4", "componentType": "INT32", "array": true, "normalized": false }, "example_fixed_length_INT32_VEC4_array": { "name": "Example fixed-length VEC4 array property with INT32 components", "description": "An example fixed length array property, with type VEC4, with component type INT32", "type": "VEC4", "componentType": "INT32", "array": true, "count": 5, "normalized": false }, "example_normalized_INT32_VEC4": { "name": "Example VEC4 property with normalized INT32 components", "description": "An example property, with type VEC4, with component type INT32, normalized", "type": "VEC4", "componentType": "INT32", "array": false, "normalized": true }, "example_variable_length_normalized_INT32_VEC4_array": { "name": "Example variable-length VEC4 array property with normalized INT32 components", "description": "An example variable length array property, with type VEC4, with component type INT32, normalized", "type": "VEC4", "componentType": "INT32", "array": true, "normalized": true }, "example_fixed_length_normalized_INT32_VEC4_array": { "name": "Example fixed-length VEC4 array property with normalized INT32 components", "description": "An example fixed length array property, with type VEC4, with component type INT32, normalized", "type": "VEC4", "componentType": "INT32", "array": true, "count": 5, "normalized": true }, "example_UINT32_VEC4": { "name": "Example VEC4 property with UINT32 components", "description": "An example property, with type VEC4, with component type UINT32", "type": "VEC4", "componentType": "UINT32", "array": false, "normalized": false }, "example_variable_length_UINT32_VEC4_array": { "name": "Example variable-length VEC4 array property with UINT32 components", "description": "An example variable length array property, with type VEC4, with component type UINT32", "type": "VEC4", "componentType": "UINT32", "array": true, "normalized": false }, "example_fixed_length_UINT32_VEC4_array": { "name": "Example fixed-length VEC4 array property with UINT32 components", "description": "An example fixed length array property, with type VEC4, with component type UINT32", "type": "VEC4", "componentType": "UINT32", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT32_VEC4": { "name": "Example VEC4 property with normalized UINT32 components", "description": "An example property, with type VEC4, with component type UINT32, normalized", "type": "VEC4", "componentType": "UINT32", "array": false, "normalized": true }, "example_variable_length_normalized_UINT32_VEC4_array": { "name": "Example variable-length VEC4 array property with normalized UINT32 components", "description": "An example variable length array property, with type VEC4, with component type UINT32, normalized", "type": "VEC4", "componentType": "UINT32", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT32_VEC4_array": { "name": "Example fixed-length VEC4 array property with normalized UINT32 components", "description": "An example fixed length array property, with type VEC4, with component type UINT32, normalized", "type": "VEC4", "componentType": "UINT32", "array": true, "count": 5, "normalized": true }, "example_INT64_VEC4": { "name": "Example VEC4 property with INT64 components", "description": "An example property, with type VEC4, with component type INT64", "type": "VEC4", "componentType": "INT64", "array": false, "normalized": false }, "example_variable_length_INT64_VEC4_array": { "name": "Example variable-length VEC4 array property with INT64 components", "description": "An example variable length array property, with type VEC4, with component type INT64", "type": "VEC4", "componentType": "INT64", "array": true, "normalized": false }, "example_fixed_length_INT64_VEC4_array": { "name": "Example fixed-length VEC4 array property with INT64 components", "description": "An example fixed length array property, with type VEC4, with component type INT64", "type": "VEC4", "componentType": "INT64", "array": true, "count": 5, "normalized": false }, "example_normalized_INT64_VEC4": { "name": "Example VEC4 property with normalized INT64 components", "description": "An example property, with type VEC4, with component type INT64, normalized", "type": "VEC4", "componentType": "INT64", "array": false, "normalized": true }, "example_variable_length_normalized_INT64_VEC4_array": { "name": "Example variable-length VEC4 array property with normalized INT64 components", "description": "An example variable length array property, with type VEC4, with component type INT64, normalized", "type": "VEC4", "componentType": "INT64", "array": true, "normalized": true }, "example_fixed_length_normalized_INT64_VEC4_array": { "name": "Example fixed-length VEC4 array property with normalized INT64 components", "description": "An example fixed length array property, with type VEC4, with component type INT64, normalized", "type": "VEC4", "componentType": "INT64", "array": true, "count": 5, "normalized": true }, "example_UINT64_VEC4": { "name": "Example VEC4 property with UINT64 components", "description": "An example property, with type VEC4, with component type UINT64", "type": "VEC4", "componentType": "UINT64", "array": false, "normalized": false }, "example_variable_length_UINT64_VEC4_array": { "name": "Example variable-length VEC4 array property with UINT64 components", "description": "An example variable length array property, with type VEC4, with component type UINT64", "type": "VEC4", "componentType": "UINT64", "array": true, "normalized": false }, "example_fixed_length_UINT64_VEC4_array": { "name": "Example fixed-length VEC4 array property with UINT64 components", "description": "An example fixed length array property, with type VEC4, with component type UINT64", "type": "VEC4", "componentType": "UINT64", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT64_VEC4": { "name": "Example VEC4 property with normalized UINT64 components", "description": "An example property, with type VEC4, with component type UINT64, normalized", "type": "VEC4", "componentType": "UINT64", "array": false, "normalized": true }, "example_variable_length_normalized_UINT64_VEC4_array": { "name": "Example variable-length VEC4 array property with normalized UINT64 components", "description": "An example variable length array property, with type VEC4, with component type UINT64, normalized", "type": "VEC4", "componentType": "UINT64", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT64_VEC4_array": { "name": "Example fixed-length VEC4 array property with normalized UINT64 components", "description": "An example fixed length array property, with type VEC4, with component type UINT64, normalized", "type": "VEC4", "componentType": "UINT64", "array": true, "count": 5, "normalized": true }, "example_FLOAT32_VEC4": { "name": "Example VEC4 property with FLOAT32 components", "description": "An example property, with type VEC4, with component type FLOAT32", "type": "VEC4", "componentType": "FLOAT32", "array": false, "normalized": false }, "example_variable_length_FLOAT32_VEC4_array": { "name": "Example variable-length VEC4 array property with FLOAT32 components", "description": "An example variable length array property, with type VEC4, with component type FLOAT32", "type": "VEC4", "componentType": "FLOAT32", "array": true, "normalized": false }, "example_fixed_length_FLOAT32_VEC4_array": { "name": "Example fixed-length VEC4 array property with FLOAT32 components", "description": "An example fixed length array property, with type VEC4, with component type FLOAT32", "type": "VEC4", "componentType": "FLOAT32", "array": true, "count": 5, "normalized": false }, "example_FLOAT64_VEC4": { "name": "Example VEC4 property with FLOAT64 components", "description": "An example property, with type VEC4, with component type FLOAT64", "type": "VEC4", "componentType": "FLOAT64", "array": false, "normalized": false }, "example_variable_length_FLOAT64_VEC4_array": { "name": "Example variable-length VEC4 array property with FLOAT64 components", "description": "An example variable length array property, with type VEC4, with component type FLOAT64", "type": "VEC4", "componentType": "FLOAT64", "array": true, "normalized": false }, "example_fixed_length_FLOAT64_VEC4_array": { "name": "Example fixed-length VEC4 array property with FLOAT64 components", "description": "An example fixed length array property, with type VEC4, with component type FLOAT64", "type": "VEC4", "componentType": "FLOAT64", "array": true, "count": 5, "normalized": false }, "example_INT8_MAT2": { "name": "Example MAT2 property with INT8 components", "description": "An example property, with type MAT2, with component type INT8", "type": "MAT2", "componentType": "INT8", "array": false, "normalized": false }, "example_variable_length_INT8_MAT2_array": { "name": "Example variable-length MAT2 array property with INT8 components", "description": "An example variable length array property, with type MAT2, with component type INT8", "type": "MAT2", "componentType": "INT8", "array": true, "normalized": false }, "example_fixed_length_INT8_MAT2_array": { "name": "Example fixed-length MAT2 array property with INT8 components", "description": "An example fixed length array property, with type MAT2, with component type INT8", "type": "MAT2", "componentType": "INT8", "array": true, "count": 5, "normalized": false }, "example_normalized_INT8_MAT2": { "name": "Example MAT2 property with normalized INT8 components", "description": "An example property, with type MAT2, with component type INT8, normalized", "type": "MAT2", "componentType": "INT8", "array": false, "normalized": true }, "example_variable_length_normalized_INT8_MAT2_array": { "name": "Example variable-length MAT2 array property with normalized INT8 components", "description": "An example variable length array property, with type MAT2, with component type INT8, normalized", "type": "MAT2", "componentType": "INT8", "array": true, "normalized": true }, "example_fixed_length_normalized_INT8_MAT2_array": { "name": "Example fixed-length MAT2 array property with normalized INT8 components", "description": "An example fixed length array property, with type MAT2, with component type INT8, normalized", "type": "MAT2", "componentType": "INT8", "array": true, "count": 5, "normalized": true }, "example_UINT8_MAT2": { "name": "Example MAT2 property with UINT8 components", "description": "An example property, with type MAT2, with component type UINT8", "type": "MAT2", "componentType": "UINT8", "array": false, "normalized": false }, "example_variable_length_UINT8_MAT2_array": { "name": "Example variable-length MAT2 array property with UINT8 components", "description": "An example variable length array property, with type MAT2, with component type UINT8", "type": "MAT2", "componentType": "UINT8", "array": true, "normalized": false }, "example_fixed_length_UINT8_MAT2_array": { "name": "Example fixed-length MAT2 array property with UINT8 components", "description": "An example fixed length array property, with type MAT2, with component type UINT8", "type": "MAT2", "componentType": "UINT8", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT8_MAT2": { "name": "Example MAT2 property with normalized UINT8 components", "description": "An example property, with type MAT2, with component type UINT8, normalized", "type": "MAT2", "componentType": "UINT8", "array": false, "normalized": true }, "example_variable_length_normalized_UINT8_MAT2_array": { "name": "Example variable-length MAT2 array property with normalized UINT8 components", "description": "An example variable length array property, with type MAT2, with component type UINT8, normalized", "type": "MAT2", "componentType": "UINT8", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT8_MAT2_array": { "name": "Example fixed-length MAT2 array property with normalized UINT8 components", "description": "An example fixed length array property, with type MAT2, with component type UINT8, normalized", "type": "MAT2", "componentType": "UINT8", "array": true, "count": 5, "normalized": true }, "example_INT16_MAT2": { "name": "Example MAT2 property with INT16 components", "description": "An example property, with type MAT2, with component type INT16", "type": "MAT2", "componentType": "INT16", "array": false, "normalized": false }, "example_variable_length_INT16_MAT2_array": { "name": "Example variable-length MAT2 array property with INT16 components", "description": "An example variable length array property, with type MAT2, with component type INT16", "type": "MAT2", "componentType": "INT16", "array": true, "normalized": false }, "example_fixed_length_INT16_MAT2_array": { "name": "Example fixed-length MAT2 array property with INT16 components", "description": "An example fixed length array property, with type MAT2, with component type INT16", "type": "MAT2", "componentType": "INT16", "array": true, "count": 5, "normalized": false }, "example_normalized_INT16_MAT2": { "name": "Example MAT2 property with normalized INT16 components", "description": "An example property, with type MAT2, with component type INT16, normalized", "type": "MAT2", "componentType": "INT16", "array": false, "normalized": true }, "example_variable_length_normalized_INT16_MAT2_array": { "name": "Example variable-length MAT2 array property with normalized INT16 components", "description": "An example variable length array property, with type MAT2, with component type INT16, normalized", "type": "MAT2", "componentType": "INT16", "array": true, "normalized": true }, "example_fixed_length_normalized_INT16_MAT2_array": { "name": "Example fixed-length MAT2 array property with normalized INT16 components", "description": "An example fixed length array property, with type MAT2, with component type INT16, normalized", "type": "MAT2", "componentType": "INT16", "array": true, "count": 5, "normalized": true }, "example_UINT16_MAT2": { "name": "Example MAT2 property with UINT16 components", "description": "An example property, with type MAT2, with component type UINT16", "type": "MAT2", "componentType": "UINT16", "array": false, "normalized": false }, "example_variable_length_UINT16_MAT2_array": { "name": "Example variable-length MAT2 array property with UINT16 components", "description": "An example variable length array property, with type MAT2, with component type UINT16", "type": "MAT2", "componentType": "UINT16", "array": true, "normalized": false }, "example_fixed_length_UINT16_MAT2_array": { "name": "Example fixed-length MAT2 array property with UINT16 components", "description": "An example fixed length array property, with type MAT2, with component type UINT16", "type": "MAT2", "componentType": "UINT16", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT16_MAT2": { "name": "Example MAT2 property with normalized UINT16 components", "description": "An example property, with type MAT2, with component type UINT16, normalized", "type": "MAT2", "componentType": "UINT16", "array": false, "normalized": true }, "example_variable_length_normalized_UINT16_MAT2_array": { "name": "Example variable-length MAT2 array property with normalized UINT16 components", "description": "An example variable length array property, with type MAT2, with component type UINT16, normalized", "type": "MAT2", "componentType": "UINT16", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT16_MAT2_array": { "name": "Example fixed-length MAT2 array property with normalized UINT16 components", "description": "An example fixed length array property, with type MAT2, with component type UINT16, normalized", "type": "MAT2", "componentType": "UINT16", "array": true, "count": 5, "normalized": true }, "example_INT32_MAT2": { "name": "Example MAT2 property with INT32 components", "description": "An example property, with type MAT2, with component type INT32", "type": "MAT2", "componentType": "INT32", "array": false, "normalized": false }, "example_variable_length_INT32_MAT2_array": { "name": "Example variable-length MAT2 array property with INT32 components", "description": "An example variable length array property, with type MAT2, with component type INT32", "type": "MAT2", "componentType": "INT32", "array": true, "normalized": false }, "example_fixed_length_INT32_MAT2_array": { "name": "Example fixed-length MAT2 array property with INT32 components", "description": "An example fixed length array property, with type MAT2, with component type INT32", "type": "MAT2", "componentType": "INT32", "array": true, "count": 5, "normalized": false }, "example_normalized_INT32_MAT2": { "name": "Example MAT2 property with normalized INT32 components", "description": "An example property, with type MAT2, with component type INT32, normalized", "type": "MAT2", "componentType": "INT32", "array": false, "normalized": true }, "example_variable_length_normalized_INT32_MAT2_array": { "name": "Example variable-length MAT2 array property with normalized INT32 components", "description": "An example variable length array property, with type MAT2, with component type INT32, normalized", "type": "MAT2", "componentType": "INT32", "array": true, "normalized": true }, "example_fixed_length_normalized_INT32_MAT2_array": { "name": "Example fixed-length MAT2 array property with normalized INT32 components", "description": "An example fixed length array property, with type MAT2, with component type INT32, normalized", "type": "MAT2", "componentType": "INT32", "array": true, "count": 5, "normalized": true }, "example_UINT32_MAT2": { "name": "Example MAT2 property with UINT32 components", "description": "An example property, with type MAT2, with component type UINT32", "type": "MAT2", "componentType": "UINT32", "array": false, "normalized": false }, "example_variable_length_UINT32_MAT2_array": { "name": "Example variable-length MAT2 array property with UINT32 components", "description": "An example variable length array property, with type MAT2, with component type UINT32", "type": "MAT2", "componentType": "UINT32", "array": true, "normalized": false }, "example_fixed_length_UINT32_MAT2_array": { "name": "Example fixed-length MAT2 array property with UINT32 components", "description": "An example fixed length array property, with type MAT2, with component type UINT32", "type": "MAT2", "componentType": "UINT32", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT32_MAT2": { "name": "Example MAT2 property with normalized UINT32 components", "description": "An example property, with type MAT2, with component type UINT32, normalized", "type": "MAT2", "componentType": "UINT32", "array": false, "normalized": true }, "example_variable_length_normalized_UINT32_MAT2_array": { "name": "Example variable-length MAT2 array property with normalized UINT32 components", "description": "An example variable length array property, with type MAT2, with component type UINT32, normalized", "type": "MAT2", "componentType": "UINT32", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT32_MAT2_array": { "name": "Example fixed-length MAT2 array property with normalized UINT32 components", "description": "An example fixed length array property, with type MAT2, with component type UINT32, normalized", "type": "MAT2", "componentType": "UINT32", "array": true, "count": 5, "normalized": true }, "example_INT64_MAT2": { "name": "Example MAT2 property with INT64 components", "description": "An example property, with type MAT2, with component type INT64", "type": "MAT2", "componentType": "INT64", "array": false, "normalized": false }, "example_variable_length_INT64_MAT2_array": { "name": "Example variable-length MAT2 array property with INT64 components", "description": "An example variable length array property, with type MAT2, with component type INT64", "type": "MAT2", "componentType": "INT64", "array": true, "normalized": false }, "example_fixed_length_INT64_MAT2_array": { "name": "Example fixed-length MAT2 array property with INT64 components", "description": "An example fixed length array property, with type MAT2, with component type INT64", "type": "MAT2", "componentType": "INT64", "array": true, "count": 5, "normalized": false }, "example_normalized_INT64_MAT2": { "name": "Example MAT2 property with normalized INT64 components", "description": "An example property, with type MAT2, with component type INT64, normalized", "type": "MAT2", "componentType": "INT64", "array": false, "normalized": true }, "example_variable_length_normalized_INT64_MAT2_array": { "name": "Example variable-length MAT2 array property with normalized INT64 components", "description": "An example variable length array property, with type MAT2, with component type INT64, normalized", "type": "MAT2", "componentType": "INT64", "array": true, "normalized": true }, "example_fixed_length_normalized_INT64_MAT2_array": { "name": "Example fixed-length MAT2 array property with normalized INT64 components", "description": "An example fixed length array property, with type MAT2, with component type INT64, normalized", "type": "MAT2", "componentType": "INT64", "array": true, "count": 5, "normalized": true }, "example_UINT64_MAT2": { "name": "Example MAT2 property with UINT64 components", "description": "An example property, with type MAT2, with component type UINT64", "type": "MAT2", "componentType": "UINT64", "array": false, "normalized": false }, "example_variable_length_UINT64_MAT2_array": { "name": "Example variable-length MAT2 array property with UINT64 components", "description": "An example variable length array property, with type MAT2, with component type UINT64", "type": "MAT2", "componentType": "UINT64", "array": true, "normalized": false }, "example_fixed_length_UINT64_MAT2_array": { "name": "Example fixed-length MAT2 array property with UINT64 components", "description": "An example fixed length array property, with type MAT2, with component type UINT64", "type": "MAT2", "componentType": "UINT64", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT64_MAT2": { "name": "Example MAT2 property with normalized UINT64 components", "description": "An example property, with type MAT2, with component type UINT64, normalized", "type": "MAT2", "componentType": "UINT64", "array": false, "normalized": true }, "example_variable_length_normalized_UINT64_MAT2_array": { "name": "Example variable-length MAT2 array property with normalized UINT64 components", "description": "An example variable length array property, with type MAT2, with component type UINT64, normalized", "type": "MAT2", "componentType": "UINT64", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT64_MAT2_array": { "name": "Example fixed-length MAT2 array property with normalized UINT64 components", "description": "An example fixed length array property, with type MAT2, with component type UINT64, normalized", "type": "MAT2", "componentType": "UINT64", "array": true, "count": 5, "normalized": true }, "example_FLOAT32_MAT2": { "name": "Example MAT2 property with FLOAT32 components", "description": "An example property, with type MAT2, with component type FLOAT32", "type": "MAT2", "componentType": "FLOAT32", "array": false, "normalized": false }, "example_variable_length_FLOAT32_MAT2_array": { "name": "Example variable-length MAT2 array property with FLOAT32 components", "description": "An example variable length array property, with type MAT2, with component type FLOAT32", "type": "MAT2", "componentType": "FLOAT32", "array": true, "normalized": false }, "example_fixed_length_FLOAT32_MAT2_array": { "name": "Example fixed-length MAT2 array property with FLOAT32 components", "description": "An example fixed length array property, with type MAT2, with component type FLOAT32", "type": "MAT2", "componentType": "FLOAT32", "array": true, "count": 5, "normalized": false }, "example_FLOAT64_MAT2": { "name": "Example MAT2 property with FLOAT64 components", "description": "An example property, with type MAT2, with component type FLOAT64", "type": "MAT2", "componentType": "FLOAT64", "array": false, "normalized": false }, "example_variable_length_FLOAT64_MAT2_array": { "name": "Example variable-length MAT2 array property with FLOAT64 components", "description": "An example variable length array property, with type MAT2, with component type FLOAT64", "type": "MAT2", "componentType": "FLOAT64", "array": true, "normalized": false }, "example_fixed_length_FLOAT64_MAT2_array": { "name": "Example fixed-length MAT2 array property with FLOAT64 components", "description": "An example fixed length array property, with type MAT2, with component type FLOAT64", "type": "MAT2", "componentType": "FLOAT64", "array": true, "count": 5, "normalized": false }, "example_INT8_MAT3": { "name": "Example MAT3 property with INT8 components", "description": "An example property, with type MAT3, with component type INT8", "type": "MAT3", "componentType": "INT8", "array": false, "normalized": false }, "example_variable_length_INT8_MAT3_array": { "name": "Example variable-length MAT3 array property with INT8 components", "description": "An example variable length array property, with type MAT3, with component type INT8", "type": "MAT3", "componentType": "INT8", "array": true, "normalized": false }, "example_fixed_length_INT8_MAT3_array": { "name": "Example fixed-length MAT3 array property with INT8 components", "description": "An example fixed length array property, with type MAT3, with component type INT8", "type": "MAT3", "componentType": "INT8", "array": true, "count": 5, "normalized": false }, "example_normalized_INT8_MAT3": { "name": "Example MAT3 property with normalized INT8 components", "description": "An example property, with type MAT3, with component type INT8, normalized", "type": "MAT3", "componentType": "INT8", "array": false, "normalized": true }, "example_variable_length_normalized_INT8_MAT3_array": { "name": "Example variable-length MAT3 array property with normalized INT8 components", "description": "An example variable length array property, with type MAT3, with component type INT8, normalized", "type": "MAT3", "componentType": "INT8", "array": true, "normalized": true }, "example_fixed_length_normalized_INT8_MAT3_array": { "name": "Example fixed-length MAT3 array property with normalized INT8 components", "description": "An example fixed length array property, with type MAT3, with component type INT8, normalized", "type": "MAT3", "componentType": "INT8", "array": true, "count": 5, "normalized": true }, "example_UINT8_MAT3": { "name": "Example MAT3 property with UINT8 components", "description": "An example property, with type MAT3, with component type UINT8", "type": "MAT3", "componentType": "UINT8", "array": false, "normalized": false }, "example_variable_length_UINT8_MAT3_array": { "name": "Example variable-length MAT3 array property with UINT8 components", "description": "An example variable length array property, with type MAT3, with component type UINT8", "type": "MAT3", "componentType": "UINT8", "array": true, "normalized": false }, "example_fixed_length_UINT8_MAT3_array": { "name": "Example fixed-length MAT3 array property with UINT8 components", "description": "An example fixed length array property, with type MAT3, with component type UINT8", "type": "MAT3", "componentType": "UINT8", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT8_MAT3": { "name": "Example MAT3 property with normalized UINT8 components", "description": "An example property, with type MAT3, with component type UINT8, normalized", "type": "MAT3", "componentType": "UINT8", "array": false, "normalized": true }, "example_variable_length_normalized_UINT8_MAT3_array": { "name": "Example variable-length MAT3 array property with normalized UINT8 components", "description": "An example variable length array property, with type MAT3, with component type UINT8, normalized", "type": "MAT3", "componentType": "UINT8", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT8_MAT3_array": { "name": "Example fixed-length MAT3 array property with normalized UINT8 components", "description": "An example fixed length array property, with type MAT3, with component type UINT8, normalized", "type": "MAT3", "componentType": "UINT8", "array": true, "count": 5, "normalized": true }, "example_INT16_MAT3": { "name": "Example MAT3 property with INT16 components", "description": "An example property, with type MAT3, with component type INT16", "type": "MAT3", "componentType": "INT16", "array": false, "normalized": false }, "example_variable_length_INT16_MAT3_array": { "name": "Example variable-length MAT3 array property with INT16 components", "description": "An example variable length array property, with type MAT3, with component type INT16", "type": "MAT3", "componentType": "INT16", "array": true, "normalized": false }, "example_fixed_length_INT16_MAT3_array": { "name": "Example fixed-length MAT3 array property with INT16 components", "description": "An example fixed length array property, with type MAT3, with component type INT16", "type": "MAT3", "componentType": "INT16", "array": true, "count": 5, "normalized": false }, "example_normalized_INT16_MAT3": { "name": "Example MAT3 property with normalized INT16 components", "description": "An example property, with type MAT3, with component type INT16, normalized", "type": "MAT3", "componentType": "INT16", "array": false, "normalized": true }, "example_variable_length_normalized_INT16_MAT3_array": { "name": "Example variable-length MAT3 array property with normalized INT16 components", "description": "An example variable length array property, with type MAT3, with component type INT16, normalized", "type": "MAT3", "componentType": "INT16", "array": true, "normalized": true }, "example_fixed_length_normalized_INT16_MAT3_array": { "name": "Example fixed-length MAT3 array property with normalized INT16 components", "description": "An example fixed length array property, with type MAT3, with component type INT16, normalized", "type": "MAT3", "componentType": "INT16", "array": true, "count": 5, "normalized": true }, "example_UINT16_MAT3": { "name": "Example MAT3 property with UINT16 components", "description": "An example property, with type MAT3, with component type UINT16", "type": "MAT3", "componentType": "UINT16", "array": false, "normalized": false }, "example_variable_length_UINT16_MAT3_array": { "name": "Example variable-length MAT3 array property with UINT16 components", "description": "An example variable length array property, with type MAT3, with component type UINT16", "type": "MAT3", "componentType": "UINT16", "array": true, "normalized": false }, "example_fixed_length_UINT16_MAT3_array": { "name": "Example fixed-length MAT3 array property with UINT16 components", "description": "An example fixed length array property, with type MAT3, with component type UINT16", "type": "MAT3", "componentType": "UINT16", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT16_MAT3": { "name": "Example MAT3 property with normalized UINT16 components", "description": "An example property, with type MAT3, with component type UINT16, normalized", "type": "MAT3", "componentType": "UINT16", "array": false, "normalized": true }, "example_variable_length_normalized_UINT16_MAT3_array": { "name": "Example variable-length MAT3 array property with normalized UINT16 components", "description": "An example variable length array property, with type MAT3, with component type UINT16, normalized", "type": "MAT3", "componentType": "UINT16", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT16_MAT3_array": { "name": "Example fixed-length MAT3 array property with normalized UINT16 components", "description": "An example fixed length array property, with type MAT3, with component type UINT16, normalized", "type": "MAT3", "componentType": "UINT16", "array": true, "count": 5, "normalized": true }, "example_INT32_MAT3": { "name": "Example MAT3 property with INT32 components", "description": "An example property, with type MAT3, with component type INT32", "type": "MAT3", "componentType": "INT32", "array": false, "normalized": false }, "example_variable_length_INT32_MAT3_array": { "name": "Example variable-length MAT3 array property with INT32 components", "description": "An example variable length array property, with type MAT3, with component type INT32", "type": "MAT3", "componentType": "INT32", "array": true, "normalized": false }, "example_fixed_length_INT32_MAT3_array": { "name": "Example fixed-length MAT3 array property with INT32 components", "description": "An example fixed length array property, with type MAT3, with component type INT32", "type": "MAT3", "componentType": "INT32", "array": true, "count": 5, "normalized": false }, "example_normalized_INT32_MAT3": { "name": "Example MAT3 property with normalized INT32 components", "description": "An example property, with type MAT3, with component type INT32, normalized", "type": "MAT3", "componentType": "INT32", "array": false, "normalized": true }, "example_variable_length_normalized_INT32_MAT3_array": { "name": "Example variable-length MAT3 array property with normalized INT32 components", "description": "An example variable length array property, with type MAT3, with component type INT32, normalized", "type": "MAT3", "componentType": "INT32", "array": true, "normalized": true }, "example_fixed_length_normalized_INT32_MAT3_array": { "name": "Example fixed-length MAT3 array property with normalized INT32 components", "description": "An example fixed length array property, with type MAT3, with component type INT32, normalized", "type": "MAT3", "componentType": "INT32", "array": true, "count": 5, "normalized": true }, "example_UINT32_MAT3": { "name": "Example MAT3 property with UINT32 components", "description": "An example property, with type MAT3, with component type UINT32", "type": "MAT3", "componentType": "UINT32", "array": false, "normalized": false }, "example_variable_length_UINT32_MAT3_array": { "name": "Example variable-length MAT3 array property with UINT32 components", "description": "An example variable length array property, with type MAT3, with component type UINT32", "type": "MAT3", "componentType": "UINT32", "array": true, "normalized": false }, "example_fixed_length_UINT32_MAT3_array": { "name": "Example fixed-length MAT3 array property with UINT32 components", "description": "An example fixed length array property, with type MAT3, with component type UINT32", "type": "MAT3", "componentType": "UINT32", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT32_MAT3": { "name": "Example MAT3 property with normalized UINT32 components", "description": "An example property, with type MAT3, with component type UINT32, normalized", "type": "MAT3", "componentType": "UINT32", "array": false, "normalized": true }, "example_variable_length_normalized_UINT32_MAT3_array": { "name": "Example variable-length MAT3 array property with normalized UINT32 components", "description": "An example variable length array property, with type MAT3, with component type UINT32, normalized", "type": "MAT3", "componentType": "UINT32", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT32_MAT3_array": { "name": "Example fixed-length MAT3 array property with normalized UINT32 components", "description": "An example fixed length array property, with type MAT3, with component type UINT32, normalized", "type": "MAT3", "componentType": "UINT32", "array": true, "count": 5, "normalized": true }, "example_INT64_MAT3": { "name": "Example MAT3 property with INT64 components", "description": "An example property, with type MAT3, with component type INT64", "type": "MAT3", "componentType": "INT64", "array": false, "normalized": false }, "example_variable_length_INT64_MAT3_array": { "name": "Example variable-length MAT3 array property with INT64 components", "description": "An example variable length array property, with type MAT3, with component type INT64", "type": "MAT3", "componentType": "INT64", "array": true, "normalized": false }, "example_fixed_length_INT64_MAT3_array": { "name": "Example fixed-length MAT3 array property with INT64 components", "description": "An example fixed length array property, with type MAT3, with component type INT64", "type": "MAT3", "componentType": "INT64", "array": true, "count": 5, "normalized": false }, "example_normalized_INT64_MAT3": { "name": "Example MAT3 property with normalized INT64 components", "description": "An example property, with type MAT3, with component type INT64, normalized", "type": "MAT3", "componentType": "INT64", "array": false, "normalized": true }, "example_variable_length_normalized_INT64_MAT3_array": { "name": "Example variable-length MAT3 array property with normalized INT64 components", "description": "An example variable length array property, with type MAT3, with component type INT64, normalized", "type": "MAT3", "componentType": "INT64", "array": true, "normalized": true }, "example_fixed_length_normalized_INT64_MAT3_array": { "name": "Example fixed-length MAT3 array property with normalized INT64 components", "description": "An example fixed length array property, with type MAT3, with component type INT64, normalized", "type": "MAT3", "componentType": "INT64", "array": true, "count": 5, "normalized": true }, "example_UINT64_MAT3": { "name": "Example MAT3 property with UINT64 components", "description": "An example property, with type MAT3, with component type UINT64", "type": "MAT3", "componentType": "UINT64", "array": false, "normalized": false }, "example_variable_length_UINT64_MAT3_array": { "name": "Example variable-length MAT3 array property with UINT64 components", "description": "An example variable length array property, with type MAT3, with component type UINT64", "type": "MAT3", "componentType": "UINT64", "array": true, "normalized": false }, "example_fixed_length_UINT64_MAT3_array": { "name": "Example fixed-length MAT3 array property with UINT64 components", "description": "An example fixed length array property, with type MAT3, with component type UINT64", "type": "MAT3", "componentType": "UINT64", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT64_MAT3": { "name": "Example MAT3 property with normalized UINT64 components", "description": "An example property, with type MAT3, with component type UINT64, normalized", "type": "MAT3", "componentType": "UINT64", "array": false, "normalized": true }, "example_variable_length_normalized_UINT64_MAT3_array": { "name": "Example variable-length MAT3 array property with normalized UINT64 components", "description": "An example variable length array property, with type MAT3, with component type UINT64, normalized", "type": "MAT3", "componentType": "UINT64", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT64_MAT3_array": { "name": "Example fixed-length MAT3 array property with normalized UINT64 components", "description": "An example fixed length array property, with type MAT3, with component type UINT64, normalized", "type": "MAT3", "componentType": "UINT64", "array": true, "count": 5, "normalized": true }, "example_FLOAT32_MAT3": { "name": "Example MAT3 property with FLOAT32 components", "description": "An example property, with type MAT3, with component type FLOAT32", "type": "MAT3", "componentType": "FLOAT32", "array": false, "normalized": false }, "example_variable_length_FLOAT32_MAT3_array": { "name": "Example variable-length MAT3 array property with FLOAT32 components", "description": "An example variable length array property, with type MAT3, with component type FLOAT32", "type": "MAT3", "componentType": "FLOAT32", "array": true, "normalized": false }, "example_fixed_length_FLOAT32_MAT3_array": { "name": "Example fixed-length MAT3 array property with FLOAT32 components", "description": "An example fixed length array property, with type MAT3, with component type FLOAT32", "type": "MAT3", "componentType": "FLOAT32", "array": true, "count": 5, "normalized": false }, "example_FLOAT64_MAT3": { "name": "Example MAT3 property with FLOAT64 components", "description": "An example property, with type MAT3, with component type FLOAT64", "type": "MAT3", "componentType": "FLOAT64", "array": false, "normalized": false }, "example_variable_length_FLOAT64_MAT3_array": { "name": "Example variable-length MAT3 array property with FLOAT64 components", "description": "An example variable length array property, with type MAT3, with component type FLOAT64", "type": "MAT3", "componentType": "FLOAT64", "array": true, "normalized": false }, "example_fixed_length_FLOAT64_MAT3_array": { "name": "Example fixed-length MAT3 array property with FLOAT64 components", "description": "An example fixed length array property, with type MAT3, with component type FLOAT64", "type": "MAT3", "componentType": "FLOAT64", "array": true, "count": 5, "normalized": false }, "example_INT8_MAT4": { "name": "Example MAT4 property with INT8 components", "description": "An example property, with type MAT4, with component type INT8", "type": "MAT4", "componentType": "INT8", "array": false, "normalized": false }, "example_variable_length_INT8_MAT4_array": { "name": "Example variable-length MAT4 array property with INT8 components", "description": "An example variable length array property, with type MAT4, with component type INT8", "type": "MAT4", "componentType": "INT8", "array": true, "normalized": false }, "example_fixed_length_INT8_MAT4_array": { "name": "Example fixed-length MAT4 array property with INT8 components", "description": "An example fixed length array property, with type MAT4, with component type INT8", "type": "MAT4", "componentType": "INT8", "array": true, "count": 5, "normalized": false }, "example_normalized_INT8_MAT4": { "name": "Example MAT4 property with normalized INT8 components", "description": "An example property, with type MAT4, with component type INT8, normalized", "type": "MAT4", "componentType": "INT8", "array": false, "normalized": true }, "example_variable_length_normalized_INT8_MAT4_array": { "name": "Example variable-length MAT4 array property with normalized INT8 components", "description": "An example variable length array property, with type MAT4, with component type INT8, normalized", "type": "MAT4", "componentType": "INT8", "array": true, "normalized": true }, "example_fixed_length_normalized_INT8_MAT4_array": { "name": "Example fixed-length MAT4 array property with normalized INT8 components", "description": "An example fixed length array property, with type MAT4, with component type INT8, normalized", "type": "MAT4", "componentType": "INT8", "array": true, "count": 5, "normalized": true }, "example_UINT8_MAT4": { "name": "Example MAT4 property with UINT8 components", "description": "An example property, with type MAT4, with component type UINT8", "type": "MAT4", "componentType": "UINT8", "array": false, "normalized": false }, "example_variable_length_UINT8_MAT4_array": { "name": "Example variable-length MAT4 array property with UINT8 components", "description": "An example variable length array property, with type MAT4, with component type UINT8", "type": "MAT4", "componentType": "UINT8", "array": true, "normalized": false }, "example_fixed_length_UINT8_MAT4_array": { "name": "Example fixed-length MAT4 array property with UINT8 components", "description": "An example fixed length array property, with type MAT4, with component type UINT8", "type": "MAT4", "componentType": "UINT8", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT8_MAT4": { "name": "Example MAT4 property with normalized UINT8 components", "description": "An example property, with type MAT4, with component type UINT8, normalized", "type": "MAT4", "componentType": "UINT8", "array": false, "normalized": true }, "example_variable_length_normalized_UINT8_MAT4_array": { "name": "Example variable-length MAT4 array property with normalized UINT8 components", "description": "An example variable length array property, with type MAT4, with component type UINT8, normalized", "type": "MAT4", "componentType": "UINT8", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT8_MAT4_array": { "name": "Example fixed-length MAT4 array property with normalized UINT8 components", "description": "An example fixed length array property, with type MAT4, with component type UINT8, normalized", "type": "MAT4", "componentType": "UINT8", "array": true, "count": 5, "normalized": true }, "example_INT16_MAT4": { "name": "Example MAT4 property with INT16 components", "description": "An example property, with type MAT4, with component type INT16", "type": "MAT4", "componentType": "INT16", "array": false, "normalized": false }, "example_variable_length_INT16_MAT4_array": { "name": "Example variable-length MAT4 array property with INT16 components", "description": "An example variable length array property, with type MAT4, with component type INT16", "type": "MAT4", "componentType": "INT16", "array": true, "normalized": false }, "example_fixed_length_INT16_MAT4_array": { "name": "Example fixed-length MAT4 array property with INT16 components", "description": "An example fixed length array property, with type MAT4, with component type INT16", "type": "MAT4", "componentType": "INT16", "array": true, "count": 5, "normalized": false }, "example_normalized_INT16_MAT4": { "name": "Example MAT4 property with normalized INT16 components", "description": "An example property, with type MAT4, with component type INT16, normalized", "type": "MAT4", "componentType": "INT16", "array": false, "normalized": true }, "example_variable_length_normalized_INT16_MAT4_array": { "name": "Example variable-length MAT4 array property with normalized INT16 components", "description": "An example variable length array property, with type MAT4, with component type INT16, normalized", "type": "MAT4", "componentType": "INT16", "array": true, "normalized": true }, "example_fixed_length_normalized_INT16_MAT4_array": { "name": "Example fixed-length MAT4 array property with normalized INT16 components", "description": "An example fixed length array property, with type MAT4, with component type INT16, normalized", "type": "MAT4", "componentType": "INT16", "array": true, "count": 5, "normalized": true }, "example_UINT16_MAT4": { "name": "Example MAT4 property with UINT16 components", "description": "An example property, with type MAT4, with component type UINT16", "type": "MAT4", "componentType": "UINT16", "array": false, "normalized": false }, "example_variable_length_UINT16_MAT4_array": { "name": "Example variable-length MAT4 array property with UINT16 components", "description": "An example variable length array property, with type MAT4, with component type UINT16", "type": "MAT4", "componentType": "UINT16", "array": true, "normalized": false }, "example_fixed_length_UINT16_MAT4_array": { "name": "Example fixed-length MAT4 array property with UINT16 components", "description": "An example fixed length array property, with type MAT4, with component type UINT16", "type": "MAT4", "componentType": "UINT16", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT16_MAT4": { "name": "Example MAT4 property with normalized UINT16 components", "description": "An example property, with type MAT4, with component type UINT16, normalized", "type": "MAT4", "componentType": "UINT16", "array": false, "normalized": true }, "example_variable_length_normalized_UINT16_MAT4_array": { "name": "Example variable-length MAT4 array property with normalized UINT16 components", "description": "An example variable length array property, with type MAT4, with component type UINT16, normalized", "type": "MAT4", "componentType": "UINT16", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT16_MAT4_array": { "name": "Example fixed-length MAT4 array property with normalized UINT16 components", "description": "An example fixed length array property, with type MAT4, with component type UINT16, normalized", "type": "MAT4", "componentType": "UINT16", "array": true, "count": 5, "normalized": true }, "example_INT32_MAT4": { "name": "Example MAT4 property with INT32 components", "description": "An example property, with type MAT4, with component type INT32", "type": "MAT4", "componentType": "INT32", "array": false, "normalized": false }, "example_variable_length_INT32_MAT4_array": { "name": "Example variable-length MAT4 array property with INT32 components", "description": "An example variable length array property, with type MAT4, with component type INT32", "type": "MAT4", "componentType": "INT32", "array": true, "normalized": false }, "example_fixed_length_INT32_MAT4_array": { "name": "Example fixed-length MAT4 array property with INT32 components", "description": "An example fixed length array property, with type MAT4, with component type INT32", "type": "MAT4", "componentType": "INT32", "array": true, "count": 5, "normalized": false }, "example_normalized_INT32_MAT4": { "name": "Example MAT4 property with normalized INT32 components", "description": "An example property, with type MAT4, with component type INT32, normalized", "type": "MAT4", "componentType": "INT32", "array": false, "normalized": true }, "example_variable_length_normalized_INT32_MAT4_array": { "name": "Example variable-length MAT4 array property with normalized INT32 components", "description": "An example variable length array property, with type MAT4, with component type INT32, normalized", "type": "MAT4", "componentType": "INT32", "array": true, "normalized": true }, "example_fixed_length_normalized_INT32_MAT4_array": { "name": "Example fixed-length MAT4 array property with normalized INT32 components", "description": "An example fixed length array property, with type MAT4, with component type INT32, normalized", "type": "MAT4", "componentType": "INT32", "array": true, "count": 5, "normalized": true }, "example_UINT32_MAT4": { "name": "Example MAT4 property with UINT32 components", "description": "An example property, with type MAT4, with component type UINT32", "type": "MAT4", "componentType": "UINT32", "array": false, "normalized": false }, "example_variable_length_UINT32_MAT4_array": { "name": "Example variable-length MAT4 array property with UINT32 components", "description": "An example variable length array property, with type MAT4, with component type UINT32", "type": "MAT4", "componentType": "UINT32", "array": true, "normalized": false }, "example_fixed_length_UINT32_MAT4_array": { "name": "Example fixed-length MAT4 array property with UINT32 components", "description": "An example fixed length array property, with type MAT4, with component type UINT32", "type": "MAT4", "componentType": "UINT32", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT32_MAT4": { "name": "Example MAT4 property with normalized UINT32 components", "description": "An example property, with type MAT4, with component type UINT32, normalized", "type": "MAT4", "componentType": "UINT32", "array": false, "normalized": true }, "example_variable_length_normalized_UINT32_MAT4_array": { "name": "Example variable-length MAT4 array property with normalized UINT32 components", "description": "An example variable length array property, with type MAT4, with component type UINT32, normalized", "type": "MAT4", "componentType": "UINT32", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT32_MAT4_array": { "name": "Example fixed-length MAT4 array property with normalized UINT32 components", "description": "An example fixed length array property, with type MAT4, with component type UINT32, normalized", "type": "MAT4", "componentType": "UINT32", "array": true, "count": 5, "normalized": true }, "example_INT64_MAT4": { "name": "Example MAT4 property with INT64 components", "description": "An example property, with type MAT4, with component type INT64", "type": "MAT4", "componentType": "INT64", "array": false, "normalized": false }, "example_variable_length_INT64_MAT4_array": { "name": "Example variable-length MAT4 array property with INT64 components", "description": "An example variable length array property, with type MAT4, with component type INT64", "type": "MAT4", "componentType": "INT64", "array": true, "normalized": false }, "example_fixed_length_INT64_MAT4_array": { "name": "Example fixed-length MAT4 array property with INT64 components", "description": "An example fixed length array property, with type MAT4, with component type INT64", "type": "MAT4", "componentType": "INT64", "array": true, "count": 5, "normalized": false }, "example_normalized_INT64_MAT4": { "name": "Example MAT4 property with normalized INT64 components", "description": "An example property, with type MAT4, with component type INT64, normalized", "type": "MAT4", "componentType": "INT64", "array": false, "normalized": true }, "example_variable_length_normalized_INT64_MAT4_array": { "name": "Example variable-length MAT4 array property with normalized INT64 components", "description": "An example variable length array property, with type MAT4, with component type INT64, normalized", "type": "MAT4", "componentType": "INT64", "array": true, "normalized": true }, "example_fixed_length_normalized_INT64_MAT4_array": { "name": "Example fixed-length MAT4 array property with normalized INT64 components", "description": "An example fixed length array property, with type MAT4, with component type INT64, normalized", "type": "MAT4", "componentType": "INT64", "array": true, "count": 5, "normalized": true }, "example_UINT64_MAT4": { "name": "Example MAT4 property with UINT64 components", "description": "An example property, with type MAT4, with component type UINT64", "type": "MAT4", "componentType": "UINT64", "array": false, "normalized": false }, "example_variable_length_UINT64_MAT4_array": { "name": "Example variable-length MAT4 array property with UINT64 components", "description": "An example variable length array property, with type MAT4, with component type UINT64", "type": "MAT4", "componentType": "UINT64", "array": true, "normalized": false }, "example_fixed_length_UINT64_MAT4_array": { "name": "Example fixed-length MAT4 array property with UINT64 components", "description": "An example fixed length array property, with type MAT4, with component type UINT64", "type": "MAT4", "componentType": "UINT64", "array": true, "count": 5, "normalized": false }, "example_normalized_UINT64_MAT4": { "name": "Example MAT4 property with normalized UINT64 components", "description": "An example property, with type MAT4, with component type UINT64, normalized", "type": "MAT4", "componentType": "UINT64", "array": false, "normalized": true }, "example_variable_length_normalized_UINT64_MAT4_array": { "name": "Example variable-length MAT4 array property with normalized UINT64 components", "description": "An example variable length array property, with type MAT4, with component type UINT64, normalized", "type": "MAT4", "componentType": "UINT64", "array": true, "normalized": true }, "example_fixed_length_normalized_UINT64_MAT4_array": { "name": "Example fixed-length MAT4 array property with normalized UINT64 components", "description": "An example fixed length array property, with type MAT4, with component type UINT64, normalized", "type": "MAT4", "componentType": "UINT64", "array": true, "count": 5, "normalized": true }, "example_FLOAT32_MAT4": { "name": "Example MAT4 property with FLOAT32 components", "description": "An example property, with type MAT4, with component type FLOAT32", "type": "MAT4", "componentType": "FLOAT32", "array": false, "normalized": false }, "example_variable_length_FLOAT32_MAT4_array": { "name": "Example variable-length MAT4 array property with FLOAT32 components", "description": "An example variable length array property, with type MAT4, with component type FLOAT32", "type": "MAT4", "componentType": "FLOAT32", "array": true, "normalized": false }, "example_fixed_length_FLOAT32_MAT4_array": { "name": "Example fixed-length MAT4 array property with FLOAT32 components", "description": "An example fixed length array property, with type MAT4, with component type FLOAT32", "type": "MAT4", "componentType": "FLOAT32", "array": true, "count": 5, "normalized": false }, "example_FLOAT64_MAT4": { "name": "Example MAT4 property with FLOAT64 components", "description": "An example property, with type MAT4, with component type FLOAT64", "type": "MAT4", "componentType": "FLOAT64", "array": false, "normalized": false }, "example_variable_length_FLOAT64_MAT4_array": { "name": "Example variable-length MAT4 array property with FLOAT64 components", "description": "An example variable length array property, with type MAT4, with component type FLOAT64", "type": "MAT4", "componentType": "FLOAT64", "array": true, "normalized": false }, "example_fixed_length_FLOAT64_MAT4_array": { "name": "Example fixed-length MAT4 array property with FLOAT64 components", "description": "An example fixed length array property, with type MAT4, with component type FLOAT64", "type": "MAT4", "componentType": "FLOAT64", "array": true, "count": 5, "normalized": false } } } }, "enums" : { "exampleEnumType" : { "values" : [ { "name" : "ExampleEnumValueA", "value" : 0 }, { "name" : "ExampleEnumValueB", "value" : 1 }, { "name" : "ExampleEnumValueC", "value" : 2 } ] } } } ================================================ FILE: specs/data/schemas/metadataClassDescriptionInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "description": 123.456 } } } ================================================ FILE: specs/data/schemas/metadataClassNameInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "name": 123.456 } } } ================================================ FILE: specs/data/schemas/metadataClassPropertiesDuplicateSemantics.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "examplePropertyA": { "type": "SCALAR", "componentType": "FLOAT32", "semantic": "TILE_GEOMETRIC_ERROR" }, "examplePropertyB": { "type": "SCALAR", "componentType": "FLOAT32", "semantic": "TILE_GEOMETRIC_ERROR" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertiesEmpty.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": {} } } } ================================================ FILE: specs/data/schemas/metadataClassPropertiesNameInvalid.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "!!! NOT A VALID IDENTIFIER !!!": { "type": "SCALAR", "componentType": "FLOAT32" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyArrayInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "array": "NOT_A_BOOLEAN" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyComponentTypeForTypeWithoutComponents.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "componentType": "UINT8" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyComponentTypeInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": 123.456 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyComponentTypeInvalidValue.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "NOT_A_VALID_COMPONENT_TYPE" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyComponentTypeMissing.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyCountInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "array": true, "count": "NOT_A_NUMBER" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyCountInvalidValue.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "array": true, "count": 1 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyCountWithoutArray.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "array": false, "count": 5 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyDefaultWithRequired.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "required": true, "default": "example" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyDescriptionInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "description": 123.456, "type": "SCALAR", "componentType": "FLOAT32" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyEnumTypeForNonEnumType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "enumType": "exampleEnum" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyEnumTypeInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "ENUM", "enumType": 123.456 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyEnumTypeMissingForEnumType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "ENUM" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyEnumTypeNotFound.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "ENUM", "enumType": "INVALID_ENUM_TYPE" } } } }, "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyEnumTypeWithoutEnums.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "ENUM", "enumType": "exampleEnum" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyMaxForNonNumericType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "max": 1.0 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyMinForNonNumericType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "min": 1.0 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyMinForVariableLengthArray.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "offset": 1.0, "array": true } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNameInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "name": 123.456, "type": "SCALAR", "componentType": "FLOAT32" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNoDataForBoolean.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "BOOLEAN", "noData": true } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNoDataInvalidEnumValueName.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "ENUM", "enumType": "exampleEnum", "noData": "INVALID_ENUM_VALUE_NAME" } } } }, "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNoDataInvalidEnumValueNames.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "ENUM", "enumType": "exampleEnum", "array": true, "noData": [ "EXAMPLE_ENUM_VALUE_A", "INVALID_ENUM_VALUE_NAME", "EXAMPLE_ENUM_VALUE_B" ] } } } }, "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNoDataTypeMismatchA.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "noData": 123 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNoDataTypeMismatchB.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "array": true, "count": 2, "noData": ["A", "B", "C"] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNoDataTypeMismatchC.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "array": true, "count": 3, "noData": [1.0, "NOT_A_NUMBER", 3.0] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNoDataWithRequired.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "required": true, "noData": "example" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNormalizedForNonIntegerComponentType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "normalized": true } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNormalizedForUnnormalizableType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "normalized": true } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyNormalizedInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "INT32", "normalized": "NOT_A_BOOLEAN" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetForNonFloatingPointTypeA.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "offset": 1.0 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetForNonFloatingPointTypeB.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "MAT2", "componentType": "UINT16", "offset": [1.0,1.0,1.0,1.0] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetForVariableLengthArray.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "offset": 1.0, "array": true } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetTypeMismatchA.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "offset": [1.0,1.0,1.0,1.0] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetTypeMismatchB.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "VEC2", "componentType": "FLOAT32", "offset": 1.0 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetTypeMismatchC.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "VEC2", "componentType": "FLOAT32", "offset": [1.0,1.0,1.0] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetTypeMismatchD.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "VEC2", "componentType": "FLOAT32", "offset": [1.0,"Not a number"] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetTypeMismatchE.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "MAT3", "componentType": "FLOAT32", "offset": [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,123.456] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetTypeMismatchF.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "array": true, "count": 5, "offset": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyOffsetTypeMismatchG.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "VEC2", "componentType": "FLOAT32", "array": true, "count": 5, "offset": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyRequiredInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "required": "NOT_A_BOOLEAN" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyScaleForNonFloatingPointType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "scale": 2.0 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyScaleForNonFloatingPointTypeB.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "MAT2", "componentType": "UINT16", "scale": [2.0,3.0,4.0,5.0] } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticArrayMismatchA.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "array": true, "semantic": "TILE_GEOMETRIC_ERROR" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticArrayMismatchB.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "semantic": "TILE_BOUNDING_BOX" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchA.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "INT32", "semantic": "TILE_GEOMETRIC_ERROR" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchB.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "INT32", "array": true, "semantic": "ATTRIBUTION_IDS" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticCountMismatch.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "semantic": "TILE_BOUNDING_BOX", "array": true, "count": 42 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticGeneric.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "STRING", "array": true, "semantic": "ATTRIBUTION_STRINGS" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "semantic": 12345 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticNormalizedMismatch.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "UINT8", "normalized": true, "semantic": "TILE_REFINE" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticTypeMismatch.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "VEC2", "componentType": "FLOAT32", "semantic": "TILE_GEOMETRIC_ERROR" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertySemanticUnknown.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "semantic": "UNKNOWN_SEMANTIC" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyTypeInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": 123.456 } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyTypeInvalidValue.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "NOT_A_VALID_TYPE" } } } } } ================================================ FILE: specs/data/schemas/metadataClassPropertyTypeMissing.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": {} } } } } ================================================ FILE: specs/data/schemas/metadataClassesInvalidType.json ================================================ { "id": "EXAMPLE_ID", "classes": { "exampleClass": "Should be an object" } } ================================================ FILE: specs/data/schemas/metadataClassesNameInvalid.json ================================================ { "id": "EXAMPLE_ID", "classes": { "!!! NOT A VALID IDENTIFIER !!!": {} } } ================================================ FILE: specs/data/schemas/metadataEnumDescriptionInvalidType.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "description": 123.456, "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumNameInvalidType.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "name": 123.456, "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValueDescriptionInvalidType.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "description": 123.456, "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValueNameInvalidType.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "values": [ { "name": 123.456, "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValueNotInDefaultValueTypeRange.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 99999 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValueNotInValueTypeRange.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "valueType": "INT8", "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": -999 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": -10 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValueTypeInvalid.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "values": ["Should be an object"] } } } ================================================ FILE: specs/data/schemas/metadataEnumValueTypeInvalidType.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "valueType": 123.456, "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValueTypeInvalidValue.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "valueType": "NOT_A_VALID_VALUE_TYPE", "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValueValueInvalidType.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": "Should be a number" }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 123.456 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValuesDuplicateName.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_A", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValuesDuplicateValue.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 0 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumValuesEmpty.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": { "values": [] } } } ================================================ FILE: specs/data/schemas/metadataEnumValuesMissing.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": {} } } ================================================ FILE: specs/data/schemas/metadataEnumsInvalidName.json ================================================ { "id": "EXAMPLE_ID", "enums": { "!!! NOT A VALID IDENTIFIER !!!": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/metadataEnumsInvalidType.json ================================================ { "id": "EXAMPLE_ID", "enums": { "exampleEnum": "Should be an object" } } ================================================ FILE: specs/data/schemas/schemaIdInvalidType.json ================================================ { "id": 123.456 } ================================================ FILE: specs/data/schemas/schemaIdInvalidValue.json ================================================ { "id": "!!! NOT AN ID STRING !!!" } ================================================ FILE: specs/data/schemas/schemaIdMissing.json ================================================ { } ================================================ FILE: specs/data/schemas/validSchema.json ================================================ { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "examplePropertyInt16": { "name": "Name of examplePropertyInt16", "description": "Description for examplePropertyInt16", "type": "SCALAR", "componentType": "INT16" }, "examplePropertyEnum": { "name": "Name of examplePropertyEnum", "description": "Description for examplePropertyEnum", "type": "ENUM", "enumType": "exampleEnum" } } } }, "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } } ================================================ FILE: specs/data/schemas/validSchemaWithMinMax.json ================================================ { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "VEC2", "componentType": "FLOAT32", "min": [0.0, 0.0], "max": [1.0, 1.0] } } } } } ================================================ FILE: specs/data/subtrees/subtreeBufferViewsWithoutBuffers.json ================================================ { "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeChildSubtreeAvailabilityInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": "NOT_AN_OBJECT" } ================================================ FILE: specs/data/subtrees/subtreeChildSubtreeAvailabilityMissing.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }] } ================================================ FILE: specs/data/subtrees/subtreeContentAvailabilityInvalidLength.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeContentAvailabilityInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": "NOT_AN_OBJECT", "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeContentMetadataArrayElementInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "propertyTables": [ { "class": "exampleClass", "count": 1 }, { "class": "exampleClass", "count": 2 } ], "contentMetadata": [0, 1, "NOT_A_NUMBER"] } ================================================ FILE: specs/data/subtrees/subtreeContentMetadataArrayElementInvalidValueA.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "propertyTables": [ { "class": "exampleClass", "count": 1 }, { "class": "exampleClass", "count": 2 } ], "contentMetadata": [0, 1, 123.456] } ================================================ FILE: specs/data/subtrees/subtreeContentMetadataArrayElementInvalidValueB.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "propertyTables": [ { "class": "exampleClass", "count": 1 }, { "class": "exampleClass", "count": 2 } ], "contentMetadata": [0, 1, 123] } ================================================ FILE: specs/data/subtrees/subtreeContentMetadataInvalidLength.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "contentMetadata": [] } ================================================ FILE: specs/data/subtrees/subtreeContentMetadataInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "contentMetadata": "NOT_AN_ARRAY" } ================================================ FILE: specs/data/subtrees/subtreeContentMetadataWithoutPropertyTables.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "contentMetadata": [0, 1] } ================================================ FILE: specs/data/subtrees/subtreePropertyTablesElementInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "propertyTables": [ "NOT_AN_OBJECT", { "class": "exampleClass", "count": 2 } ] } ================================================ FILE: specs/data/subtrees/subtreePropertyTablesInvalidLength.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "propertyTables": [] } ================================================ FILE: specs/data/subtrees/subtreePropertyTablesInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "propertyTables": "NOT_AN_ARRAY" } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityAvailableCountInvalid.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 12345 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityAvailableCountMismatch.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 1234 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityBitstreamAndConstant.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "constant": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityBitstreamInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": "NOT_A_NUMBER", "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityBitstreamInvalidValueA.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 123.456, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityBitstreamInvalidValueB.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": -1, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityBitstreamInvalidValueC.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 12345, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityBitstreamLengthTooLarge.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 4 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityBitstreamLengthTooSmall.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 2 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityConstantInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "constant": "NOT_A_NUMBER", "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityConstantInvalidValue.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "constant": 3, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityForParentMissingForAvailableTile.json ================================================ { "buffers": [{ "uri": "subtreeBufferTileAvailabilityForParentMissingForAvailableTile.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 8 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": "NOT_AN_OBJECT", "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityMissing.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityMissingForAvailableContent.json ================================================ { "buffers": [{ "uri": "subtreeBufferTileAvailabilityMissingForAvailableContent.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 3 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "bitstream": 1, "availableCount": 5 }], "childSubtreeAvailability": { "availableCount": 0, "constant": 0 } } ================================================ FILE: specs/data/subtrees/subtreeTileAvailabilityNeitherBitstreamNorConstant.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/subtreeTileMetadataInvalidType.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "propertyTables": [ { "class": "exampleClass", "count": 1 } ], "tileMetadata": "NOT_A_NUMBER" } ================================================ FILE: specs/data/subtrees/subtreeTileMetadataInvalidValueA.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "propertyTables": [ { "class": "exampleClass", "count": 1 } ], "tileMetadata": 123.456 } ================================================ FILE: specs/data/subtrees/subtreeTileMetadataInvalidValueB.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 }, "propertyTables": [ { "class": "exampleClass", "count": 1 } ], "tileMetadata": -1 } ================================================ FILE: specs/data/subtrees/validSubtree-0-0-0.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/validSubtree.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 3 }, { "buffer": 0, "byteOffset": 8, "byteLength": 8 } ], "tileAvailability": { "bitstream": 0, "availableCount": 7 }, "contentAvailability": [{ "availableCount": 0, "constant": 0 }], "childSubtreeAvailability": { "bitstream": 1, "availableCount": 8 } } ================================================ FILE: specs/data/subtrees/validSubtreeBuffersWithoutBufferViews.json ================================================ { "buffers": [{ "uri": "validBuffer.bin", "byteLength": 16 }], "tileAvailability": { "constant": 1 }, "contentAvailability": [{ "constant": 1 }], "childSubtreeAvailability": { "constant": 0 } } ================================================ FILE: specs/data/subtrees/validSubtreeImplicitTiling.json.input ================================================ { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "subtrees/{level}.{x}.{y}.subtree" } } ================================================ FILE: specs/data/subtrees/validSubtreeNoBuffers.json ================================================ { "tileAvailability": { "constant": 1 }, "contentAvailability": [{ "constant": 1 }], "childSubtreeAvailability": { "constant": 0 } } ================================================ FILE: specs/data/tilesets/assetTilesetVersionInvalidType.json ================================================ { "asset" : { "version": "1.1", "tilesetVersion": 123 }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/assetVersionInvalidType.json ================================================ { "asset" : { "version": 1.1 }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/assetVersionMissing.json ================================================ { "asset" : { }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/assetVersionUnknown.json ================================================ { "asset" : { "version" : "123.456" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/boundingVolumeBoxArrayInvalidElementType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 4.0, "root": { "boundingVolume": { "box": [ 0.5, 0.5, 0.5, 0.5, 0.0, "Not a number", 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError": 2.0 } } ================================================ FILE: specs/data/tilesets/boundingVolumeBoxInvalidArrayLength.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5 ] }, "geometricError" : 2.0 } } ================================================ FILE: specs/data/tilesets/boundingVolumeMissingProperty.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "boundingVolume" : { }, "geometricError" : 2.0 } } ================================================ FILE: specs/data/tilesets/boundingVolumeRegionArrayElementsOutOfRange.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 4.0, "root": { "boundingVolume": { "region": [ 3.2, 1.6, -3.2, -1.6, 10000, 9999 ] }, "geometricError": 2.0 } } ================================================ FILE: specs/data/tilesets/boundingVolumeRegionArrayInvalidElementType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 4.0, "root": { "boundingVolume": { "region": [ 0.5, 0.5, "Not a number", 0.0, 0.0, 0.5 ] }, "geometricError": 2.0 } } ================================================ FILE: specs/data/tilesets/boundingVolumeRegionInvalidArrayLength.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "boundingVolume" : { "region" : [ 0.5, 0.5, 0.5, 0.5 ] }, "geometricError" : 2.0 } } ================================================ FILE: specs/data/tilesets/boundingVolumeSphereArrayElementOutOfRange.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 4.0, "root": { "boundingVolume": { "sphere": [ 0.5, 0.5, 0.5, -123.456 ] }, "geometricError": 2.0 } } ================================================ FILE: specs/data/tilesets/boundingVolumeSphereArrayInvalidElementType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 4.0, "root": { "boundingVolume": { "sphere": [ 0.5, 0.5, "Not a number", 0.5 ] }, "geometricError": 2.0 } } ================================================ FILE: specs/data/tilesets/boundingVolumeSphereInvalidArrayLength.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "boundingVolume" : { "sphere" : [ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ] }, "geometricError" : 2.0 } } ================================================ FILE: specs/data/tilesets/customSemanticsSchema.json ================================================ { "id": "EXAMPLE-Semantics-0.0.0", "description": "A schema file that defines custom semantics to test the handling of the 'semantic matching schemas'", "classes": { "CustomSemanticsA": { "properties": { "CUSTOM_SEMANTICS_SIMPLE": { "description": "Example for simple custom semantics", "type": "STRING" } } }, "CustomSemanticsB": { "properties": { "CUSTOM_SEMANTICS_COMPLEX": { "description": "Example for complex custom semantics", "type": "VEC3", "componentType": "FLOAT32", "array": true, "count": 2 } } } } } ================================================ FILE: specs/data/tilesets/extensionFoundButNotUsed.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ], "extensions": { "EXAMPLE_EXTENSION_NOT_DECLARED_AS_USED": { } } }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/extensionNotDeclaredAsRequired.json ================================================ { "extras": { "info": { "note": "This tileset is INVALID because it uses the MAXAR_content_3tz extension, but does not list it in the 'extensionsRequired'" } }, "extensionsUsed": [ "MAXAR_content_3tz" ], "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/3tz/simple.3tz" } } } ================================================ FILE: specs/data/tilesets/extensionNotDeclared_1_0_glTF.json ================================================ { "asset" : { "version" : "1.0" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "tiles/glTF/Triangle/Triangle.gltf" }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/extensionNotNecessary_1_1_glTF.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "tiles/glTF/Triangle/Triangle.gltf" }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/extensionRequiredButNotUsed.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extensions": { "EXAMPLE_EXTENSION_A" : {}, "EXAMPLE_EXTENSION_B" : {} }, "extensionsUsed": [ "EXAMPLE_EXTENSION_A", "EXAMPLE_EXTENSION_B" ], "extensionsRequired": [ "EXAMPLE_EXTENSION_A", "EXAMPLE_EXTENSION_B", "EXAMPLE_EXTENSION_NOT_IN_USED" ] } ================================================ FILE: specs/data/tilesets/extensionUsedButNotFound.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ], "extensions": { "EXAMPLE_EXTENSION_A": { } } }, "geometricError" : 1.0 }, "extensionsUsed": [ "EXAMPLE_EXTENSION_A", "EXAMPLE_EXTENSION_NOT_FOUND" ] } ================================================ FILE: specs/data/tilesets/extensionsInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extensions": "NOT_AN_OBJECT" } ================================================ FILE: specs/data/tilesets/extensionsRequiredDuplicateElement.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extensions": { "EXAMPLE_EXTENSION_A" : {}, "EXAMPLE_EXTENSION_B" : {} }, "extensionsUsed": [ "EXAMPLE_EXTENSION_A", "EXAMPLE_EXTENSION_B" ], "extensionsRequired": [ "EXAMPLE_EXTENSION_A", "EXAMPLE_EXTENSION_B", "EXAMPLE_EXTENSION_A" ] } ================================================ FILE: specs/data/tilesets/extensionsRequiredInvalidArrayLength.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extensionsRequired": [] } ================================================ FILE: specs/data/tilesets/extensionsRequiredInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extensionsRequired": "NOT_AN_ARRAY" } ================================================ FILE: specs/data/tilesets/extensionsUsedDuplicateElement.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extensions": { "EXAMPLE_EXTENSION_A" : {}, "EXAMPLE_EXTENSION_B" : {} }, "extensionsUsed": [ "EXAMPLE_EXTENSION_A", "EXAMPLE_EXTENSION_B", "EXAMPLE_EXTENSION_A" ] } ================================================ FILE: specs/data/tilesets/extensionsUsedInvalidArrayLength.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extensionsUsed": [] } ================================================ FILE: specs/data/tilesets/extensionsUsedInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extensionsUsed": "NOT_AN_ARRAY" } ================================================ FILE: specs/data/tilesets/extensionsValueInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extensions": { "EXAMPLE_EXTENSION_A": "NOT_AN_OBJECT" }, "extensionsUsed": [ "EXAMPLE_EXTENSION_A" ] } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/README.md ================================================ Test data for the validation of extensions in the context of external tilesets. (This is a special aspect of https://github.com/CesiumGS/3d-tiles-validator/issues/231 ). Each of these data sets consists of a `tileset.json` that refers to an `external.json`. They use a "dummy" extension called `VENDOR_example_extension` to check the validation of the `extensionsUsed` propery of a tileset. (This means that the validation will always at least create one warning, because the extension is not supported). In the following, the term.. - 'declared' means that a tileset declares the extension in its `extesionsUsed` - 'contained' means that the tileset actually contains such an extension object in its `extensions` These cases are considered: - `declaredInBothContainedInExternal`: This is valid. The external tileset contains it and declares it. The main tileset also declares it (because it refers to one that contains it). - `declaredInBothContainedInTileset`: This valid, but causes a warning. The external tileset does not have to declare it if it does not contain it. - `declaredInExternalContainedInExternal`: This is invalid. The main tileset also has to declare it when it refers to one that contains it. - `declaredInExternalContainedInTileset`: This is invalid. The main tileset has to declare it if it contains it. - `declaredInNoneContainedInExternal`: This is invalid. Both tilesets have to declare it when the external one contains it. - `declaredInTilesetContainedInExternal`: This is invalid. The external one also has to declare it when it contains it - `declaredInTilesetContainedInTileset`: This is valid. Only the main tileset has to declare it if only the main tileset contains it. ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInBothContainedInExternal/external.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0 }, "extensionsUsed": [ "VENDOR_example_extension" ], "extensions": { "VENDOR_example_extension": { "exampleExtension": { "description": "A dummy example extension" } } } } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInBothContainedInExternal/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "external.json" } } ] }, "extensionsUsed": [ "VENDOR_example_extension" ] } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInBothContainedInTileset/external.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0 }, "extensionsUsed": [ "VENDOR_example_extension" ] } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInBothContainedInTileset/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "external.json" } } ] }, "extensionsUsed": [ "VENDOR_example_extension" ], "extensions": { "VENDOR_example_extension": { "exampleExtension": { "description": "A dummy example extension" } } } } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInExternalContainedInExternal/external.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0 }, "extensionsUsed": [ "VENDOR_example_extension" ], "extensions": { "VENDOR_example_extension": { "exampleExtension": { "description": "A dummy example extension" } } } } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInExternalContainedInExternal/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "external.json" } } ] } } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInExternalContainedInTileset/external.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0 }, "extensionsUsed": [ "VENDOR_example_extension" ] } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInExternalContainedInTileset/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "external.json" } } ] }, "extensions": { "VENDOR_example_extension": { "exampleExtension": { "description": "A dummy example extension" } } } } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInNoneContainedInExternal/external.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0 }, "extensions": { "VENDOR_example_extension": { "exampleExtension": { "description": "A dummy example extension" } } } } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInNoneContainedInExternal/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "external.json" } } ] } } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInTilesetContainedInExternal/external.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0 }, "extensions": { "VENDOR_example_extension": { "exampleExtension": { "description": "A dummy example extension" } } } } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInTilesetContainedInExternal/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "external.json" } } ] }, "extensionsUsed": [ "VENDOR_example_extension" ] } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInTilesetContainedInTileset/external.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0 } } ================================================ FILE: specs/data/tilesets/externalTilesetExtensions/declaredInTilesetContainedInTileset/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "external.json" } } ] }, "extensionsUsed": [ "VENDOR_example_extension" ], "extensions": { "VENDOR_example_extension": { "exampleExtension": { "description": "A dummy example extension" } } } } ================================================ FILE: specs/data/tilesets/extrasUnexpectedType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "extras": "NOT_AN_OBJECT_CAUSES_WARNING" } ================================================ FILE: specs/data/tilesets/groupClassIdInvalid.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes" : { "exampleClass" : { } } }, "groups": [ { "class": "EXAMPLE_INVALID_CLASS_ID" } ], "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/groupClassIdInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes" : { "exampleClass" : { } } }, "groups": [ { "class": 123.456 } ], "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/groupWithoutSchema.json ================================================ { "asset" : { "version" : "1.1" }, "groups": [ { "class": "EXAMPLE_CLASS_ID" } ], "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/implicitTilingAvailableLevelsInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": "NOT_AN_INTEGER", "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingAvailableLevelsInvalidValue.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 0, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingContentUriTemplateVariableInvalid.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "content": { "uri": "example-{level}-{x}-{y}-{INVALID}.glb" }, "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "../subtrees/validSubtree-{level}-{x}-{y}.json" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingContentsUriTemplateVariableInvalid.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "refine": "ADD", "contents": [ { "uri": "exampleA-{level}-{x}-{y}.glb" }, { "uri": "exampleB-{level}-{x}-{y}-{INVALID}.glb" } ], "implicitTiling": { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "../subtrees/validSubtree-{level}-{x}-{y}.json" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : "NOT_AN_OBJECT" } } ================================================ FILE: specs/data/tilesets/implicitTilingRootWithChildren.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "content": { "uri": "example-{level}-{x}-{y}.glb" }, "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } }, "children": [ ] } } ================================================ FILE: specs/data/tilesets/implicitTilingRootWithContentBoundingVolume.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "refine": "ADD", "content": { "uri": "example-{level}-{x}-{y}.glb", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] } }, "implicitTiling": { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingRootWithMetadata.json ================================================ { "asset" : { "version" : "1.1" }, "schema" : { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass" : { "properties": { "exampleFloatScalar": { "type": "SCALAR", "componentType": "FLOAT32" } } } } }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "content": { "uri": "example-{level}-{x}-{y}.glb" }, "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } }, "metadata": { "class": "exampleClass", "properties": { "exampleFloatScalar": 1.0 } } } } ================================================ FILE: specs/data/tilesets/implicitTilingSubdivisionSchemeInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": 123.456, "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingSubdivisionSchemeInvalidValue.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "NOT_A_VALID_VALUE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingSubtreeLevelsInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": "NOT_AN_INTEGER", "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingSubtreeLevelsInvalidValue.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 0, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingSubtreesInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": "NOT_AN_OBJECT" } } } ================================================ FILE: specs/data/tilesets/implicitTilingSubtreesUriInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": 123.456 } } } } ================================================ FILE: specs/data/tilesets/implicitTilingSubtreesUriMissing.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { } } } } ================================================ FILE: specs/data/tilesets/implicitTilingSubtreesUriTemplateVariableInvalid.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "OCTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}-{z}-{NOT_A_VALID_NAME}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingSubtreesUriTemplateVariableMissing.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingValid.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } } } } ================================================ FILE: specs/data/tilesets/implicitTilingWithBoundingSphere.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "sphere" : [ 0.0, 0.0, 0.0, 1.0 ] }, "geometricError" : 1.0, "refine": "ADD", "implicitTiling" : { "subdivisionScheme": "QUADTREE", "subtreeLevels": 3, "availableLevels": 6, "subtrees": { "uri": "example-{level}-{x}-{y}.subtree" } } } } ================================================ FILE: specs/data/tilesets/invalidJson.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, , 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/packages/tilesetPackageWithWarnings/TriangleWithWarnings/TriangleWithWarnings.gltf ================================================ { "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "nodes" : [ { "mesh" : 0 }, { "name": "Unused empty node to create infos" } ], "meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1 }, "indices" : 0 } ] } ], "buffers" : [ { "uri" : "simpleTriangle.bin", "byteLength" : 44 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 6, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 8, "byteLength" : 36, "target" : 34962 } ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 3, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 3, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] } ], "asset" : { "version" : "2.123" } } ================================================ FILE: specs/data/tilesets/packages/tilesetPackageWithWarnings/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "TriangleWithWarnings/TriangleWithWarnings.gltf" } } } ================================================ FILE: specs/data/tilesets/packages/validTilesetPackage/Triangle/Triangle.gltf ================================================ { "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "nodes" : [ { "mesh" : 0 } ], "meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1 }, "indices" : 0 } ] } ], "buffers" : [ { "uri" : "simpleTriangle.bin", "byteLength" : 44 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 6, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 8, "byteLength" : 36, "target" : 34962 } ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 3, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 3, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] } ], "asset" : { "version" : "2.0" } } ================================================ FILE: specs/data/tilesets/packages/validTilesetPackage/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/tilesets/propertiesInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "properties": { "exampleProperty": "Should be an object" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/propertiesMaximumInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "properties": { "exampleProperty": { "minimum" : 10.0, "maximum": "Should be a number" } }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/propertiesMaximumMissing.json ================================================ { "asset" : { "version" : "1.1" }, "properties": { "exampleProperty": { "minimum" : 10.0 } }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/propertiesMinimumInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "properties": { "exampleProperty": { "minimum" : "Should be a number", "maximum": 5.0 } }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/propertiesMinimumLargerThanMaximum.json ================================================ { "asset" : { "version" : "1.1" }, "properties": { "exampleProperty": { "minimum" : 10.0, "maximum" : 5.0 } }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/propertiesMinimumMissing.json ================================================ { "asset" : { "version" : "1.1" }, "properties": { "exampleProperty": { "maximum" : 10.0 } }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/statisticsClassesIdInvalid.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32" } } } } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "statistics": { "classes": { "INVALID_CLASS_ID": {} } } } ================================================ FILE: specs/data/tilesets/statisticsClassesInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "statistics": { "classes": "Should be an object" } } ================================================ FILE: specs/data/tilesets/statisticsClassesMinPropertiesMismatch.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32" } } } } }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "statistics": { "classes": {} } } ================================================ FILE: specs/data/tilesets/statisticsClassesPropertiesMinPropertiesMismatch.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32" } } } } }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "statistics": { "classes": { "exampleClass": { "properties": {} } } } } ================================================ FILE: specs/data/tilesets/statisticsClassesPropertiesPropertyNameInvalid.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32" } } } } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 }, "statistics": { "classes": { "exampleClass": { "properties": { "INVALID_PROPERTY_NAME": { "min": 0.0, "max": 10.0 } } } } } } ================================================ FILE: specs/data/tilesets/statisticsClassesValueInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_ID" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "statistics": { "classes": { "exampleClass": "Should be an object" } } } ================================================ FILE: specs/data/tilesets/statisticsClassesWithoutSchema.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, "statistics": { "classes": { "exampleClass": { } } } } ================================================ FILE: specs/data/tilesets/tileChildrenEmptyArray.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "children": [] } } ================================================ FILE: specs/data/tilesets/tileContentBoundingVolumeInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "http://example.com/example.glb", "boundingVolume": "NOT_AN_OBJECT" } } } ================================================ FILE: specs/data/tilesets/tileContentBoundingVolumeNotInTileBoundingVolume.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/glTF/Triangle/Triangle.gltf", "boundingVolume": { "box" : [ 5.0, 5.0, 5.0, 10.0, 0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 10.0 ] } } } } ================================================ FILE: specs/data/tilesets/tileContentBoundingVolumeWithRotationTransform.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 10.0 ] }, "geometricError" : 1.0, "transform": [ 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1 ], "content": { "uri": "tiles/glTF/Triangle/Triangle.gltf", "boundingVolume": { "box" : [ 0.0, 0.0, 2.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 2.0 ] } } } } ================================================ FILE: specs/data/tilesets/tileContentBoundingVolumeWithTransform.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "transform": [ 2.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 5.0, 6.0, 7.0, 1.0 ], "content": { "uri": "tiles/glTF/Triangle/Triangle.gltf", "boundingVolume": { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] } } } } ================================================ FILE: specs/data/tilesets/tileContentGroupInvalidIndex.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes" : { "exampleClass" : { } } }, "groups": [ { "class": "exampleClass" } ], "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "http://example.com/example.glb", "group": 2 } } } ================================================ FILE: specs/data/tilesets/tileContentGroupInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes" : { "exampleClass" : { } } }, "groups": [ { "class": "exampleClass" } ], "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "http://example.com/example.glb", "group": 123.456 } } } ================================================ FILE: specs/data/tilesets/tileContentGroupNegativeIndex.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes" : { "exampleClass" : { } } }, "groups": [ { "class": "exampleClass" } ], "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "http://example.com/example.glb", "group": -2 } } } ================================================ FILE: specs/data/tilesets/tileContentGroupWithoutTilesetGroups.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "http://example.com/example.glb", "group": 0 } } } ================================================ FILE: specs/data/tilesets/tileContentInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": "Not an object" } } ================================================ FILE: specs/data/tilesets/tileContentsInvalidType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "contents": { "uri": "http://example.com/example0.glb" } } } ================================================ FILE: specs/data/tilesets/tileGeometricErrorMissing.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] } } } ================================================ FILE: specs/data/tilesets/tileGeometricErrorNegative.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : -1.0 } } ================================================ FILE: specs/data/tilesets/tileGeometricErrorNotSmallerThanParentGeometricError.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 8.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 4.0, "children": [ { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children" : [ { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 }, { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0 }, { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.1 } ] }, { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 4.1 } ] } } ================================================ FILE: specs/data/tilesets/tileInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "children" : [ "not an object" ] } } ================================================ FILE: specs/data/tilesets/tileMetadataClassInvalid.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "examplePropertyInt16": { "name": "Name of examplePropertyInt16", "description": "Description for examplePropertyInt16", "type": "SCALAR", "componentType": "INT16" }, "examplePropertyEnum": { "name": "Name of examplePropertyEnum", "description": "Description for examplePropertyEnum", "type": "ENUM", "enumType": "exampleEnum" } } } }, "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "metadata": { "class": "EXAMPLE_INVALID_CLASS_ID" } } } ================================================ FILE: specs/data/tilesets/tileMetadataClassInvalidType.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "examplePropertyInt16": { "name": "Name of examplePropertyInt16", "description": "Description for examplePropertyInt16", "type": "SCALAR", "componentType": "INT16" }, "examplePropertyEnum": { "name": "Name of examplePropertyEnum", "description": "Description for examplePropertyEnum", "type": "ENUM", "enumType": "exampleEnum" } } } }, "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "metadata": { "class": 123.456 } } } ================================================ FILE: specs/data/tilesets/tileMetadataClassMissing.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "examplePropertyInt16": { "name": "Name of examplePropertyInt16", "description": "Description for examplePropertyInt16", "type": "SCALAR", "componentType": "INT16" }, "examplePropertyEnum": { "name": "Name of examplePropertyEnum", "description": "Description for examplePropertyEnum", "type": "ENUM", "enumType": "exampleEnum" } } } }, "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "metadata": { } } } ================================================ FILE: specs/data/tilesets/tileMetadataGeometricErrorInconsistent.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes" : { "exampleClass" : { "properties": { "exampleFloatScalarAsGeometricError": { "type": "SCALAR", "componentType": "FLOAT32", "semantic": "TILE_GEOMETRIC_ERROR" } } } } }, "geometricError" : 4.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "metadata": { "class": "exampleClass", "properties": { "exampleFloatScalarAsGeometricError": 3.5 } }, "children": [ { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "metadata": { "class": "exampleClass", "properties": { "exampleFloatScalarAsGeometricError": 3.6 } } }, { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "metadata": { "class": "exampleClass", "properties": { "exampleFloatScalarAsGeometricError": 2.5 } } } ] } } ================================================ FILE: specs/data/tilesets/tileMetadataRequiredPropertyMissing.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "examplePropertyInt16": { "name": "Name of examplePropertyInt16", "description": "Description for examplePropertyInt16", "type": "SCALAR", "componentType": "INT16", "required": true }, "examplePropertyEnum": { "name": "Name of examplePropertyEnum", "description": "Description for examplePropertyEnum", "type": "ENUM", "enumType": "exampleEnum" } } } }, "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "metadata": { "class": "exampleClass", "properties": { "examplePropertyEnum": "EXAMPLE_ENUM_VALUE_A" } } } } ================================================ FILE: specs/data/tilesets/tileMetadataRequiredPropertyNull.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "examplePropertyInt16": { "name": "Name of examplePropertyInt16", "description": "Description for examplePropertyInt16", "type": "SCALAR", "componentType": "INT16", "required": true }, "examplePropertyEnum": { "name": "Name of examplePropertyEnum", "description": "Description for examplePropertyEnum", "type": "ENUM", "enumType": "exampleEnum" } } } }, "enums": { "exampleEnum": { "values": [ { "name": "EXAMPLE_ENUM_VALUE_A", "value": 0 }, { "name": "EXAMPLE_ENUM_VALUE_B", "value": 1 } ] } } }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "metadata": { "class": "exampleClass", "properties": { "examplePropertyInt16": null, "examplePropertyEnum": "EXAMPLE_ENUM_VALUE_A" } } } } ================================================ FILE: specs/data/tilesets/tileMetadataScalarValueNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "examplePropertyInt16": { "type": "SCALAR", "componentType": "INT16" } } } } }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "metadata": { "class": "exampleClass", "properties": { "examplePropertyInt16": 66666 } } } } ================================================ FILE: specs/data/tilesets/tileMetadataVec3ArrayElementValueNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "examplePropertyVec3Int16Array": { "type": "VEC3", "componentType": "INT16", "array": true, "count": 3 } } } } }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "metadata": { "class": "exampleClass", "properties": { "examplePropertyVec3Int16Array": [ [ 0, 1, 2 ], [ 333333, 4, 5 ], [ 6, 7, 888888 ] ] } } } } ================================================ FILE: specs/data/tilesets/tileMetadataVec3ElementValueNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "examplePropertyVec3Int16": { "type": "VEC3", "componentType": "INT16" } } } } }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "metadata": { "class": "exampleClass", "properties": { "examplePropertyVec3Int16": [ 88888, 12345, 99999 ] } } } } ================================================ FILE: specs/data/tilesets/tileMetadataWithoutSchema.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "metadata": { "class": "exampleClass" } } } ================================================ FILE: specs/data/tilesets/tileRefineInvalidValue.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "INVALID_VALUE" } } ================================================ FILE: specs/data/tilesets/tileRefineMissingInRoot.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "children": [ { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 0.0, "refine": "ADD" } ] } } ================================================ FILE: specs/data/tilesets/tileRefineMissingInRootOfExternal.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "tileRefineMissingInRootOfExternalA.json" } } ] } } ================================================ FILE: specs/data/tilesets/tileRefineMissingInRootOfExternalA.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 1.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 0.5 } } ================================================ FILE: specs/data/tilesets/tileRefineWrongCase.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": "RePlaCe" } } ================================================ FILE: specs/data/tilesets/tileRefineWrongType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "refine": 123.456 } } ================================================ FILE: specs/data/tilesets/tileTransformInvalidArrayElementType.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "transform": [0, 0, 0, 0, 0, 0, 0, 0, "NOT_A_NUMBER", 0, 0, 0, 0, 0, 0, 0] } } ================================================ FILE: specs/data/tilesets/tileTransformInvalidArrayLength.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "transform": [0, 0, 0] } } ================================================ FILE: specs/data/tilesets/tileTransformInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "transform": "NOT_AN_ARRAY" } } ================================================ FILE: specs/data/tilesets/tileTransformNonInvertible.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "transform": [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] } } ================================================ FILE: specs/data/tilesets/tileTransformNotAffine.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2] } } ================================================ FILE: specs/data/tilesets/tileWithContentAndContents.json ================================================ { "asset": { "version": "1.1" }, "geometricError": 2.0, "root": { "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0, "content": { "uri": "http://example.com/example.glb" }, "contents": [ { "uri": "http://example.com/example0.glb" }, { "uri": "http://example.com/example1.glb" } ] } } ================================================ FILE: specs/data/tilesets/tiles/3tz/invalid.3tz ================================================ ================================================ FILE: specs/data/tilesets/tiles/Notes.txt ================================================ Tile content files used in the spec tilesets, for basic content data validation tests. For b3dm: - The `valid.b3dm` is the `parent.b3dm` from the original validator (https://github.com/CesiumGS/3d-tiles-validator/tree/e84202480eb6572383008076150c8e52c99af3c3/validator/specs/data/Tileset) - The `invalid.b3dm` is the same, but with an invalid `version` in the header. - The `invalidWithInvalidGlb.b3dm` is the same as the `valid.b3dm`, but with an invalid length in the GLB header. - The `invalidAlignment.b3dm` is the B3DM from https://github.com/CesiumGS/cesium/blob/87d639542f5858dc42a090b8034819e33bf4afa6/Apps/SampleData/Cesium3DTiles/Batched/BatchedColors/batchedColors.b3dm to check whether the validator detects https://github.com/CesiumGS/3d-tiles-samples-generator/issues/1 For glTF: - The models are based on the `Triangle` sample model from https://github.com/KhronosGroup/glTF-Sample-Models/blob/8e9a5a6ad1a2790e2333e3eb48a1ee39f9e0e31b/2.0/Triangle/, where various types of warnings or errors have been introduced manually The remaining tile contents are taken from the CesiumJS sample data (at https://github.com/CesiumGS/cesium/tree/c0ec95713b6cde5a91eea320795c84408159dcad/Apps/SampleData/Cesium3DTiles), which, at the given commit, have been invalid or caused warnings: For pnts: - The `invalid.pnts` is the `PointCloud\PointCloudWithPerPointProperties\pointCloudWithPerPointProperties.pnts` For i3dm: - The `invalid.i3dm` is the `Instanced\InstancedWithBatchTable\instancedWithBatchTable.i3dm` For cmpt: - The `validWithGlbWarning.cmpt` is the `Composite\Composite\composite.cmpt` For geom (only for content type detection): - The `content.geom` is the `Classification\PointCloud\content.geom` For vctr (only for content type detection): - The `parent.vctr` is the `Specs\Data\Cesium3DTiles\Vector\VectorTilePoints\parent.vctr` For geojson (only for content type detection): - The `lineString.geojson` is the `Specs\Data\Cesium3DTiles\GeoJson\LineString\lineString.geojson` For 3tz (only for content type detection): - The `simple.3tz` is just a 3TZ file with a minimal, valid `tileset.json` ================================================ FILE: specs/data/tilesets/tiles/geojson/lineString.geojson ================================================ { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "UL", "code": 12 }, "geometry": { "type": "LineString", "coordinates": [ [ -75.61209430782448, 40.042530611425896 ], [ -75.61219430782448, 40.042530611425896 ], [ -75.61219430782448, 40.042630611425896 ], [ -75.61209430782448, 40.042630611425896 ], [ -75.61209430782448, 40.042530611425896 ] ] } } ] } ================================================ FILE: specs/data/tilesets/tiles/glTF/Triangle/Triangle.gltf ================================================ { "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "nodes" : [ { "mesh" : 0 } ], "meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1 }, "indices" : 0 } ] } ], "buffers" : [ { "uri" : "simpleTriangle.bin", "byteLength" : 44 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 6, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 8, "byteLength" : 36, "target" : 34962 } ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 3, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 3, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] } ], "asset" : { "version" : "2.0" } } ================================================ FILE: specs/data/tilesets/tiles/glTF/TriangleWithErrors/TriangleWithErrors.gltf ================================================ { "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "nodes" : [ { "mesh" : 0 } ], "meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1, "NORMAL" : 2 }, "indices" : 0 } ] } ], "buffers" : [ { "uri" : "simpleTriangle.bin", "byteLength" : 44 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 100000, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 8, "byteLength" : 36, "target" : 34962 } ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 3, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 3, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] } ], "asset" : { "version" : "2.0" } } ================================================ FILE: specs/data/tilesets/tiles/glTF/TriangleWithWarnings/TriangleWithWarnings.gltf ================================================ { "scene" : 0, "scenes" : [ { "nodes" : [ 0 ] } ], "nodes" : [ { "mesh" : 0 }, { "name": "Unused empty node to create infos" } ], "meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1 }, "indices" : 0 } ] } ], "buffers" : [ { "uri" : "simpleTriangle.bin", "byteLength" : 44 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 6, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 8, "byteLength" : 36, "target" : 34962 } ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 3, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 3, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] } ], "asset" : { "version" : "2.123" } } ================================================ FILE: specs/data/tilesets/tiles/i3dm/i3dmWithUri/README.md ================================================ A tileset that refers to a single I3DM file, which in turn refers to a single glTF file (the `Box` glTF sample model). The I3DM refers to the GLB using a URI, in contrast to embedding the GLB inside the GLB. The URI is `"Box.glb "`: It includes spaces, as a regression test for https://github.com/CesiumGS/3d-tiles-validator/issues/276 . The string (including spaces) consists of 11 characters. In order to achieve the alignment requirement, the payload data is padded with _additional_ `0x00` bytes to achieve a payload length of 16 bytes. This is not allowed by the specification, and should cause a WARNING during the validation. ================================================ FILE: specs/data/tilesets/tiles/i3dm/i3dmWithUri/tileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "i3dmWithUri.i3dm" } } } ================================================ FILE: specs/data/tilesets/tilesetAssetMissing.json ================================================ { "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetGeometricErrorMissing.json ================================================ { "asset" : { "version" : "1.1" }, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetGeometricErrorNegative.json ================================================ { "asset" : { "version" : "1.0" }, "geometricError" : -2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetMetadataEntityPropertyEnumInvalidValue.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "ENUM", "enumType": "exampleEnum" } } } }, "enums" : { "exampleEnum" : { "valueType": "UINT8", "values" : [ { "name" : "NO_DATA_ENUM_VALUE", "value" : 255 }, { "name" : "EXAMPLE_ENUM_VALUE_A", "value" : 0 }, { "name" : "EXAMPLE_ENUM_VALUE_B", "value" : 1 }, { "name" : "EXAMPLE_ENUM_VALUE_C", "value" : 2 }, { "name" : "DEFAULT_ENUM_VALUE", "value" : 3 } ] } } }, "metadata": { "class": "exampleClass", "properties": { "exampleProperty": "EXAMPLE_ENUM_VALUE_THAT_DOES_NOT_EXIST" } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetMetadataEntityPropertyMaxNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "max": 10 } } } } }, "metadata": { "class": "exampleClass", "properties": { "exampleProperty": 100 } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetMetadataEntityPropertyMaxWithNormalizedNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "UINT16", "normalized": true, "max": 0.1 } } } } }, "metadata": { "class": "exampleClass", "properties": { "exampleProperty": 50000 } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetMetadataEntityPropertyMaxWithOffsetNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "max": 0, "offset": -95 } } } } }, "metadata": { "class": "exampleClass", "properties": { "exampleProperty": 100 } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetMetadataEntityPropertyMaxWithScaleNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "max": 1000, "scale": 100 } } } } }, "metadata": { "class": "exampleClass", "properties": { "exampleProperty": 100 } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetMetadataEntityPropertyMinNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "min": 1000 } } } } }, "metadata": { "class": "exampleClass", "properties": { "exampleProperty": 100 } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetMetadataEntityPropertyMinWithNormalizedNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "UINT16", "normalized": true, "min": 0.9 } } } } }, "metadata": { "class": "exampleClass", "properties": { "exampleProperty": 100 } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetMetadataEntityPropertyMinWithOffsetNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "min": 10, "offset": -95 } } } } }, "metadata": { "class": "exampleClass", "properties": { "exampleProperty": 100 } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetMetadataEntityPropertyMinWithScaleNotInRange.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes": { "exampleClass": { "properties": { "exampleProperty": { "type": "SCALAR", "componentType": "FLOAT32", "min": 10, "scale": 0.01 } } } } }, "metadata": { "class": "exampleClass", "properties": { "exampleProperty": 100 } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetSchemaUriInvalidType.json ================================================ { "asset" : { "version" : "1.1" }, "schemaUri": 123, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetWithCycleA.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tilesetWithCycleB.json" } } } ================================================ FILE: specs/data/tilesets/tilesetWithCycleB.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tilesetWithCycleC.json" } } } ================================================ FILE: specs/data/tilesets/tilesetWithCycleC.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tilesetWithCycleA.json" } } } ================================================ FILE: specs/data/tilesets/tilesetWithMultipleExternal.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "tilesetWithMultipleExternalA.json" } }, { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "tilesetWithMultipleExternalB.json" } } ] } } ================================================ FILE: specs/data/tilesets/tilesetWithMultipleExternalA.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 4.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "children": [ { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "tilesetWithMultipleExternalA0.json" } }, { "geometricError" : 1.0, "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "content": { "uri": "tilesetWithMultipleExternalA1.json" } } ] } } ================================================ FILE: specs/data/tilesets/tilesetWithMultipleExternalA0.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetWithMultipleExternalA1.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetWithMultipleExternalB.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetWithSchemaAndSchemaUri.json ================================================ { "asset" : { "version" : "1.1" }, "schema" : { "id": "EXAMPLE_SCHEMA_ID" }, "schemaUri" : "http://example.com/example.json", "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/tilesetWithUnicodeBOM.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/validTileset.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/validTilesetWith3tzWithError.json ================================================ { "extensionsUsed": [ "MAXAR_content_3tz" ], "extensionsRequired" : [ "MAXAR_content_3tz" ], "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/3tz/withError.3tz" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithCustomSemantics.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "examplePropertyA": { "type": "STRING", "array": true, "semantic": "ATTRIBUTION_STRINGS" }, "examplePropertyB": { "type": "STRING", "semantic": "CUSTOM_SEMANTICS_SIMPLE" }, "examplePropertyC": { "type": "VEC3", "componentType": "FLOAT32", "array": true, "count": 2, "semantic": "CUSTOM_SEMANTICS_COMPLEX" } } } } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/validTilesetWithCustomSemanticsWithInvalidType.json ================================================ { "asset": { "version": "1.1" }, "schema": { "id": "EXAMPLE_ID", "classes": { "exampleClass": { "properties": { "examplePropertyA": { "type": "STRING", "array": true, "semantic": "ATTRIBUTION_STRINGS" }, "examplePropertyB": { "type": "BOOLEAN", "semantic": "CUSTOM_SEMANTICS_SIMPLE" }, "examplePropertyC": { "type": "VEC2", "componentType": "FLOAT32", "array": true, "count": 2, "semantic": "CUSTOM_SEMANTICS_COMPLEX" } } } } }, "geometricError": 2.0, "root": { "refine": "REPLACE", "boundingVolume": { "box": [0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5] }, "geometricError": 1.0 } } ================================================ FILE: specs/data/tilesets/validTilesetWithExternalValidTilesetWithValidB3dmWithInvalidGlb.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "validTilesetWithValidB3dmWithInvalidGlb.json" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithGlbWithErrors.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/glTF/TriangleGlbWithErrors/TriangleGlbWithInvalidLength.glb" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithGltfWithErrors.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/glTF/TriangleWithErrors/TriangleWithErrors.gltf" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithGltfWithWarnings.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/glTF/TriangleWithWarnings/TriangleWithWarnings.gltf" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithIB3dmWithInvalidAlignment.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/b3dm/invalidAlignment.b3dm" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithInvalid3tz.json ================================================ { "extensionsUsed": [ "MAXAR_content_3tz" ], "extensionsRequired" : [ "MAXAR_content_3tz" ], "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/3tz/invalid.3tz" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithInvalidB3dm.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/b3dm/invalid.b3dm" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithInvalidB3dmWithGlbWithInfos.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/b3dm/invalidDueToWrongAlignmentWithGlbWithInfos.b3dm" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithInvalidI3dm.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/i3dm/invalid.i3dm" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithInvalidPnts.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/pnts/invalid.pnts" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithInvalidSchemaFromUri.json ================================================ { "asset" : { "version" : "1.1" }, "schemaUri": "../schemas/schemaIdMissing.json", "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/validTilesetWithSchema.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes" : { "exampleClass" : { "properties": { "exampleFloatScalar": { "type": "SCALAR", "componentType": "FLOAT32" } } } } }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/validTilesetWithTileMetadata.json ================================================ { "asset" : { "version" : "1.1" }, "schema": { "id": "EXAMPLE_SCHEMA_ID", "classes" : { "exampleClass" : { "properties": { "exampleFloatScalarAsGeometricError": { "type": "SCALAR", "componentType": "FLOAT32", "semantic": "TILE_GEOMETRIC_ERROR" } } } } }, "geometricError" : 4.0, "root" : { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 2.0, "metadata": { "class": "exampleClass", "properties": { "exampleFloatScalarAsGeometricError": 3.5 } }, "children": [ { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "metadata": { "class": "exampleClass", "properties": { "exampleFloatScalarAsGeometricError": 2.5 } } }, { "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "metadata": { "class": "exampleClass", "properties": { "exampleFloatScalarAsGeometricError": 2.5 } } } ] } } ================================================ FILE: specs/data/tilesets/validTilesetWithUnresolvableSchemaUri.json ================================================ { "asset" : { "version" : "1.1" }, "schemaUri": "schemas/THIS_DOES_NOT_EXIST.json", "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/data/tilesets/validTilesetWithValid3tz.json ================================================ { "extensionsUsed": [ "MAXAR_content_3tz" ], "extensionsRequired" : [ "MAXAR_content_3tz" ], "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/3tz/simple.3tz" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithValidB3dm.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/b3dm/valid.b3dm" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithValidB3dmWithInvalidGlb.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/b3dm/validWithInvalidGlb.b3dm" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithValidCmptWithGlbInfo.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/cmpt/validWithGlbInfo.cmpt" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithValidGltf.json ================================================ { "asset" : { "version" : "1.1" }, "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0, "content": { "uri": "tiles/glTF/Triangle/Triangle.gltf" } } } ================================================ FILE: specs/data/tilesets/validTilesetWithValidSchemaFromUri.json ================================================ { "asset" : { "version" : "1.1" }, "schemaUri": "../schemas/validSchema.json", "geometricError" : 2.0, "root" : { "refine": "REPLACE", "boundingVolume" : { "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] }, "geometricError" : 1.0 } } ================================================ FILE: specs/extensions/BoundingVolumeS2ValidationSpec.ts ================================================ import { Validators } from "../../src/validation/Validators"; describe("Tileset 3DTILES_bounding_volume_S2 extension validation", function () { it("detects issues in s2AndInvalidBox", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/boundingVolumeS2/s2AndInvalidBox.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in s2MaximumHeightInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/boundingVolumeS2/s2MaximumHeightInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in s2MinimumHeightGreaterThanMaximumHeight", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/boundingVolumeS2/s2MinimumHeightGreaterThanMaximumHeight.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BOUNDING_VOLUME_INVALID"); }); it("detects issues in s2MinimumHeightInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/boundingVolumeS2/s2MinimumHeightInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in s2TokenInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/boundingVolumeS2/s2TokenInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in s2TokenInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/boundingVolumeS2/s2TokenInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("S2_TOKEN_INVALID"); }); it("detects issues in s2TokenMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/boundingVolumeS2/s2TokenMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects no issues in validTilesetWithS2", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/boundingVolumeS2/validTilesetWithS2.json" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/extensions/ContentGltfValidationSpec.ts ================================================ import { Validators } from "../../src/validation/Validators"; describe("Tileset 3DTILES_content_gltf extension validation", function () { it("detects issues in contentGltfExtensionRequiredButNotUsed", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/contentGltfExtensionRequiredButNotUsed.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTENSION_REQUIRED_BUT_NOT_USED"); }); it("detects issues in contentGltfExtensionsRequiredDuplicateElement", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/contentGltfExtensionsRequiredDuplicateElement.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_NOT_UNIQUE"); }); it("detects issues in contentGltfExtensionsRequiredInvalidArrayLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/contentGltfExtensionsRequiredInvalidArrayLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in contentGltfExtensionsRequiredInvalidElementType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/contentGltfExtensionsRequiredInvalidElementType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in contentGltfExtensionsRequiredInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/contentGltfExtensionsRequiredInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in contentGltfExtensionsUsedDuplicateElement", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/contentGltfExtensionsUsedDuplicateElement.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_NOT_UNIQUE"); }); it("detects issues in contentGltfExtensionsUsedInvalidArrayLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/contentGltfExtensionsUsedInvalidArrayLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in contentGltfExtensionsUsedInvalidElementType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/contentGltfExtensionsUsedInvalidElementType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in contentGltfExtensionsUsedInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/contentGltfExtensionsUsedInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in tileset_1_0_withContentGltfRequiredButNotUsed", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/tileset_1_0_withContentGltfRequiredButNotUsed.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTENSION_REQUIRED_BUT_NOT_USED"); }); it("detects issues in tileset_1_0_withContentGltfUsedButNotFound", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/tileset_1_0_withContentGltfUsedButNotFound.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTENSION_USED_BUT_NOT_FOUND"); }); it("detects issues in tileset_1_0_withContentGltfUsedButNotRequired", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/tileset_1_0_withContentGltfUsedButNotRequired.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTENSION_REQUIRED_BUT_NOT_DECLARED"); }); it("detects issues in tileset_1_1_withContentGltfUsedButNotFound", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/tileset_1_1_withContentGltfUsedButNotFound.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("EXTENSION_USED_BUT_NOT_FOUND"); }); it("detects no issues in validTileset_1_0_withGltf", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/validTileset_1_0_withGltf.json" ); expect(result.length).toEqual(0); }); it("detects no issues in validTileset_1_0_withExtensionObject", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/validTileset_1_0_withExtensionObject.json" ); expect(result.length).toEqual(0); }); it("detects no issues in validTileset_1_1_withContentGltfUsedAndFound", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/validTileset_1_1_withContentGltfUsedAndFound.json" ); expect(result.length).toEqual(0); }); it("detects no issues in validTileset_1_1_withGltf", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/contentGltf/validTileset_1_1_withGltf.json" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/extensions/MaxarContentGeojonValidationSpec.ts ================================================ import { Validators } from "../../src/validation/Validators"; describe("Tileset MAXAR_content_geojson extension validation", function () { it("detects issues in invalidTilesetWithGeojson", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidTilesetWithGeojson.json" ); // Expect validation errors because GeoJSON content is used without // declaring the MAXAR_content_geojson extension in extensionsUsed // and extensionsRequired expect(result.length).toEqual(2); // Should have content validation errors for undeclared extension expect(result.get(0).type).toEqual("EXTENSION_FOUND_BUT_NOT_USED"); expect(result.get(1).type).toEqual("EXTENSION_REQUIRED_BUT_NOT_DECLARED"); }); it("detects error when extension is in extensionsUsed but not in extensionsRequired", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/extensionsUsedButNotRequiredTileset.json" ); // Should have validation error because MAXAR_content_geojson must be in both // extensionsUsed AND extensionsRequired when using GeoJSON content expect(result.length).toEqual(1); // Should have extension validation error for missing from extensionsRequired expect(result.get(0).type).toEqual("EXTENSION_REQUIRED_BUT_NOT_DECLARED"); expect(result.get(0).message).toContain("MAXAR_content_geojson"); expect(result.get(0).message).toContain( "was not declared in 'extensionsRequired'" ); }); it("detects invalid propertiesSchemaUri type", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidPropertiesSchemaUri.json" ); // Expect error for invalid propertiesSchemaUri type expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); expect(result.get(0).message).toContain("propertiesSchemaUri"); }); it("detects invalid extension object type", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidExtensionObject.json" ); // Expect errors for invalid extension object type expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); expect(result.get(0).message).toContain("MAXAR_content_geojson"); expect(result.get(1).type).toEqual("TYPE_MISMATCH"); expect(result.get(1).message).toContain("MAXAR_content_geojson"); }); it("validates extension without propertiesSchemaUri", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/validTilesetWithMaxarContentGeojson.json" ); // Should have no validation errors for valid tileset expect(result.length).toEqual(0); }); it("validates extension with valid propertiesSchemaUri", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/validWithPropertiesSchemaUri.json" ); // Should have no validation errors for valid tileset expect(result.length).toEqual(0); }); it("detects errors in invalid schema content", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidSchemaContent.json" ); // Should have exactly 6 errors for invalid schema content expect(result.length).toEqual(6); // Check that we have validation errors for the schema expect(result.get(0).message).toContain("property is required"); expect(result.get(1).type).toEqual("VALUE_NOT_IN_LIST"); expect(result.get(1).message).toContain("InvalidGeometryType"); expect(result.get(2).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(2).message).toContain("property must be in"); expect(result.get(3).type).toEqual("STRING_LENGTH_MISMATCH"); expect(result.get(3).message).toContain("must have a length of at least 1"); expect(result.get(4).type).toEqual("VALUE_NOT_IN_LIST"); expect(result.get(4).message).toContain("InvalidType"); expect(result.get(5).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(5).message).toContain( "can only be used with Integer and Float types" ); }); it("detects error when schema file does not exist", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/nonExistentSchema.json" ); // Should have IO error for missing file expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IO_ERROR"); expect(result.get(0).message).toContain("could not be resolved"); }); it("detects error when min > max in property schema", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidMinMaxTileset.json" ); // Should have exactly 1 validation errors for min > max expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(0).message).toContain("min"); expect(result.get(0).message).toContain("must be <= max"); }); it("detects error when required property has default value", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidRequiredWithDefaultTileset.json" ); // Should have content validation info and validation errors for required with default expect(result.length).toEqual(1); // Check that we have a VALUE_NOT_IN_RANGE error for required property with default expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(0).message).toContain( "A required property cannot have a default value" ); }); it("validates non-required properties without default values (defaults to null)", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/validOptionalWithoutDefaultsTileset.json" ); // Should have no validation errors for valid tileset expect(result.length).toEqual(0); }); it("detects error when default values have incorrect types", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidDefaultTypesTileset.json" ); expect(result.length).toEqual(5); // Check that we have TYPE_MISMATCH errors for incorrect default value types expect(result.get(0).type).toEqual("TYPE_MISMATCH"); expect(result.get(0).message).toContain( "property must have type 'string', but has type 'number'" ); expect(result.get(1).type).toEqual("TYPE_MISMATCH"); expect(result.get(1).message).toContain( "roperty must have type 'integer', but has type 'string'" ); expect(result.get(2).type).toEqual("TYPE_MISMATCH"); expect(result.get(2).message).toContain( "property must have type 'number', but has type 'boolean'" ); expect(result.get(3).type).toEqual("TYPE_MISMATCH"); expect(result.get(3).message).toContain( "property must have type 'boolean', but has type 'string'" ); expect(result.get(4).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(4).message).toContain( "Variant type properties cannot have default values" ); }); it("detects error when propertiesSchemaUri has invalid URI format", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidUriFormat.json" ); // Should have validation error for invalid URI format expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_VALUE_INVALID"); expect(result.get(0).message).toContain("must be a valid URI"); }); it("detects error when min/max properties are used on non-numeric types", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidMinMaxOnNonNumericType.json" ); expect(result.length).toEqual(3); // Check that we have VALUE_NOT_IN_RANGE errors for min/max on wrong types expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(0).message).toContain( "Properties 'min' and 'max' can only be used with Integer and Float types, but property type is 'String'" ); expect(result.get(1).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(1).message).toContain( "Properties 'min' and 'max' can only be used with Integer and Float types, but property type is 'Boolean'" ); expect(result.get(2).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(2).message).toContain( "Properties 'min' and 'max' can only be used with Integer and Float types, but property type is 'Variant'" ); }); it("validates non-required properties without default values (defaults to null)", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/validOptionalWithoutDefaultsTileset.json" ); // Should have no validation errors - non-required properties are allowed to omit defaults expect(result.length).toEqual(0); }); it("detects error when schema contains duplicate property IDs", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/duplicatePropertyIdsTileset.json" ); // Should have validation errors for duplicate property IDs expect(result.length).toBeGreaterThan(0); // Find the duplicate ID error let foundDuplicateIdError = false; for (let i = 0; i < result.length; i++) { const issue = result.get(i); if ( issue.type === "VALUE_NOT_IN_RANGE" && issue.message.includes("Property ID") && issue.message.includes("is not unique") ) { foundDuplicateIdError = true; expect(issue.message).toContain("duplicateId"); expect(issue.message).toContain("All property IDs must be unique"); break; } } // Should have found at least one duplicate ID error expect(foundDuplicateIdError).toBe(true); }); it("detects error when default values have incorrect types", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidDefaultTypesTileset.json" ); expect(result.length).toEqual(5); // Check that we have TYPE_MISMATCH errors for incorrect default value types expect(result.get(0).type).toEqual("TYPE_MISMATCH"); expect(result.get(0).message).toContain( "property must have type 'string', but has type 'number'" ); expect(result.get(1).type).toEqual("TYPE_MISMATCH"); expect(result.get(1).message).toContain( "roperty must have type 'integer', but has type 'string'" ); expect(result.get(2).type).toEqual("TYPE_MISMATCH"); expect(result.get(2).message).toContain( "property must have type 'number', but has type 'boolean'" ); expect(result.get(3).type).toEqual("TYPE_MISMATCH"); expect(result.get(3).message).toContain( "property must have type 'boolean', but has type 'string'" ); expect(result.get(4).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(4).message).toContain( "Variant type properties cannot have default values" ); }); it("detects error when propertiesSchemaUri has invalid URI format", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidUriFormat.json" ); // Should have validation error for invalid URI format expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_VALUE_INVALID"); expect(result.get(0).message).toContain("must be a valid URI"); }); it("detects error when min/max properties are used on non-numeric types", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/invalidMinMaxOnNonNumericType.json" ); expect(result.length).toEqual(3); // Check that we have VALUE_NOT_IN_RANGE errors for min/max on wrong types expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(0).message).toContain( "Properties 'min' and 'max' can only be used with Integer and Float types, but property type is 'String'" ); expect(result.get(1).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(1).message).toContain( "Properties 'min' and 'max' can only be used with Integer and Float types, but property type is 'Boolean'" ); expect(result.get(2).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(2).message).toContain( "Properties 'min' and 'max' can only be used with Integer and Float types, but property type is 'Variant'" ); }); it("detects error when GeoJSON contains bare geometry instead of Feature or FeatureCollection", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/bareGeometryTileset.json" ); // Should have validation error because while bare geometry is technically valid GeoJSON, // most GeoJSON consumers expect Features or FeatureCollections at the root level expect(result.length).toEqual(1); // Check that we have a content validation error for the bare geometry expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); expect(result.get(0).message).toContain( "bare_geometry.geojson caused validation errors" ); }); it("detects error when GeoJSON contains GeometryCollection geometry", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarContentGeojson/geometryCollectionTileset.json" ); // Should have validation error because GeometryCollection is not supported // by the MAXAR_content_geojson extension, even though it's valid GeoJSON expect(result.length).toEqual(1); // Check that we have a content validation error for the GeometryCollection expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); expect(result.get(0).message).toContain( "geometryCollection.geojson caused validation errors" ); // Check that the specific error message mentions MAXAR_content_geojson extension expect(result.get(0).causes.length).toEqual(1); expect(result.get(0).causes[0].type).toEqual("VALUE_NOT_IN_LIST"); expect(result.get(0).causes[0].message).toContain( "GeometryCollection is not supported by the MAXAR_content_geojson extension" ); expect(result.get(0).causes[0].message).toContain( "Supported geometry types are: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon" ); }); }); ================================================ FILE: specs/extensions/MaxarExtentValidatorSpec.ts ================================================ import { Validators } from "../../src/validation/Validators"; describe("Tileset MAXAR_extent extension validation", function () { it("detects no issues in validTilesetWithMaxarExtent", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/validTilesetWithMaxarExtent.json" ); expect(result.length).toEqual(0); }); it("detects issues in invalidEmptyUri", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/invalidEmptyUri.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_VALUE_INVALID"); }); it("detects issues in invalidMissingUri", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/invalidMissingUri.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in invalidUriType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/invalidUriType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in invalidNonResolvableUri", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/invalidNonResolvableUri.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IO_ERROR"); expect(result.get(0).message).toContain("could not be resolved"); }); it("detects issues in invalidGeojsonContent", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/invalidGeojsonContent.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); expect(result.get(0).message).toContain("coordinates"); }); it("validates spatial containment with validTilesetWithSpatialExtent", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/validTilesetWithSpatialExtent.json" ); expect(result.length).toEqual(0); }); it("detects spatial containment issues in invalidSpatialExtent", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/invalidSpatialExtent.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BOUNDING_VOLUMES_INCONSISTENT"); expect(result.get(0).message).toContain( "not contained within the root tile's bounding volume" ); }); it("validates GeoJSON with only Polygon and MultiPolygon geometries", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/validPolygonsOnlyTileset.json" ); expect(result.length).toEqual(0); }); it("detects invalid geometry types in GeoJSON", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/invalidGeometryTypesTileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GEOMETRY_TYPE"); expect(result.get(0).message).toContain( "must contain only Polygon or MultiPolygon geometries" ); expect(result.get(0).message).toContain("Point, LineString"); }); it("detects insufficient coordinates in extent polygon", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/insufficientCoordinatesTileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GEOMETRY_SIZE"); expect(result.get(0).message).toContain( "must have at least 3 unique coordinates" ); }); it("detects self-intersecting extent polygon", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/selfIntersectingTileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GEOMETRY_STRUCTURE"); expect(result.get(0).message).toContain( "is self-intersecting, which is forbidden" ); }); it("detects complex extent with vertex outside southern hemisphere region bounds", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/extentOverflowingTileTileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("BOUNDING_VOLUMES_INCONSISTENT"); expect(result.get(0).message).toContain( "not contained within the root tile's bounding volume" ); }); it("does not flag a near-miss as self-intersection", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/nearMissTileset.json" ); expect(result.length).toEqual(0); }); it("flags a true crossing as self-intersection", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/trueCrossingTileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GEOMETRY_STRUCTURE"); expect(result.get(0).message).toContain( "is self-intersecting, which is forbidden" ); }); it("flags a collinear overlap as invalid geometry", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/collinearOverlapTileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GEOMETRY_STRUCTURE"); expect(result.get(0).message).toContain( "is self-intersecting, which is forbidden" ); }); it("accepts overlapping rings without self-intersections", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/overlappingRingsTileset.json" ); expect(result.length).toEqual(0); }); it("flags internal vertex touching a non-adjacent edge as invalid", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/internalTouchRingTileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GEOMETRY_STRUCTURE"); }); it("flags near-vertex-on-other-side that breaks the ring as invalid", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/nearVertexOnOtherSideFailTileset.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GEOMETRY_STRUCTURE"); }); it("accepts near-vertex-on-other-side within epsilon as valid", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarExtent/nearVertexOnOtherSideOkTileset.json" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/extensions/MaxarGridValidationSpec.ts ================================================ import { Validators } from "../../src/validation/Validators"; describe("Tileset MAXAR_grid extension validation", function () { it("detects no issues in validTilesetWithMaxarGrid", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/validTilesetWithMaxarGrid.json" ); expect(result.length).toEqual(0); }); // Note: VRICON_grid is just a legacy name of MAXAR_grid it("detects no issues in validTilesetWithVriconGrid", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/validTilesetWithVriconGrid.json" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/extensions/MaxarGridValidatorSpec.ts ================================================ import { Validators } from "../../src/validation/Validators"; describe("Tileset MAXAR_grid extension validation", function () { it("detects no issues in validTilesetWithMaxarGrid", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/validTilesetWithMaxarGrid.json" ); expect(result.length).toEqual(0); }); it("detects no issues in validTilesetWithVriconGrid", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/validTilesetWithVriconGrid.json" ); expect(result.length).toEqual(0); }); it("detects issues in invalidGridType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidGridType.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in invalidCenterLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidCenterLength.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in invalidSizeLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidSizeLength.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in invalidBoundingBoxLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidBoundingBoxLength.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in invalidIndexLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidIndexLength.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in invalidElevation", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidElevation.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects no issues in validS2Grid", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/validS2Grid.json" ); expect(result.length).toEqual(0); }); it("detects issues in invalidS2GridWithCenter", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidS2GridWithCenter.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in invalidSrsReferenceSystem", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidSrsReferenceSystem.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in invalidTileLevel", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidTileLevel.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in invalidS2GridWithSize", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidS2GridWithSize.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in invalidS2GridWithSrs", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidS2GridWithSrs.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in invalidCoordinateSystemType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidCoordinateSystemType.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in invalidCoordinateSystemValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidCoordinateSystemValue.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("STRING_VALUE_INVALID"); }); it("detects issues in invalidBoundingBoxSemantics", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/maxarGrid/invalidBoundingBoxSemantics.json" ); expect(result.length).toBeGreaterThan(0); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); }); ================================================ FILE: specs/extensions/NgaGpmValidatorSpec.ts ================================================ import { Validators } from "../../src/validation/Validators"; describe("Tileset NGA_gpm extension validation", function () { it("detects issues in ngaGpmInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmInvalidType.json" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); expect(result.get(1).type).toEqual("EXTENSION_USED_BUT_NOT_FOUND"); }); it("detects issues in ngaGpmMasterRecordMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmMasterRecordMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in ngaGpmMasterRecordInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmMasterRecordInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ngaGpmUnmodeledErrorRecordMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmUnmodeledErrorRecordMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in ngaGpmUnmodeledErrorRecordInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmUnmodeledErrorRecordInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ngaGpmInterpolationParamsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmInterpolationParamsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in ngaGpmInterpolationParamsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmInterpolationParamsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ngaGpmInterTileCorrelationGroupsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmInterTileCorrelationGroupsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in ngaGpmInterTileCorrelationGroupsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmInterTileCorrelationGroupsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ngaGpmInterTileCorrelationGroupsInvalidLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmInterTileCorrelationGroupsInvalidLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in ngaGpmInterTileCorrelationGroupsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmInterTileCorrelationGroupsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in ngaGpmThreeDimConformalParamsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmThreeDimConformalParamsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ngaGpmPpeManifestInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmPpeManifestInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ngaGpmAnchorPointMetadataInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ngaGpmAnchorPointMetadataInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in masterRecordVersionMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordVersionMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in masterRecordVersionInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordVersionInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in masterRecordImplementationMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordImplementationMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in masterRecordImplementationInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordImplementationInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in masterRecordModelCoordSystemMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordModelCoordSystemMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in masterRecordModelCoordSystemInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordModelCoordSystemInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in masterRecordIdInformationMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordIdInformationMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in masterRecordIdInformationInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordIdInformationInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in masterRecordDatasetExtentInformationInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordDatasetExtentInformationInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in masterRecordCollectionRecordListInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordCollectionRecordListInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in masterRecordCollectionRecordListInvalidLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordCollectionRecordListInvalidLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in masterRecordCollectionRecordListElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/masterRecordCollectionRecordListElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in modelCoordSystemMcsTypeMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in modelCoordSystemMcsTypeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in modelCoordSystemMcsTypeInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in modelCoordSystemMcsTypeEcefCrsEcefMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefCrsEcefMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in modelCoordSystemMcsTypeEcefCrsEcefInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefCrsEcefInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in modelCoordSystemMcsTypeLsrAxisUnitVectorsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrAxisUnitVectorsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in modelCoordSystemMcsTypeLsrAxisUnitVectorsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrAxisUnitVectorsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in modelCoordSystemMcsTypeLsrOriginMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrOriginMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in modelCoordSystemMcsTypeLsrOriginInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrOriginInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in modelCoordSystemMcsTypeUtmCrsHorizontalUtmMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmCrsHorizontalUtmMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in modelCoordSystemMcsTypeUtmCrsHorizontalUtmInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmCrsHorizontalUtmInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in modelCoordSystemMcsTypeUtmCrsVerticalMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmCrsVerticalMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in modelCoordSystemMcsTypeUtmCrsVerticalInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmCrsVerticalInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in referenceSystemDefinitionMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemDefinitionMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in referenceSystemDescriptionInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemDescriptionInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in referenceSystemEpochInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemEpochInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in referenceSystemEpochMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemEpochMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in referenceSystemNameInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemNameInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in referenceSystemNameMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemNameMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in referenceSystemOrgWithIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemOrgWithIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in referenceSystemOrgWithIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemOrgWithIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in referenceSystemWithDefinitionAndEpoch", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemWithDefinitionAndEpoch.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in referenceSystemWithDefinitionAndOrgWithId", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceSystemWithDefinitionAndOrgWithId.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in organizationSystemIdPairOrganizationInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/organizationSystemIdPairOrganizationInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in organizationSystemIdPairOrganizationMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/organizationSystemIdPairOrganizationMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in organizationSystemIdPairSystemIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/organizationSystemIdPairSystemIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in organizationSystemIdPairSystemIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/organizationSystemIdPairSystemIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in point3dInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/point3dInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in point3dInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/point3dInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in point3dElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/point3dElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in ppeManifestInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ppeManifestInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in ppeManifestInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ppeManifestInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in ppeManifestElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ppeManifestElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in ppeMetadataMaxInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ppeMetadataMaxInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeMetadataMinInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ppeMetadataMinInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeMetadataSourceMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ppeMetadataSourceMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in ppeMetadataSourceInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ppeMetadataSourceInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in rotationThetasInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/rotationThetasInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in rotationThetasInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/rotationThetasInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in rotationThetasElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/rotationThetasElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in sensorRecordCollectionUnitRecordsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in sensorRecordCollectionUnitRecordsInvalidLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsInvalidLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in sensorRecordCollectionUnitRecordsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in sensorRecordCollectionUnitRecordsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in sensorRecordSensorIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordSensorIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in sensorRecordSensorIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordSensorIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in sensorRecordSensorModeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordSensorModeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in sensorRecordSensorModeMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordSensorModeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in sensorRecordSensorTypeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordSensorTypeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in sensorRecordSensorTypeMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordSensorTypeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in spdcfAInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfAInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in spdcfAInvalidValueA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfAInvalidValueA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfAInvalidValueB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfAInvalidValueB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfAlphaInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfAlphaInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in spdcfAlphaInvalidValueA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfAlphaInvalidValueA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfAlphaInvalidValueB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfAlphaInvalidValueB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfAlphaMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfAlphaMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in spdcfAMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfAMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in spdcfBetaInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfBetaInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in spdcfBetaInvalidValueA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfBetaInvalidValueA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfBetaInvalidValueB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfBetaInvalidValueB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfBetaMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfBetaMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in spdcfTInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfTInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in spdcfTInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfTInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfTMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/spdcfTMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in threeDimConformalParamsCovarianceElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsCovarianceElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in threeDimConformalParamsCovarianceInvalidLengthFor4A", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsCovarianceInvalidLengthFor4A.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_INCONSISTENT"); }); it("detects issues in threeDimConformalParamsCovarianceInvalidLengthFor4B", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsCovarianceInvalidLengthFor4B.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_INCONSISTENT"); }); it("detects issues in threeDimConformalParamsCovarianceInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsCovarianceInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in threeDimConformalParamsCovarianceMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsCovarianceMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in threeDimConformalParamsFlagsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsFlagsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in threeDimConformalParamsFlagsInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsFlagsInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in threeDimConformalParamsFlagsInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsFlagsInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in threeDimConformalParamsFlagsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsFlagsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in threeDimConformalParamsFlagsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsFlagsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in threeDimConformalParamsNormalizingScaleFactorInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsNormalizingScaleFactorInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in threeDimConformalParamsNormalizingScaleFactorMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsNormalizingScaleFactorMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in threeDimConformalParamsParametersElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsParametersElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in threeDimConformalParamsParametersInvalidLengthFor4A", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsParametersInvalidLengthFor4A.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_INCONSISTENT"); }); it("detects issues in threeDimConformalParamsParametersInvalidLengthFor4B", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsParametersInvalidLengthFor4B.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_INCONSISTENT"); }); it("detects issues in threeDimConformalParamsParametersInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsParametersInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in threeDimConformalParamsParametersMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsParametersMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in threeDimConformalParamsRecenteringElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsRecenteringElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in threeDimConformalParamsRecenteringInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsRecenteringInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in threeDimConformalParamsRecenteringInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsRecenteringInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in threeDimConformalParamsRecenteringInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsRecenteringInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in threeDimConformalParamsRecenteringMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsRecenteringMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in threeDimConformalParamsFlagsInvalidValues", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/threeDimConformalParamsFlagsInvalidValues.json" ); expect(result.length).toEqual(3); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); expect(result.get(1).type).toEqual("ARRAY_LENGTH_MISMATCH"); expect(result.get(2).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in unitVectorInvalidLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unitVectorInvalidLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in unitVectorInvalidElementValueA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unitVectorInvalidElementValueA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in unitVectorInvalidElementValueB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unitVectorInvalidElementValueB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in unmodeledErrorCorrParamsInvalidElementType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorCorrParamsInvalidElementType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in unmodeledErrorCorrParamsInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorCorrParamsInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in unmodeledErrorCorrParamsInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorCorrParamsInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in unmodeledErrorCorrParamsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorCorrParamsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in unmodeledErrorCorrParamsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorCorrParamsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in unmodeledErrorCorrRotationThetasInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorCorrRotationThetasInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in unmodeledErrorCorrRotationThetasMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorCorrRotationThetasMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in unmodeledErrorPostsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorPostsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in unmodeledErrorPostsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorPostsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in unmodeledErrorPostsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorPostsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in unmodeledErrorUniqueIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorUniqueIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in unmodeledErrorUniqueIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorUniqueIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in unmodeledErrorPostCovarianceMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorPostCovarianceMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in unmodeledErrorPostCovarianceInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorPostCovarianceInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in unmodeledErrorPostPositionInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorPostPositionInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in unmodeledErrorPostPositionMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unmodeledErrorPostPositionMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in covarUpperTriangleElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/covarUpperTriangleElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in covarUpperTriangleInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/covarUpperTriangleInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in covarUpperTriangleInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/covarUpperTriangleInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in interpolationParamsDampeningParamInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsDampeningParamInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in interpolationParamsDampeningParamMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsDampeningParamMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in interpolationParamsInterpNumPostsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsInterpNumPostsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in interpolationParamsInterpNumPostsInvalidValueA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsInterpNumPostsInvalidValueA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in interpolationParamsInterpNumPostsInvalidValueB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsInterpNumPostsInvalidValueB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in interpolationParamsInterpNumPostsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsInterpNumPostsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in interpolationParamsInterpolationModeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsInterpolationModeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in interpolationParamsInterpolationModeInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsInterpolationModeInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in interpolationParamsInterpolationModeMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsInterpolationModeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in interpolationParamsInterpolationModeNearestNeighborWithDampeningParam", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsInterpolationModeNearestNeighborWithDampeningParam.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in interpolationParamsInterpolationModeNearestNeighborWithInterpNumPoints", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/interpolationParamsInterpolationModeNearestNeighborWithInterpNumPoints.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in collectionRecordCollectionIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionRecordCollectionIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in collectionRecordCollectionIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionRecordCollectionIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in collectionRecordPlatformIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionRecordPlatformIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in collectionRecordPlatformIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionRecordPlatformIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in collectionRecordSensorRecordsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionRecordSensorRecordsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in collectionRecordSensorRecordsInvalidLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionRecordSensorRecordsInvalidLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in collectionRecordSensorRecordsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionRecordSensorRecordsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in collectionRecordSensorRecordsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionRecordSensorRecordsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in sensorRecordCollectionUnitRecordsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in sensorRecordCollectionUnitRecordsInvalidLength", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsInvalidLength.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in sensorRecordCollectionUnitRecordsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in sensorRecordCollectionUnitRecordsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordCollectionUnitRecordsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in sensorRecordSensorIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordSensorIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in sensorRecordSensorIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordSensorIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in sensorRecordSensorModeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordSensorModeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in sensorRecordsSensorModeMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordsSensorModeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in sensorRecordsSensorTypeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordsSensorTypeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in sensorRecordsSensorTypeMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/sensorRecordsSensorTypeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in collectionUnitRecordCollectionUnitIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionUnitRecordCollectionUnitIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in collectionUnitRecordCollectionUnitIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionUnitRecordCollectionUnitIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in collectionUnitRecordExtentInformationInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionUnitRecordExtentInformationInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in collectionUnitRecordExtentInformationMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionUnitRecordExtentInformationMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in collectionUnitRecordPointSourceIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionUnitRecordPointSourceIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in collectionUnitRecordPointSourceIdInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionUnitRecordPointSourceIdInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in collectionUnitRecordPointSourceIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionUnitRecordPointSourceIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in collectionUnitRecordReferenceDateTimeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionUnitRecordReferenceDateTimeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in collectionUnitRecordReferenceDateTimeMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/collectionUnitRecordReferenceDateTimeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in extentInformationLsrAxisUnitVectorsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in extentInformationLsrAxisUnitVectorsInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in extentInformationLsrAxisUnitVectorsInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in extentInformationLsrAxisUnitVectorsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in extentInformationLsrAxisUnitVectorsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrAxisUnitVectorsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in extentInformationLsrLengthsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrLengthsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in extentInformationLsrLengthsInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrLengthsInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in extentInformationLsrLengthsInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrLengthsInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in extentInformationLsrLengthsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrLengthsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in extentInformationLsrLengthsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationLsrLengthsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in extentInformationOriginInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationOriginInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in extentInformationOriginMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/extentInformationOriginMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in idInformationDatasetIdInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/idInformationDatasetIdInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in idInformationDatasetIdMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/idInformationDatasetIdMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in idInformationReferenceDateTimeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/idInformationReferenceDateTimeInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in idInformationReferenceDateTimeMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/idInformationReferenceDateTimeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in correlationGroupGroupFlagsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupGroupFlagsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in correlationGroupGroupFlagsInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupGroupFlagsInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in correlationGroupGroupFlagsInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupGroupFlagsInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in correlationGroupGroupFlagsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupGroupFlagsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in correlationGroupGroupsGroupFlagsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupGroupsGroupFlagsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in correlationGroupGroupsParamsInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupGroupsParamsInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in correlationGroupGroupsParamsMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupGroupsParamsMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in correlationGroupParamsElementInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupParamsElementInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in correlationGroupParamsInvalidLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupParamsInvalidLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in correlationGroupParamsInvalidLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupParamsInvalidLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in correlationGroupRotationThetasInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupRotationThetasInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in correlationGroupRotationThetasMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/correlationGroupRotationThetasMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in anchorPointMetadataContentIndexInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/anchorPointMetadataContentIndexInvalidType.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in anchorPointMetadataContentIndexInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/anchorPointMetadataContentIndexInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in anchorPointMetadataContentIndexMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/anchorPointMetadataContentIndexMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in anchorPointMetadataPlacementTypeInvalidValue", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/anchorPointMetadataPlacementTypeInvalidValue.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in anchorPointMetadataPlacementTypeMeshContentWithContentIndex", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/anchorPointMetadataPlacementTypeMeshContentWithContentIndex.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in anchorPointMetadataPlacementTypeMissing", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/anchorPointMetadataPlacementTypeMissing.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in lsrAxisUnitVectorsNotOrthogonalA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/lsrAxisUnitVectorsNotOrthogonalA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VECTORS_NOT_ORTHOGONAL"); }); it("detects issues in lsrAxisUnitVectorsNotOrthogonalB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/lsrAxisUnitVectorsNotOrthogonalB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VECTORS_NOT_ORTHOGONAL"); }); it("detects issues in lsrAxisUnitVectorsNotOrthogonalC", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/lsrAxisUnitVectorsNotOrthogonalC.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VECTORS_NOT_ORTHOGONAL"); }); it("detects issues in ppeMetadataSourceValuesNotUnique", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/ppeMetadataSourceValuesNotUnique.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "PER_POINT_ERROR_SOURCE_VALUES_NOT_UNIQUE" ); }); it("detects issues in referenceDateTimeNotIso8601A", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceDateTimeNotIso8601A.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_VALUE_INVALID"); }); it("detects issues in referenceDateTimeNotIso8601B", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceDateTimeNotIso8601B.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_VALUE_INVALID"); }); it("detects issues in referenceDateTimeNotIso8601C", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceDateTimeNotIso8601C.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_VALUE_INVALID"); }); it("detects issues in referenceDateTimeNotIso8601D", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/referenceDateTimeNotIso8601D.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_VALUE_INVALID"); }); it("detects issues in unitVectorNotUnitLengthA", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unitVectorNotUnitLengthA.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VECTOR_NOT_UNIT_LENGTH"); }); it("detects issues in unitVectorNotUnitLengthB", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/unitVectorNotUnitLengthB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VECTOR_NOT_UNIT_LENGTH"); }); it("detects issues in modelCoordSystemMcsTypeEcefWithAxisUnitVectors", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefWithAxisUnitVectors.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in modelCoordSystemMcsTypeEcefWithCrsHorizontalUtm", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefWithCrsHorizontalUtm.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in modelCoordSystemMcsTypeEcefWithCrsVertical", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefWithCrsVertical.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in modelCoordSystemMcsTypeEcefWithOrigin", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeEcefWithOrigin.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in modelCoordSystemMcsTypeLsrWithCrsEcef", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrWithCrsEcef.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in modelCoordSystemMcsTypeLsrWithCrsHorizontalUtm", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrWithCrsHorizontalUtm.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in modelCoordSystemMcsTypeLsrWithCrsVertical", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeLsrWithCrsVertical.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in modelCoordSystemMcsTypeUtmWithAxisUnitVectors", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmWithAxisUnitVectors.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in modelCoordSystemMcsTypeUtmWithCrsEcef", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmWithCrsEcef.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in modelCoordSystemMcsTypeUtmWithOrigin", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/gpm/modelCoordSystemMcsTypeUtmWithOrigin.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); }); ================================================ FILE: specs/extensions/VriconClassValidationSpec.ts ================================================ import { Validators } from "../../src/validation/Validators"; describe("Tileset VRICON_class extension validation", function () { it("detects no issues in validTilesetWithVriconClass", async function () { const result = await Validators.validateTilesetFile( "specs/data/extensions/vriconClass/validTilesetWithVriconClass.json" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/gltfExtensions/ExtInstanceFeaturesValidationSpec.ts ================================================ import { validateGltf } from "./validateGltf"; // NOTE: These specs only cover the cases that are specific for // the EXT_instance_features validation. Most of the low-level // validation (e.g. that of the actual feature IDs) is covered // with the ExtMeshFeaturesValidationSpec.ts. describe("EXT_instance_features extension validation", function () { it("detects issues in InstanceFeaturesFeatureIdAttributeInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/instanceFeatures/InstanceFeaturesFeatureIdAttributeInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in InstanceFeaturesWithoutMeshGpuInstancing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/instanceFeatures/InstanceFeaturesWithoutMeshGpuInstancing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects no issues in ValidInstanceFeatures", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/instanceFeatures/ValidInstanceFeatures.gltf" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/gltfExtensions/ExtMeshFeaturesValidationSpec.ts ================================================ import { validateGltf } from "./validateGltf"; describe("EXT_mesh_features extension validation", function () { it("detects issues in FeatureIdAttributeAccessorNormalized", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeAccessorNormalized.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects issues in FeatureIdAttributeAccessorNotScalar", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeAccessorNotScalar.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects issues in FeatureIdAttributeAttributeInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeAttributeInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in FeatureIdAttributeAttributeInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeAttributeInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in FeatureIdAttributeFeatureCountInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in FeatureIdAttributeFeatureCountInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in FeatureIdAttributeFeatureCountMismatch", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountMismatch.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("FEATURE_COUNT_MISMATCH"); }); it("detects issues in FeatureIdAttributeFeatureCountMismatchForNullFeatureId", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountMismatchForNullFeatureId.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("FEATURE_COUNT_MISMATCH"); }); it("detects issues in FeatureIdAttributeFeatureCountMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeFeatureCountMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in FeatureIdAttributeLabelInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeLabelInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in FeatureIdAttributeLabelInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeLabelInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_PATTERN_MISMATCH"); }); it("detects issues in FeatureIdAttributeNullFeatureIdInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeNullFeatureIdInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in FeatureIdAttributeNullFeatureIdInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdAttributeNullFeatureIdInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in FeatureIdTextureFeatureCountMismatch", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureFeatureCountMismatch.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("FEATURE_COUNT_MISMATCH"); }); it("detects issues in FeatureIdTextureSamplerInvalidFilterMode", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureSamplerInvalidFilterMode.gltf" ); expect(result.length).toEqual(2); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); expect(result.get(1).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in FeatureIdTextureTextureChannelsInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureChannelsInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in FeatureIdTextureTextureChannelsInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureChannelsInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in FeatureIdTextureTextureChannelsTooManyChannels", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureChannelsTooManyChannels.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TEXTURE_CHANNELS_OUT_OF_RANGE"); }); it("detects issues in FeatureIdTextureTextureChannelsTooManyElements", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureChannelsTooManyElements.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TEXTURE_CHANNELS_OUT_OF_RANGE"); }); it("detects issues in FeatureIdTextureTextureImageDataInvalid", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureImageDataInvalid.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IO_ERROR"); }); it("detects issues in FeatureIdTextureTextureIndexInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureIndexInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in FeatureIdTextureTextureIndexInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureIndexInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in FeatureIdTextureTextureInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in FeatureIdTextureTextureTexCoordInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureTexCoordInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in FeatureIdTextureTextureTexCoordInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/FeatureIdTextureTextureTexCoordInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects no issues in ValidFeatureIdAttribute", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/ValidFeatureIdAttribute.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidFeatureIdAttributeWithByteStride", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/ValidFeatureIdAttributeWithByteStride.glb" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidFeatureIdAttributeWithLargerFeatureCount", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/ValidFeatureIdAttributeWithLargerFeatureCount.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidFeatureIdAttributeWithNullFeatureId", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/ValidFeatureIdAttributeWithNullFeatureId.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidFeatureIdTexture (GLB)", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/ValidFeatureIdTexture.glb" ); expect(result.length).toEqual(0); }); it("detects issues in ValidFeatureIdTexture", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/ValidFeatureIdTexture.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidFeatureIdTextureUsingDefaultChannels", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/ValidFeatureIdTextureUsingDefaultChannels.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidFeatureIdAttributeDefault", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/meshFeatures/ValidFeatureIdAttributeDefault/ValidFeatureIdAttributeDefault.gltf" ); // TODO: This should actually DO cause an issue for now, // because a default glTF (with external resources) // can not be read with glTF-Transform. // See https://github.com/donmccurdy/glTF-Transform/issues/1099 // and the corresponding notes in `GltfDataReader.ts`! console.error( "ValidFeatureIdAttributeDefault is skipping actual data validation" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/gltfExtensions/ExtStructuralMetadataValidationSpec.ts ================================================ import { validateGltf } from "./validateGltf"; describe("EXT_structural_metadata extension validation", function () { it("detects issues in ExtensionInMeshPrimitiveWithoutTopLevelObject", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/ExtensionInMeshPrimitiveWithoutTopLevelObject.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects issues in PropertyAttributesClassPropertyArray", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyArray.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_METADATA_PROPERTY_TYPE"); }); it("detects issues in PropertyAttributesClassPropertyInvalidComponentType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyInvalidComponentType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_METADATA_PROPERTY_TYPE"); }); it("detects issues in PropertyAttributesClassPropertyInvalidEnumValueType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyInvalidEnumValueType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_METADATA_PROPERTY_TYPE"); }); it("detects issues in PropertyAttributesClassPropertyMaxNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyMaxNotInRange.gltf" ); expect(result.length).toEqual(4); for (let i = 0; i < result.length; i++) { expect(result.get(i).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); } }); it("detects issues in PropertyAttributesClassPropertyMinNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyMinNotInRange.gltf" ); expect(result.length).toEqual(4); for (let i = 0; i < result.length; i++) { expect(result.get(i).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); } }); it("detects issues in PropertyAttributesClassPropertyString", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesClassPropertyString.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_METADATA_PROPERTY_TYPE"); }); it("detects issues in PropertyAttributesMeshPrimitivePropertyAttributesInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesMeshPrimitivePropertyAttributesInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in PropertyAttributesMeshPrimitivePropertyAttributesInvalidElementValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesMeshPrimitivePropertyAttributesInvalidElementValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in PropertyAttributesMeshPrimitivePropertyAttributesInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesMeshPrimitivePropertyAttributesInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in PropertyAttributesMeshPrimitivePropertyAttributesInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesMeshPrimitivePropertyAttributesInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in PropertyAttributesPropertyAttributePropertyInvalidAttribute", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyInvalidAttribute.gltf" ); expect(result.length).toEqual(3); for (let i = 0; i < result.length; i++) { expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); } }); it("detects issues in PropertyAttributesPropertyAttributePropertyMaxMismatch", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyMaxMismatch.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects issues in PropertyAttributesPropertyAttributePropertyMaxNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyMaxNotInRange.gltf" ); expect(result.length).toEqual(4); for (let i = 0; i < result.length; i++) { expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); } }); it("detects issues in PropertyAttributesPropertyAttributePropertyMinMismatch", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyMinMismatch.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects issues in PropertyAttributesPropertyAttributePropertyMinNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyAttributesPropertyAttributePropertyMinNotInRange.gltf" ); expect(result.length).toEqual(4); for (let i = 0; i < result.length; i++) { expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); } }); it("detects issues in PropertyTextureClassPropertyMaxNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureClassPropertyMaxNotInRange.gltf" ); expect(result.length).toEqual(7); for (let i = 0; i < result.length; i++) { expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); } }); it("detects issues in PropertyTextureClassPropertyMinNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureClassPropertyMinNotInRange.gltf" ); expect(result.length).toEqual(10); for (let i = 0; i < result.length; i++) { expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); } }); it("detects issues in PropertyTextureClassPropertyWithOffsetScaleMinNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureClassPropertyWithOffsetScaleMinNotInRange.gltf" ); expect(result.length).toEqual(10); for (let i = 0; i < result.length; i++) { expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); } }); it("detects issues in PropertyTextureEnumsInvalidEnumValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureEnumsInvalidEnumValue.gltf" ); expect(result.length).toEqual(3); for (let i = 0; i < result.length; i++) { expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); } }); it("detects issues in PropertyTextureInvalidPropertyTypeA", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureInvalidPropertyTypeA.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_METADATA_PROPERTY_TYPE"); }); it("detects issues in PropertyTextureInvalidPropertyTypeB", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureInvalidPropertyTypeB.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_METADATA_PROPERTY_TYPE"); }); it("detects issues in PropertyTextureMeshPrimitivePropertyTexturesInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTexturesInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in PropertyTextureMeshPrimitivePropertyTexturesInvalidElementValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTexturesInvalidElementValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in PropertyTextureMeshPrimitivePropertyTexturesInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTexturesInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in PropertyTextureMeshPrimitivePropertyTexturesInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTexturesInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in PropertyTextureMeshPrimitivePropertyTextureTexCoordInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTextureMeshPrimitivePropertyTextureTexCoordInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in PropertyTexturePropertyChannelsSizeMismatch", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyChannelsSizeMismatch.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TEXTURE_CHANNELS_SIZE_MISMATCH"); }); it("detects issues in PropertyTexturePropertyIndexInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyIndexInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in PropertyTexturePropertyIndexInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyIndexInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects no issues in PropertyTexturePropertyTexCoordDefault", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexCoordDefault.gltf" ); expect(result.length).toEqual(0); }); it("detects issues in PropertyTexturePropertyTexCoordInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexCoordInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in PropertyTexturePropertyTexturePropertyMaxMismatch", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexturePropertyMaxMismatch.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects issues in PropertyTexturePropertyTexturePropertyMaxNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexturePropertyMaxNotInRange.gltf" ); expect(result.length).toEqual(7); for (let i = 0; i < result.length; i++) { expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); } }); it("detects issues in PropertyTexturePropertyTexturePropertyMinMismatch", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexturePropertyMinMismatch.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects issues in PropertyTexturePropertyTexturePropertyMinNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/PropertyTexturePropertyTexturePropertyMinNotInRange.gltf" ); expect(result.length).toEqual(10); for (let i = 0; i < result.length; i++) { expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); } }); it("detects issues in StructuralMetadataMissingSchema", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/StructuralMetadataMissingSchema.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ANY_OF_ERROR"); }); it("detects issues in StructuralMetadataSchemaAndSchemaUri", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/StructuralMetadataSchemaAndSchemaUri.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ONE_OF_ERROR"); }); it("detects no issues in ValidMultipleClasses", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/ValidMultipleClasses.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidPropertyAttributes", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/ValidPropertyAttributes.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidPropertyTexture", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/ValidPropertyTexture.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidPropertyTextureEnums", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/structuralMetadata/ValidPropertyTextureEnums.gltf" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/gltfExtensions/ExtValidationSpec.ts ================================================ import { validateGltf } from "./validateGltf"; describe("combined EXT_structural_metadata and EXT_mesh_features extension validation", function () { it("detects issues in FeatureIdAttributeAndPropertyTableFeatureIdNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/FeatureIdAttributeAndPropertyTableFeatureIdNotInRange.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in FeatureIdAttributeAndPropertyTableWithValueNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/FeatureIdAttributeAndPropertyTableWithValueNotInRange.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects issues in FeatureIdAttributePropertyTableInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/FeatureIdAttributePropertyTableInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in FeatureIdAttributePropertyTableWithoutPropertyTables", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/FeatureIdAttributePropertyTableWithoutPropertyTables.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects issues in FeatureIdAttributePropertyTableWithoutStructuralMetadata", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/FeatureIdAttributePropertyTableWithoutStructuralMetadata.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects issues in FeatureIdTextureAndPropertyTableFeatureIdNotInRange", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/FeatureIdTextureAndPropertyTableFeatureIdNotInRange.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects no issues in ValidFeatureIdAttributeAndPropertyTable", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/ValidFeatureIdAttributeAndPropertyTable.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidFeatureIdTextureAndPropertyTable", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/ValidFeatureIdTextureAndPropertyTable.gltf" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/gltfExtensions/KhrLightsPunctualValidationSpec.ts ================================================ import { Validators } from "../../src/validation/Validators"; describe("KHR_lights_punctual extension validation", function () { it("detects no issues in validTilesetWithKhrLightsPunctual when no temporal traits are used", async function () { const result = await Validators.validateTilesetFile( "specs/data/gltfExtensions/khrLightsPunctual/validTilesetWithKhrLightsPunctual.json" ); // Should only have info messages, no errors since we only validate temporal traits expect(result.length).toEqual(0); }); it("detects issues in validTilesetWithInvalidKhrLightsPunctual", async function () { const result = await Validators.validateTilesetFile( "specs/data/gltfExtensions/khrLightsPunctual/validTilesetWithInvalidKhrLightsPunctual.json" ); // Expect one error from the glTF Validator that complains about // the MAXAR_temporal_light_traits extension being used within // one light, but not being declared in extensionsUsed. expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("CONTENT_VALIDATION_ERROR"); }); }); ================================================ FILE: specs/gltfExtensions/MaxarImageOrthoValidationSpec.ts ================================================ import { validateGltf } from "./validateGltf"; describe("MAXAR_image_ortho extension validation", function () { it("detects no issues in validMaxarImageOrtho", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarImageOrtho/validMaxarImageOrtho.gltf" ); // Should only have info messages, no errors expect(result.length).toEqual(0); }); it("detects missing srs property", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarImageOrtho/invalidMissingSrs.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects invalid transform array length", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarImageOrtho/invalidTransformLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects invalid coordinate system", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarImageOrtho/invalidCoordinateSystem.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_VALUE_INVALID"); }); }); ================================================ FILE: specs/gltfExtensions/MaxarNonvisualGeometryValidationSpec.ts ================================================ import { validateGltf } from "./validateGltf"; describe("MAXAR_nonvisual_geometry extension validation", function () { it("detects issues in NodeExtensionMeshMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/NodeExtensionMeshMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in NodeExtensionMeshInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/NodeExtensionMeshInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in NodeExtensionMeshInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/NodeExtensionMeshInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in NodeExtensionMeshNotFound", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/NodeExtensionMeshNotFound.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in PrimitiveExtensionShapeMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionShapeMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in PrimitiveExtensionShapeInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionShapeInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in PrimitiveExtensionShapeInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionShapeInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in PrimitiveExtensionTypeMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionTypeMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in PrimitiveExtensionTypeInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionTypeInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in PrimitiveExtensionTypeEmpty", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/PrimitiveExtensionTypeEmpty.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("STRING_LENGTH_MISMATCH"); }); it("detects issues in ShapePointsIncompatibleMode", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ShapePointsIncompatibleMode.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects issues in ShapePathIncompatibleMode", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ShapePathIncompatibleMode.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects issues in ShapeSurfaceIncompatibleMode", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ShapeSurfaceIncompatibleMode.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects issues in ShapeVolumeIncompatibleMode", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ShapeVolumeIncompatibleMode.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("validates ValidNodeExtension", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ValidNodeExtension.gltf" ); expect(result.length).toEqual(0); }); it("validates ValidPrimitiveExtensionPoints", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ValidPrimitiveExtensionPoints.gltf" ); expect(result.length).toEqual(0); }); it("validates ValidPrimitiveExtensionPath", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ValidPrimitiveExtensionPath.gltf" ); expect(result.length).toEqual(0); }); it("validates ValidPrimitiveExtensionSurface", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ValidPrimitiveExtensionSurface.gltf" ); expect(result.length).toEqual(0); }); it("validates ValidPrimitiveExtensionVolume", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ValidPrimitiveExtensionVolume.gltf" ); expect(result.length).toEqual(0); }); it("validates ValidComplexExample", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/maxarNonvisualGeometry/ValidComplexExample.gltf" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/gltfExtensions/MaxarTemporalLightTraits/MaxarTemporalLightTraitsValidationSpec.ts ================================================ import { validateGltf } from "../validateGltf"; describe("MAXAR_temporal_light_traits extension validation", function () { it("detects no issues in validTemporalLightTraits", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/validTemporalLightTraits.gltf" ); expect(result.length).toEqual(0); }); it("detects missing waveform property in temporal light traits", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidMissingWaveform.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects invalid waveform value in temporal light traits", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidWaveform.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects undeclared MAXAR_temporal_light_traits extension", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidUndeclaredExtension.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects invalid duty property with sine waveform", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidDutyWithSineWaveform.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects invalid duty property with triangle waveform", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/invalidDutyWithTriangleWaveform.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("INVALID_GLTF_STRUCTURE"); }); it("detects no issues with valid duty property and square waveform", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/khrLightsPunctual/maxarTemporalLightTraits/validDutyWithSquareWaveform.gltf" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/gltfExtensions/NgaGpmLocalValidationSpec.ts ================================================ import { validateGltf } from "./validateGltf"; describe("NGA_gpm_local extension validation", function () { it("detects issues in anchorPointDirectAdjustmentParamsInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointDirectAdjustmentParamsInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in anchorPointDirectAdjustmentParamsInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointDirectAdjustmentParamsInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in anchorPointDirectAdjustmentParamsInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointDirectAdjustmentParamsInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in anchorPointDirectAdjustmentParamsMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointDirectAdjustmentParamsMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in anchorPointDirectPositionInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointDirectPositionInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in anchorPointDirectPositionInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointDirectPositionInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in anchorPointDirectPositionMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointDirectPositionMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in anchorPointIndirectAdjustmentParamsInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectAdjustmentParamsInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in anchorPointIndirectAdjustmentParamsInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectAdjustmentParamsInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in anchorPointIndirectAdjustmentParamsInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectAdjustmentParamsInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in anchorPointIndirectAdjustmentParamsMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectAdjustmentParamsMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in anchorPointIndirectCovarianceInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectCovarianceInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in anchorPointIndirectCovarianceMatrixInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectCovarianceMatrixInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in anchorPointIndirectCovarianceMatrixInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectCovarianceMatrixInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in anchorPointIndirectCovarianceMatrixMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectCovarianceMatrixMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in anchorPointIndirectPositionInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectPositionInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in anchorPointIndirectPositionInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectPositionInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in anchorPointIndirectPositionInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectPositionInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in anchorPointIndirectPositionMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointIndirectPositionMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in anchorPointsDirectInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointsDirectInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in anchorPointsDirectInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointsDirectInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in anchorPointsDirectInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointsDirectInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in anchorPointsIndirectInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointsIndirectInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in anchorPointsIndirectInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointsIndirectInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in anchorPointsIndirectInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/anchorPointsIndirectInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in correlationGroupGroupFlagsElementInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupGroupFlagsElementInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in correlationGroupGroupFlagsInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupGroupFlagsInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in correlationGroupGroupFlagsInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupGroupFlagsInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in correlationGroupGroupFlagsMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupGroupFlagsMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in correlationGroupParamsInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupParamsInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in correlationGroupParamsInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupParamsInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in correlationGroupParamsInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupParamsInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in correlationGroupParamsMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupParamsMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in correlationGroupRotationThetasInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupRotationThetasInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in correlationGroupRotationThetasInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupRotationThetasInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in correlationGroupRotationThetasInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupRotationThetasInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in correlationGroupRotationThetasMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/correlationGroupRotationThetasMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in covarianceDirectUpperTriangleInconsistentLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/covarianceDirectUpperTriangleInconsistentLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_INCONSISTENT"); }); it("detects issues in covarianceDirectUpperTriangleInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/covarianceDirectUpperTriangleInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in covarianceDirectUpperTriangleElementInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/covarianceDirectUpperTriangleElementInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in directAnchorPointsDirectMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/directAnchorPointsDirectMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in directCovarianceDirectUpperTriangleMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/directCovarianceDirectUpperTriangleMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in directWithAnchorPointsIndirect", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/directWithAnchorPointsIndirect.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in directWithIntraTileCorrelationGroups", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/directWithIntraTileCorrelationGroups.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in indirectAnchorPointsIndirectMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/indirectAnchorPointsIndirectMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in indirectIntraTileCorrelationGroupsMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/indirectIntraTileCorrelationGroupsMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in indirectWithAnchorPointsDirect", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/indirectWithAnchorPointsDirect.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in indirectWithCovarianceDirectUpperTriangle", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/indirectWithCovarianceDirectUpperTriangle.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("DISALLOWED_VALUE_FOUND"); }); it("detects issues in intraTileCorrelationGroupsInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/intraTileCorrelationGroupsInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in intraTileCorrelationGroupsInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/intraTileCorrelationGroupsInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in intraTileCorrelationGroupsInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/intraTileCorrelationGroupsInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeMetadataMaxInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeMetadataMaxInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeMetadataMinInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeMetadataMinInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeMetadataSourceInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeMetadataSourceInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in ppeMetadataSourceInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeMetadataSourceInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in ppeTextureIndexInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureIndexInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeTextureIndexInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureIndexInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeTextureNoDataInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureNoDataInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeTextureNoDataInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureNoDataInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeTextureOffsetInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureOffsetInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeTextureScaleInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureScaleInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeTexturesInvalidElementType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTexturesInvalidElementType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_ELEMENT_TYPE_MISMATCH"); }); it("detects issues in ppeTexturesInvalidLength", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTexturesInvalidLength.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("ARRAY_LENGTH_MISMATCH"); }); it("detects issues in ppeTexturesInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTexturesInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeTextureTexCoordInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureTexCoordInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeTextureTexCoordInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureTexCoordInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in ppeTextureTraitsInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureTraitsInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in ppeTextureTraitsMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ppeTextureTraitsMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in spdcfAInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfAInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in spdcfAInvalidValueA", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfAInvalidValueA.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfAInvalidValueB", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfAInvalidValueB.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfAlphaInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfAlphaInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in spdcfAlphaInvalidValueA", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfAlphaInvalidValueA.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfAlphaInvalidValueB", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfAlphaInvalidValueB.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfAlphaMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfAlphaMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in spdcfAMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfAMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in spdcfBetaInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfBetaInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in spdcfBetaInvalidValueA", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfBetaInvalidValueA.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfBetaInvalidValueB", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfBetaInvalidValueB.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfBetaMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfBetaMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in spdcfTInvalidType", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfTInvalidType.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in spdcfTInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfTInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in spdcfTMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/spdcfTMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in storageTypeInvalidValue", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/storageTypeInvalidValue.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in storageTypeMissing", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/storageTypeMissing.gltf" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects no issues in ValidGltfGpmLocal", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ValidGltfGpmLocal.gltf" ); expect(result.length).toEqual(0); }); it("detects no issues in ValidMeshPrimitiveGpmLocal", async function () { const result = await validateGltf( "./specs/data/gltfExtensions/gpmLocal/ValidMeshPrimitiveGpmLocal.gltf" ); expect(result.length).toEqual(0); }); }); ================================================ FILE: specs/gltfExtensions/validateGltf.ts ================================================ import fs from "fs"; import path from "path"; import { ResourceResolvers } from "3d-tiles-tools"; import { ValidationContext } from "../../src/validation/ValidationContext"; import { GltfExtensionValidators } from "../../src/validation/gltf/GltfExtensionValidators"; export async function validateGltf(gltfFileName: string) { fs.readFileSync(gltfFileName); const directory = path.dirname(gltfFileName); const fileName = path.basename(gltfFileName); const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); const context = new ValidationContext(directory, resourceResolver); const gltfFileData = await resourceResolver.resolveData(fileName); if (gltfFileData) { await GltfExtensionValidators.validateGltfExtensions( gltfFileName, gltfFileData, context ); } const validationResult = context.getResult(); return validationResult; } ================================================ FILE: specs/jasmine.json ================================================ { "spec_dir": "specs", "spec_files": ["**/*Spec.*s"], "helpers": [], "random": false } ================================================ FILE: specs/metadata/BinaryPropertyTableValidationSpec.ts ================================================ import { ResourceResolvers } from "3d-tiles-tools"; import { ValidationContext } from "../../src/validation/ValidationContext"; import { BinaryPropertyTableValidator } from "../../src/validation/metadata/BinaryPropertyTableValidator"; import { PropertyTableTestUtilities } from "./PropertyTableTestUtilities"; // A flag to enable printing all `ValidationResult` // instances to the console during the tests. const debugLogResults = false; describe("metadata/BinaryPropertyTableValidationSpec", function () { //========================================================================== //=== example_INT16_SCALAR test cases: // - no issues for valid input // - `values` not properly aligned due to wrong `byteOffset` // - `values` length invalid due to wrong `byteLength` describe("issues for example_INT16_SCALAR", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects unaligned values byteOffset for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: Assign a value to values // byteOffset to cause an invalid alignment const valuesBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"].values; const binaryMetadata = binaryPropertyTable.binaryMetadata; binaryMetadata.binaryBufferStructure!.bufferViews![ valuesBufferViewIndex ].byteOffset = 1; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_ALIGNMENT"); }); it("detects invalid values byteLength for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: Assign a value to values // byteLength to cause an invalid size const valuesBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"].values; const binaryMetadata = binaryPropertyTable.binaryMetadata; binaryMetadata.binaryBufferStructure!.bufferViews![ valuesBufferViewIndex ].byteLength = 12345; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_LENGTH"); }); }); //========================================================================== //=== example_variable_length_INT16_SCALAR_array test cases: // - no issues for valid input // - `arrayOffsets` not properly aligned due to wrong `byteOffset` // - `arrayOffsets` length invalid due to wrong `byteLength` // - `arrayOffsets` contains descending values // - `arrayOffsets` contains values that are out of range for the `values` describe("issues for example_variable_length_INT16_SCALAR_array", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_variable_length_INT16_SCALAR_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_INT16_SCALAR_array(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects unaligned arrayOffsets byteOffset for example_variable_length_INT16_SCALAR_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_INT16_SCALAR_array(); // For the test: Assign a value to arrayOffsets // byteOffset to cause an invalid alignment const arrayOffsetsBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"] .arrayOffsets!; const binaryMetadata = binaryPropertyTable.binaryMetadata; binaryMetadata.binaryBufferStructure!.bufferViews![ arrayOffsetsBufferViewIndex ].byteOffset = 5; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_ALIGNMENT"); }); it("detects wrong arrayOffsets byteLength for example_variable_length_INT16_SCALAR_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_INT16_SCALAR_array(); // For the test: Assign a value to arrayOffsets // byteLength to cause an invalid length const arrayOffsetsBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"] .arrayOffsets!; const binaryMetadata = binaryPropertyTable.binaryMetadata; binaryMetadata.binaryBufferStructure!.bufferViews![ arrayOffsetsBufferViewIndex ].byteLength = 12345; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_LENGTH"); }); it("detects descending arrayOffsets for example_variable_length_INT16_SCALAR_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_INT16_SCALAR_array(); // For the test: Write a value into the arrayOffsets // buffer, to make it descending const arrayOffsetsBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"] .arrayOffsets!; const binaryMetadata = binaryPropertyTable.binaryMetadata; const arrayOffsetsBufferViewData = binaryMetadata.binaryBufferData!.bufferViewsData![ arrayOffsetsBufferViewIndex ]; arrayOffsetsBufferViewData.writeInt32LE(12345, 4); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_OFFSETS"); }); it("detects arrayOffsets that are out of range for example_variable_length_INT16_SCALAR_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_INT16_SCALAR_array(); // For the test: Write values into the arrayOffsets // buffer so that the 'values' buffer is not long // enough to match the last array offsets entry const arrayOffsetsBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"] .arrayOffsets!; const binaryMetadata = binaryPropertyTable.binaryMetadata; const arrayOffsetsBufferViewData = binaryMetadata.binaryBufferData!.bufferViewsData![ arrayOffsetsBufferViewIndex ]; arrayOffsetsBufferViewData.writeInt32LE(0, 0); arrayOffsetsBufferViewData.writeInt32LE(123, 4); arrayOffsetsBufferViewData.writeInt32LE(12345, 8); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_LENGTH"); }); }); //========================================================================== //=== example_fixed_length_INT16_SCALAR_array test cases: // - no issues for valid input // - `values` length does not match in view of the `classProperty.count` describe("issues for example_fixed_length_INT16_SCALAR_array", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_fixed_length_INT16_SCALAR_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_INT16_SCALAR_array(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects invalid values byteLength for example_fixed_length_INT16_SCALAR_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_INT16_SCALAR_array(); // For the test: Assign a value to the 'count' of // the property, so that the length of the 'values' // buffer view does no longer match const binaryMetadata = binaryPropertyTable.binaryMetadata; binaryMetadata.metadataClass.properties!["testProperty"].count = 12345; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_LENGTH"); }); }); //========================================================================== //=== example_BOOLEAN test cases: // - no issues for valid input // - `values` length does not match for `propertyTable.count` describe("issues for example_BOOLEAN", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_BOOLEAN", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_BOOLEAN(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("should not report issues for valid values byteLength for example_BOOLEAN", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_BOOLEAN(); // For the test: Assign a value to the 'count' of // the property table that JUST SO fits into one // byte (this should NOT cause an issue!) binaryPropertyTable.propertyTable.count = 8; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects invalid values byteLength for example_BOOLEAN", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_BOOLEAN(); // For the test: Assign a value to the 'count' of // the property table, so that the length of the 'values' // buffer view does no longer match binaryPropertyTable.propertyTable.count = 9; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_LENGTH"); }); }); //========================================================================== //=== example_variable_length_BOOLEAN_array test cases: // - no issues for valid input // - `values` length does not match for given `arrayOffsets` describe("issues for example_variable_length_BOOLEAN_array", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_variable_length_BOOLEAN_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_BOOLEAN_array(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects invalid values byteLength for example_variable_length_BOOLEAN_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_BOOLEAN_array(); // For the test: Write values into the arrayOffsets // buffer so that the 'values' buffer is not long // enough to match the last array offsets entry const arrayOffsetsBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"] .arrayOffsets!; const binaryMetadata = binaryPropertyTable.binaryMetadata; const arrayOffsetsBufferViewData = binaryMetadata.binaryBufferData!.bufferViewsData![ arrayOffsetsBufferViewIndex ]; arrayOffsetsBufferViewData.writeInt32LE(0, 0); arrayOffsetsBufferViewData.writeInt32LE(123, 4); arrayOffsetsBufferViewData.writeInt32LE(12345, 8); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_LENGTH"); }); }); //========================================================================== //=== example_fixed_length_BOOLEAN_array test cases: // - no issues for valid input // - `values` length does not match for given `arrayOffsets` describe("issues for example_fixed_length_BOOLEAN_array", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_fixed_length_BOOLEAN_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_BOOLEAN_array(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects invalid values byteLength for example_fixed_length_BOOLEAN_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_BOOLEAN_array(); // For the test: Assign a value to the 'count' of // the property, so that the length of the 'values' // buffer view does no longer match const binaryMetadata = binaryPropertyTable.binaryMetadata; binaryMetadata.metadataClass.properties!["testProperty"].count = 12345; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_LENGTH"); }); }); //========================================================================== //=== example_STRING test cases // - no issues for valid input // - `stringOffsets` not properly aligned due to wrong `byteOffset` // - `stringOffsets` length invalid due to wrong `byteLength` // - `stringOffsets` contains descending values // - `stringOffsets` contains values that are out of range for the `values` describe("issues for example_STRING", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_STRING", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_STRING(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects unaligned stringOffsets byteOffset for example_STRING", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_STRING(); // For the test: Assign a value to stringOffsets // byteOffset to cause an invalid alignment const stringOffsetsBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"] .stringOffsets!; const binaryMetadata = binaryPropertyTable.binaryMetadata; binaryMetadata.binaryBufferStructure!.bufferViews![ stringOffsetsBufferViewIndex ].byteOffset = 5; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_ALIGNMENT"); }); it("detects wrong stringOffsets byteLength for example_STRING", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_STRING(); // For the test: Assign a value to stringOffsets // byteLength to cause an invalid length const stringOffsetsBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"] .stringOffsets!; const binaryMetadata = binaryPropertyTable.binaryMetadata; binaryMetadata.binaryBufferStructure!.bufferViews![ stringOffsetsBufferViewIndex ].byteLength = 12345; BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_LENGTH"); }); it("detects descending stringOffsets for example_STRING", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_STRING(); // For the test: Write a value into the stringOffsets // buffer, to make it descending const stringOffsetsBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"] .stringOffsets!; const binaryMetadata = binaryPropertyTable.binaryMetadata; const stringOffsetsBufferViewData = binaryMetadata.binaryBufferData!.bufferViewsData![ stringOffsetsBufferViewIndex ]; stringOffsetsBufferViewData.writeInt32LE(12345, 4); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_OFFSETS"); }); it("detects stringOffsets that are out of range for example_STRING", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_STRING(); // For the test: Write values into the stringOffsets // buffer so that the 'values' buffer is not long // enough to match the last string offsets entry const stringOffsetsBufferViewIndex = binaryPropertyTable.propertyTable.properties!["testProperty"] .stringOffsets!; const binaryMetadata = binaryPropertyTable.binaryMetadata; const stringOffsetsBufferViewData = binaryMetadata.binaryBufferData!.bufferViewsData![ stringOffsetsBufferViewIndex ]; stringOffsetsBufferViewData.writeInt32LE(0, 0); stringOffsetsBufferViewData.writeInt32LE(123, 4); stringOffsetsBufferViewData.writeInt32LE(12345, 8); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_INVALID_LENGTH"); }); }); //========================================================================== //=== example_variable_length_STRING_array test cases // - no issues for valid input // (arrayOffsets issues are already covered with example_variable_length_INT16_SCALAR_array) // (stringOffsets issues are already covered with example_STRING) describe("issues for example_variable_length_STRING_array", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_variable_length_STRING_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_STRING_array(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); }); //========================================================================== //=== example_fixed_length_STRING_array test cases // - no issues for valid input // (stringOffsets issues are already covered with example_STRING) describe("issues for example_fixed_length_STRING_array", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_fixed_length_STRING_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_STRING_array(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); }); //========================================================================== //=== example_FLOAT32_VEC2 test cases // - no issues for valid input describe("issues for example_FLOAT32_VEC2", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_FLOAT32_VEC2", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_FLOAT32_VEC2(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); }); //========================================================================== //=== example_variable_length_UINT32_VEC2_array test cases // - no issues for valid input // (arrayOffsets issues are already covered with example_variable_length_INT16_SCALAR_array) describe("issues for example_variable_length_UINT32_VEC2_array", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_variable_length_UINT32_VEC2_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_UINT32_VEC2_array(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); }); //========================================================================== //=== example_fixed_length_UINT32_VEC2_array test cases // - no issues for valid input // (arrayOffsets issues are already covered with example_fixed_length_INT16_SCALAR_array) describe("issues for example_fixed_length_UINT32_VEC2_array", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for a valid example_fixed_length_UINT32_VEC2_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_UINT32_VEC2_array(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); }); }); ================================================ FILE: specs/metadata/BinaryPropertyTableValuesValidationSpec.ts ================================================ import { ResourceResolvers } from "3d-tiles-tools"; import { ValidationContext } from "../../src/validation/ValidationContext"; import { BinaryPropertyTableValidator } from "../../src/validation/metadata/BinaryPropertyTableValidator"; import { PropertyTableTestUtilities } from "./PropertyTableTestUtilities"; import { BinaryPropertyTable } from "3d-tiles-tools"; // A flag to enable printing all `ValidationResult` // instances to the console during the tests. const debugLogResults = false; // A function for preparing a property table with the // example_INT16_SCALAR for the tests, by filling it // with the values 10 and 12 function prepareTest_example_INT16_SCALAR( binaryPropertyTable: BinaryPropertyTable ) { const propertyTableProperty = binaryPropertyTable.propertyTable.properties!["testProperty"]; const valuesBufferViewIndex = propertyTableProperty.values; const binaryMetadata = binaryPropertyTable.binaryMetadata; const valuesBufferViewData = binaryMetadata.binaryBufferData!.bufferViewsData![valuesBufferViewIndex]; valuesBufferViewData.writeInt16LE(10, 0); valuesBufferViewData.writeInt16LE(12, 2); } // A function to set the offset/scale of the class property for the tests function setClassPropertyOffsetScale( binaryPropertyTable: BinaryPropertyTable, offset: any, scale: any ) { const binaryMetadata = binaryPropertyTable.binaryMetadata; const classProperty = binaryMetadata.metadataClass.properties!["testProperty"]; classProperty.offset = offset; classProperty.scale = scale; } // A function to set the offset/scale of the property table property for the tests function setPropertyTablePropertyOffsetScale( binaryPropertyTable: BinaryPropertyTable, offset: any, scale: any ) { const propertyTableProperty = binaryPropertyTable.propertyTable.properties!["testProperty"]; propertyTableProperty.offset = offset; propertyTableProperty.scale = scale; } // A function to set the min/max of the class property for the tests function setClassPropertyMinMax( binaryPropertyTable: BinaryPropertyTable, min: any, max: any ) { const binaryMetadata = binaryPropertyTable.binaryMetadata; const classProperty = binaryMetadata.metadataClass.properties!["testProperty"]; classProperty.min = min; classProperty.max = max; } // A function to set the min/max of the property table property for the tests function setPropertyTablePropertyMinMax( binaryPropertyTable: BinaryPropertyTable, min: any, max: any ) { const propertyTableProperty = binaryPropertyTable.propertyTable.properties!["testProperty"]; propertyTableProperty.min = min; propertyTableProperty.max = max; } describe("metadata/BinaryPropertyTableValuesValidationSpec", function () { //========================================================================== //=== example_ENUM_with_noData test cases: // - no issues for valid input // - no issues for values that are the 'noData' value describe("issues for example_ENUM_with_noData", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for values that are valid for example_ENUM with a noData value", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_ENUM_with_noData(); // For the test: // Write a value into the 'values' buffer that // matches the 'noData' value of the example const propertyTableProperty = binaryPropertyTable.propertyTable.properties!["testProperty"]; const valuesBufferViewIndex = propertyTableProperty.values; const binaryMetadata = binaryPropertyTable.binaryMetadata; const valuesBufferViewData = binaryMetadata.binaryBufferData!.bufferViewsData![ valuesBufferViewIndex ]; valuesBufferViewData.writeUInt16LE(9999, 2); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); }); //========================================================================== //=== example_variable_length_ENUM_array test cases: // - no issues for valid input describe("issues for example_variable_length_ENUM_array", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for values that are valid for example_variable_length_ENUM_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_ENUM_array(); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects values that are not valid enum values for example_variable_length_ENUM_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_variable_length_ENUM_array(); // For the test: // Write a value into the 'values' buffer that // does not represent a valid enum value const propertyTableProperty = binaryPropertyTable.propertyTable.properties!["testProperty"]; const valuesBufferViewIndex = propertyTableProperty.values; const binaryMetadata = binaryPropertyTable.binaryMetadata; const valuesBufferViewData = binaryMetadata.binaryBufferData!.bufferViewsData![ valuesBufferViewIndex ]; valuesBufferViewData.writeUInt16LE(12345, 2); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); }); //========================================================================== //=== example_INT16_SCALAR test cases: // - no issues for valid input // - values out of range for 'min' and 'max' in classProperty // and in propertyTableProperty // - computed values do not match the 'min' or 'max' // of the propertyTableProperty // // // // // //=== example_INT16_SCALAR test cases without offset or scale: // // // // // describe("issues for example_INT16_SCALAR (without offset or scale)", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for values that are valid for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property min/max to 10/12 // - Set the property table property min/max to 10/12 // This should NOT cause any issues! prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyMinMax(binaryPropertyTable, 10, 12); setPropertyTablePropertyMinMax(binaryPropertyTable, 10, 12); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects values smaller than the class property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property minimum to 11 // This should cause an issue for 10 being smaller than 11 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyMinMax(binaryPropertyTable, 11, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values greater than the class property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set class property maximum to 11 // This should cause an issue for 12 being greater than 11 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyMinMax(binaryPropertyTable, undefined, 11); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values smaller than the property table property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property minimum to 11 // This should cause an issue for 10 being smaller than 11 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyMinMax(binaryPropertyTable, 11, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values greater than the property table property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property maximum to 11 // This should cause an issue for 12 being greater than 11 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 11); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects when the property table property minimum does not match the computed minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property minimum to 9 // This should cause an issue for the computed minimum // of 10 not matching the property table property minimum of 9 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyMinMax(binaryPropertyTable, 9, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects when the property table property maximum does not match the computed maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property minimum to 13 // This should cause an issue for the computed maximum // of 12 not matching the property table property maximum of 13 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 13); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); }); // // // // // //=== example_INT16_SCALAR test cases with offset in class property: // // // // // describe("issues for example_INT16_SCALAR with offset in class property", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for values with offset in class property that are valid for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the class property min/max to 110/112 // - Set the property table property min/max to 110/112 // This should NOT cause any issues! prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setClassPropertyMinMax(binaryPropertyTable, 110, 112); setPropertyTablePropertyMinMax(binaryPropertyTable, 110, 112); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects values with offset in class property smaller than the class property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the class property minimum to 111 // This should cause an issue for 110 being smaller than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setClassPropertyMinMax(binaryPropertyTable, 111, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with offset in class property greater than the class property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set class property maximum to 111 // This should cause an issue for 112 being greater than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setClassPropertyMinMax(binaryPropertyTable, undefined, 111); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with offset in class property smaller than the property table property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the property table property minimum to 111 // This should cause an issue for 110 being smaller than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, 111, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with offset in class property greater than the property table property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the property table property maximum to 111 // This should cause an issue for 112 being greater than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 111); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects when the property table property minimum does not match the computed minimum with offset in class property for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the property table property minimum to 109 // This should cause an issue for the computed minimum // of 10 not matching the property table property minimum of 109 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, 109, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects when the property table property maximum does not match the computed maximum with offset in class property for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the property table property minimum to 113 // This should cause an issue for the computed maximum // of 112 not matching the property table property maximum of 113 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 113); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); }); // // // // // //=== example_INT16_SCALAR test cases with offset in property table property: // // // // // describe("issues for example_INT16_SCALAR with offset in property table property", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for values with offset in property table property that are valid for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property offset to 100 // - Set the class property min/max to 110/112 // - Set the property table property min/max to 110/112 // This should NOT cause any issues! prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, 100, undefined); setClassPropertyMinMax(binaryPropertyTable, 110, 112); setPropertyTablePropertyMinMax(binaryPropertyTable, 110, 112); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects values with offset in property table property smaller than the class property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property offset to 100 // - Set the class property minimum to 111 // This should cause an issue for 110 being smaller than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, 100, undefined); setClassPropertyMinMax(binaryPropertyTable, 111, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with offset in property table property greater than the class property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property offset to 100 // - Set class property maximum to 111 // This should cause an issue for 112 being greater than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, 100, undefined); setClassPropertyMinMax(binaryPropertyTable, undefined, 111); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with offset in property table property smaller than the property table property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property offset to 100 // - Set the property table property minimum to 111 // This should cause an issue for 110 being smaller than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, 111, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with offset in property table property greater than the property table property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property offset to 100 // - Set the property table property maximum to 111 // This should cause an issue for 112 being greater than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 111); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects when the property table property minimum does not match the computed minimum with offset in property table property for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property offset to 100 // - Set the property table property minimum to 109 // This should cause an issue for the computed minimum // of 10 not matching the property table property minimum of 109 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, 109, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects when the property table property maximum does not match the computed maximum with offset in property table property for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property offset to 100 // - Set the property table property minimum to 113 // This should cause an issue for the computed maximum // of 112 not matching the property table property maximum of 113 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 113); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); }); // // // // // //=== example_INT16_SCALAR test cases with offset in class property: // // // // // describe("issues for example_INT16_SCALAR with offset in class property", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for values with offset in class property that are valid for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the class property min/max to 110/112 // - Set the property table property min/max to 110/112 // This should NOT cause any issues! prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setClassPropertyMinMax(binaryPropertyTable, 110, 112); setPropertyTablePropertyMinMax(binaryPropertyTable, 110, 112); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects values with offset in class property smaller than the class property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the class property minimum to 111 // This should cause an issue for 110 being smaller than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setClassPropertyMinMax(binaryPropertyTable, 111, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with offset in class property greater than the class property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set class property maximum to 111 // This should cause an issue for 112 being greater than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setClassPropertyMinMax(binaryPropertyTable, undefined, 111); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with offset in class property smaller than the property table property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the property table property minimum to 111 // This should cause an issue for 110 being smaller than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, 111, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with offset in class property greater than the property table property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the property table property maximum to 111 // This should cause an issue for 112 being greater than 111 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 111); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects when the property table property minimum does not match the computed minimum with offset in class property for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the property table property minimum to 109 // This should cause an issue for the computed minimum // of 10 not matching the property table property minimum of 109 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, 109, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects when the property table property maximum does not match the computed maximum with offset in class property for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the class property offset to 100 // - Set the property table property minimum to 113 // This should cause an issue for the computed maximum // of 112 not matching the property table property maximum of 113 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setClassPropertyOffsetScale(binaryPropertyTable, 100, undefined); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 113); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); }); // // // // // //=== example_INT16_SCALAR test cases with scale in property table property: // // // // // describe("issues for example_INT16_SCALAR with scale in property table property", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for values with scale in property table property that are valid for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property scale to 10 // - Set the class property min/max to 100/120 // - Set the property table property min/max to 100/120 // This should NOT cause any issues! prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, undefined, 10); setClassPropertyMinMax(binaryPropertyTable, 100, 120); setPropertyTablePropertyMinMax(binaryPropertyTable, 100, 120); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects values with scale in property table property smaller than the class property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property scale to 10 // - Set the class property minimum to 101 // This should cause an issue for 100 being smaller than 101 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, undefined, 10); setClassPropertyMinMax(binaryPropertyTable, 101, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with scale in property table property greater than the class property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property scale to 10 // - Set class property maximum to 119 // This should cause an issue for 120 being greater than 119 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, undefined, 10); setClassPropertyMinMax(binaryPropertyTable, undefined, 119); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with scale in property table property smaller than the property table property minimum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property scale to 10 // - Set the property table property minimum to 101 // This should cause an issue for 100 being smaller than 101 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, undefined, 10); setPropertyTablePropertyMinMax(binaryPropertyTable, 101, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values with scale in property table property greater than the property table property maximum for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property scale to 10 // - Set the property table property maximum to 119 // This should cause an issue for 120 being greater than 119 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, undefined, 10); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 119); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects when the property table property minimum does not match the computed minimum with scale in property table property for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property scale to 10 // - Set the property table property minimum to 99 // This should cause an issue for the computed minimum // of 100 not matching the property table property minimum of 99 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, undefined, 10); setPropertyTablePropertyMinMax(binaryPropertyTable, 99, undefined); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects when the property table property maximum does not match the computed maximum with scale in property table property for example_INT16_SCALAR", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_INT16_SCALAR(); // For the test: // - Fill the property with the values 10 and 12 // - Set the property table property scale to 10 // - Set the property table property minimum to 121 // This should cause an issue for the computed maximum // of 120 not matching the property table property maximum of 121 prepareTest_example_INT16_SCALAR(binaryPropertyTable); setPropertyTablePropertyOffsetScale(binaryPropertyTable, undefined, 10); setPropertyTablePropertyMinMax(binaryPropertyTable, undefined, 121); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); }); //========================================================================== //=== example_fixed_length_normalized_INT64_VEC2_array test cases: // - no issues for valid input // - values out of range for 'min' and 'max' in classProperty // and in propertyTableProperty // - computed values do not match the 'min' or 'max' // of the propertyTableProperty // // // // // //=== example_fixed_length_normalized_INT64_VEC2_array test cases without offset or scale: // // // // // describe("issues for example_fixed_length_normalized_INT64_VEC2_array (without offset or scale)", function () { let context: ValidationContext; beforeEach(function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("should not report issues for values that are valid for example_fixed_length_normalized_INT64_VEC2_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_normalized_INT64_VEC2_array(); // For the test: // - Set the class property min/max to the actual min/max // - Set the property table property min/max to the actual min/max // This should NOT cause any issues! setClassPropertyMinMax( binaryPropertyTable, [ [0, 0], [-1, 0], [0, -1], ], [ [0, 0], [1, 0], [0, 1], ] ); setPropertyTablePropertyMinMax( binaryPropertyTable, [ [0, 0], [-1, 0], [0, -1], ], [ [0, 0], [1, 0], [0, 1], ] ); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(0); }); it("detects values smaller than the class property minimum for example_fixed_length_normalized_INT64_VEC2_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_normalized_INT64_VEC2_array(); // For the test: // - Set the class property minimum to a value where one component // is 0.5, even though the actual minimum component is -1 // This should cause an issue setClassPropertyMinMax( binaryPropertyTable, [ [0, 0], [-0.5, 0], [0, -1], ], [ [0, 0], [1, 0], [0, 1], ] ); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values greater than the class property maximum for example_fixed_length_normalized_INT64_VEC2_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_normalized_INT64_VEC2_array(); // For the test: // - Set the class property maximum to a value where one component // is 0.5, even though the actual maximum component is 1 // This should cause an issue setClassPropertyMinMax( binaryPropertyTable, [ [0, 0], [-1, 0], [0, -1], ], [ [0, 0], [0.5, 0], [0, 1], ] ); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values smaller than the property table property minimum for example_fixed_length_normalized_INT64_VEC2_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_normalized_INT64_VEC2_array(); // For the test: // - Set the property table property minimum to a value where one component // is 0.5, even though the actual minimum component is -1 // This should cause an issue setPropertyTablePropertyMinMax( binaryPropertyTable, [ [0, 0], [-0.5, 0], [0, -1], ], [ [0, 0], [1, 0], [0, 1], ] ); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects values greater than the property table property maximum for example_fixed_length_normalized_INT64_VEC2_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_normalized_INT64_VEC2_array(); // For the test: // - Set the property table property maximum to a value where one component // is 0.5, even though the actual maximum component is 1 // This should cause an issue setPropertyTablePropertyMinMax( binaryPropertyTable, [ [0, 0], [-1, 0], [0, -1], ], [ [0, 0], [0.5, 0], [0, 1], ] ); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE"); }); it("detects when the property table property minimum does not match the computed minimum for example_fixed_length_normalized_INT64_VEC2_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_normalized_INT64_VEC2_array(); // For the test: // - Set the property table property minimum to a value where one component // is -1.5, even though the actual maximum component is 1 // This should cause an issue setPropertyTablePropertyMinMax( binaryPropertyTable, [ [0, 0], [-1.5, 0], [0, -1], ], [ [0, 0], [1, 0], [0, 1], ] ); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); it("detects when the property table property maximum does not match the computed maximum for example_fixed_length_normalized_INT64_VEC2_array", function () { const binaryPropertyTable = PropertyTableTestUtilities.createDefaultBinaryPropertyTable_example_fixed_length_normalized_INT64_VEC2_array(); // For the test: // - Set the property table property maximum to a value where one component // is 1.5, even though the actual maximum component is 1 // This should cause an issue setPropertyTablePropertyMinMax( binaryPropertyTable, [ [0, 0], [-1, 0], [0, -1], ], [ [0, 0], [1.5, 0], [0, 1], ] ); BinaryPropertyTableValidator.validateBinaryPropertyTable( "test", binaryPropertyTable, context ); const result = context.getResult(); if (debugLogResults) { console.log(result.toJson()); } expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_VALUE_MISMATCH"); }); }); }); ================================================ FILE: specs/metadata/PropertyTableTestUtilities.ts ================================================ import { BinaryPropertyTable } from "3d-tiles-tools"; import { BinaryPropertyTables } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { MetadataEnum } from "3d-tiles-tools"; /** * Methods to create `BinaryPropertyTable` instances that are valid, * and contain the data for a single property. * * These methods are used in the `BinaryPropertyTableValidationSpec.ts` * to create valid `BinaryPropertyTable` instances, that are then made * invalid in various ways in order to check whether these errors are * detected asvalidation issues. * * @internal */ export class PropertyTableTestUtilities { /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_INT16_SCALAR(): BinaryPropertyTable { const example_INT16_SCALAR: ClassProperty = { type: "SCALAR", componentType: "INT16", }; const example_INT16_SCALAR_values = [-32768, 32767]; const classProperty = example_INT16_SCALAR; const values = example_INT16_SCALAR_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_variable_length_INT16_SCALAR_array(): BinaryPropertyTable { const example_variable_length_INT16_SCALAR_array: ClassProperty = { type: "SCALAR", componentType: "INT16", array: true, }; const example_variable_length_INT16_SCALAR_array_values = [ [-32768, 32767], [-1, 0, 1], ]; const classProperty = example_variable_length_INT16_SCALAR_array; const values = example_variable_length_INT16_SCALAR_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_fixed_length_INT16_SCALAR_array(): BinaryPropertyTable { const example_fixed_length_INT16_SCALAR_array: ClassProperty = { type: "SCALAR", componentType: "INT16", array: true, count: 2, }; const example_fixed_length_INT16_SCALAR_array_values = [ [-32768, 32767], [-1, 1], ]; const classProperty = example_fixed_length_INT16_SCALAR_array; const values = example_fixed_length_INT16_SCALAR_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_BOOLEAN(): BinaryPropertyTable { const example_BOOLEAN: ClassProperty = { type: "BOOLEAN", }; const example_BOOLEAN_values = [true, false]; const classProperty = example_BOOLEAN; const values = example_BOOLEAN_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_variable_length_BOOLEAN_array(): BinaryPropertyTable { const example_variable_length_BOOLEAN_array: ClassProperty = { type: "BOOLEAN", array: true, }; const example_variable_length_BOOLEAN_array_values = [ [true, false], [false, true, false, true], ]; const classProperty = example_variable_length_BOOLEAN_array; const values = example_variable_length_BOOLEAN_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_fixed_length_BOOLEAN_array(): BinaryPropertyTable { const example_fixed_length_BOOLEAN_array: ClassProperty = { type: "BOOLEAN", array: true, }; const example_fixed_length_BOOLEAN_array_values = [ [true, false, true], [false, true, false], ]; const classProperty = example_fixed_length_BOOLEAN_array; const values = example_fixed_length_BOOLEAN_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_STRING(): BinaryPropertyTable { const example_STRING: ClassProperty = { type: "STRING", }; const example_STRING_values = ["Test string", "Another string"]; const classProperty = example_STRING; const values = example_STRING_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_variable_length_STRING_array(): BinaryPropertyTable { const example_variable_length_STRING_array: ClassProperty = { type: "STRING", array: true, }; const example_variable_length_STRING_array_values = [ ["A0", "A1", "A2"], ["B0", "B1"], ]; const classProperty = example_variable_length_STRING_array; const values = example_variable_length_STRING_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_fixed_length_STRING_array(): BinaryPropertyTable { const example_fixed_length_STRING_array: ClassProperty = { type: "STRING", array: true, count: 3, }; const example_fixed_length_STRING_array_values = [ ["A0", "A1", "A2"], ["B0", "B1", "B2"], ]; const classProperty = example_fixed_length_STRING_array; const values = example_fixed_length_STRING_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_FLOAT32_VEC2(): BinaryPropertyTable { const example_FLOAT32_VEC2: ClassProperty = { type: "VEC2", componentType: "FLOAT32", }; const example_FLOAT32_VEC2_values = [ [0.0, 1.0], [2.0, 3.0], ]; const classProperty = example_FLOAT32_VEC2; const values = example_FLOAT32_VEC2_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_variable_length_UINT32_VEC2_array(): BinaryPropertyTable { const example_variable_length_UINT32_VEC2_array: ClassProperty = { type: "VEC2", componentType: "FLOAT32", array: true, }; const example_variable_length_UINT32_VEC2_array_values = [ [ [0.0, 1.0], [2.0, 3.0], ], [ [4.0, 5.0], [6.0, 7.0], [8.0, 9.0], ], ]; const classProperty = example_variable_length_UINT32_VEC2_array; const values = example_variable_length_UINT32_VEC2_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_fixed_length_UINT32_VEC2_array(): BinaryPropertyTable { const example_fixed_length_UINT32_VEC2_array: ClassProperty = { type: "VEC2", componentType: "FLOAT32", array: true, count: 2, }; const example_fixed_length_UINT32_VEC2_array_values = [ [ [0.0, 1.0], [2.0, 3.0], ], [ [4.0, 5.0], [6.0, 7.0], ], ]; const classProperty = example_fixed_length_UINT32_VEC2_array; const values = example_fixed_length_UINT32_VEC2_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_variable_length_ENUM_array(): BinaryPropertyTable { const example_variable_length_ENUM_array: ClassProperty = { type: "ENUM", enumType: "testMetadataEnum", array: true, }; const example_example_variable_length_ENUM_array_values = [ ["ExampleEnumValueA", "ExampleEnumValueB", "ExampleEnumValueC"], ["ExampleEnumValueB", "ExampleEnumValueA"], ]; const testMetadataEnum: MetadataEnum = { values: [ { name: "ExampleEnumValueA", value: 0, }, { name: "ExampleEnumValueB", value: 1, }, { name: "ExampleEnumValueC", value: 2, }, ], }; const classProperty = example_variable_length_ENUM_array; const values = example_example_variable_length_ENUM_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, testMetadataEnum ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_ENUM_with_noData(): BinaryPropertyTable { const example_ENUM: ClassProperty = { type: "ENUM", enumType: "testMetadataEnum", noData: "ExampleEnumValueNoData", default: "ExampleEnumValueB", }; const example_ENUM_values = [ "ExampleEnumValueA", "ExampleEnumValueB", "ExampleEnumValueC", "ExampleEnumValueNoData", ]; const testMetadataEnum: MetadataEnum = { values: [ { name: "ExampleEnumValueA", value: 0, }, { name: "ExampleEnumValueB", value: 1, }, { name: "ExampleEnumValueC", value: 2, }, { name: "ExampleEnumValueNoData", value: 9999, }, ], }; const classProperty = example_ENUM; const values = example_ENUM_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, testMetadataEnum ); return binaryPropertyTable; } /** * Creates an unspecified valid default `BinaryPropertyTable`, containing * a single property with the type indicated in the method name. * * @returns The `BinaryPropertyTable` */ static createDefaultBinaryPropertyTable_example_fixed_length_normalized_INT64_VEC2_array(): BinaryPropertyTable { const example_fixed_length_normalized_INT64_VEC2_array: ClassProperty = { type: "VEC2", componentType: "INT64", array: true, normalized: true, }; // The normalized values here are // [ // [ 0, 0] // [-1, 0] // [ 0, -1] // ], // [ // [ 0, 0] // [ 1, 0] // [ 0, 1] // ] const example_fixed_length_normalized_INT64_VEC2_array_values = [ [ [0, 0], [-9223372036854775808n, 0], [0, -9223372036854775808n], ], [ [0, 0], [9223372036854775807n, 0], [0, 9223372036854775807n], ], ]; const classProperty = example_fixed_length_normalized_INT64_VEC2_array; const values = example_fixed_length_normalized_INT64_VEC2_array_values; const arrayOffsetType = "UINT32"; const stringOffsetType = "UINT32"; const binaryPropertyTable = BinaryPropertyTables.createBinaryPropertyTableFromProperty( "testProperty", classProperty, values, arrayOffsetType, stringOffsetType, undefined ); return binaryPropertyTable; } } ================================================ FILE: specs/metadata/PropertyTableValidationSpec.ts ================================================ import { readJsonUnchecked } from "../../src/base/readJsonUnchecked"; import { ResourceResolvers } from "3d-tiles-tools"; import { ValidationContext } from "../../src/validation/ValidationContext"; import { PropertyTableValidator } from "../../src/validation/metadata/PropertyTableValidator"; import { Schema } from "3d-tiles-tools"; describe("metadata/PropertyTableValidationSpec", function () { let fullMetadataSchema: Schema; let context: ValidationContext; beforeAll(async function () { fullMetadataSchema = await readJsonUnchecked( "specs/data/schemas/FullMetadataSchema.json" ); }); beforeEach(async function () { const directory = "specs/data/propertyTables/"; const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); context = new ValidationContext(directory, resourceResolver); }); it("detects issues in propertiesInvalidType", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertiesInvalidType.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in propertiesMinPropertiesMismatch", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertiesMinPropertiesMismatch.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("NUMBER_OF_PROPERTIES_MISMATCH"); }); it("detects issues in propertyArrayOffsetsInvalidType", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyArrayOffsetsInvalidType.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in propertyArrayOffsetsInvalidValue", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyArrayOffsetsInvalidValue.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in propertyArrayOffsetTypeInvalidType", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyArrayOffsetTypeInvalidType.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in propertyArrayOffsetTypeInvalidValue", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyArrayOffsetTypeInvalidValue.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in propertyClassInvalidType", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyClassInvalidType.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in propertyClassInvalidValue", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyClassInvalidValue.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in propertyCountInvalidType", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyCountInvalidType.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in propertyCountInvalidValue", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyCountInvalidValue.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in propertyIdInvalid", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyIdInvalid.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("IDENTIFIER_NOT_FOUND"); }); it("detects issues in propertyStringOffsetsInvalidType", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyStringOffsetsInvalidType.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in propertyStringOffsetsInvalidValue", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyStringOffsetsInvalidValue.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE"); }); it("detects issues in propertyStringOffsetTypeInvalidType", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyStringOffsetTypeInvalidType.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in propertyStringOffsetTypeInvalidValue", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyStringOffsetTypeInvalidValue.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("VALUE_NOT_IN_LIST"); }); it("detects issues in propertyStringWithoutStringOffsets", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyStringWithoutStringOffsets.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); it("detects issues in propertyValueMissing", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyValueMissing.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("PROPERTY_MISSING"); }); it("detects issues in propertyValuesInvalidType", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyValuesInvalidType.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); it("detects issues in propertyVariableLengthArrayWithMin", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyVariableLengthArrayWithMin.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY" ); }); it("detects issues in propertyVariableLengthArrayWithOffset", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyVariableLengthArrayWithOffset.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual( "METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY" ); }); it("detects issues in propertyVariableLengthArrayWithoutArrayOffsets", async function () { const inputData = await readJsonUnchecked( "specs/data/propertyTables/propertyVariableLengthArrayWithoutArrayOffsets.json" ); const propertyTable = inputData.propertyTables[0]; const numBufferViews = 2; PropertyTableValidator.validatePropertyTable( "test", propertyTable, numBufferViews, fullMetadataSchema, context ); const result = context.getResult(); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); }); ================================================ FILE: src/ValidatorMain.ts ================================================ import path from "path"; import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { Iterables } from "3d-tiles-tools"; import { TileImplicitTiling } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { readJsonUnchecked } from "./base/readJsonUnchecked"; import { globMatcher } from "./base/globMatcher"; import { writeUnchecked } from "./base/writeUnchecked"; import { Validators } from "./validation/Validators"; import { ValidationResult } from "./validation/ValidationResult"; import { ValidationOptions } from "./validation/ValidationOptions"; import { ValidatedElement } from "./validation/ValidatedElement"; /** * A class summarizing the command-line functions of the validator. * * The functions in this class are supposed to be called from `main.ts`, * based on the parsed command line arguments. * * @internal */ export class ValidatorMain { static readonly specsDataRootDir = "specs/data/"; /** * Performs a run of the validator, using the given configuration settings. * * The configuration may contain properties that match the (long form * of the) command line arguments, as well as an `options: ValidationOptions` * object (using default options if none are given). * * @param args - The command line arguments (the `yargs` instance) * @param config - The configuration for the validator run */ static async performValidation(args: any, config: any) { const validationOptions = defaultValue( config.options, new ValidationOptions() ); if (config.tilesetFile) { const reportFileName = ValidatorMain.obtainReportFileName( config, config.tilesetFile ); await ValidatorMain.validateTilesetFile( config.tilesetFile, reportFileName, validationOptions ); } else if (config.tilesetsDirectory) { await ValidatorMain.validateTilesetsDirectory( config.tilesetsDirectory, config.tilesetGlobPattern, config.writeReports, validationOptions ); } else if (config.tileContentFile) { const reportFileName = ValidatorMain.obtainReportFileName( config, config.tileContentFile ); await ValidatorMain.validateTileContentFile( config.tileContentFile, reportFileName, validationOptions ); } else if (config.metadataSchemaFile) { const reportFileName = ValidatorMain.obtainReportFileName( config, config.metadataSchemaFile ); await ValidatorMain.validateSchemaFile( config.metadataSchemaFile, reportFileName ); } else if (config.tilesetSpecs) { await ValidatorMain.validateAllTilesetSpecFiles(config.writeReports); } else if (config.metadataSchemaSpecs) { await ValidatorMain.validateAllMetadataSchemaSpecFiles( config.writeReports ); } else if (config.subtreeSpecs) { await ValidatorMain.validateAllSubtreeSpecFiles(config.writeReports); } else { args.showHelp(); } } /** * If a `reportFile` was specified in the given configuration, * then this is returned. * * Otherwise, if `writeReports` was specified, a report file * name is derived from the given file name and returned * (with the details about this name being unspecified for now). * * Otherwise, `undefined` is returned. * * @param config - The validation configuration * @param inputFileName - The input file name * @returns The report file name, or `undefined` */ private static obtainReportFileName( config: any, inputFileName: string ): string | undefined { if (config.reportFile) { return config.reportFile; } if (config.writeReports) { return ValidatorMain.deriveReportFileName(inputFileName); } return undefined; } static async validateTilesetFile( fileName: string, reportFileName: string | undefined, options: ValidationOptions | undefined ): Promise { console.log("Validating tileset " + fileName); const validationResult = await Validators.validateTilesetFile( fileName, options ); if (defined(reportFileName)) { await writeUnchecked(reportFileName, validationResult.serialize()); } else { console.log("Validation result:"); console.log(validationResult.serialize()); } return validationResult; } static async validateTilesetsDirectory( directoryName: string, globPattern: string, writeReports: boolean, options: ValidationOptions | undefined ): Promise { console.log( "Validating tilesets from " + directoryName + " matching " + globPattern ); const recurse = true; const allFiles = Iterables.overFiles(directoryName, recurse); const ignoreCase = true; const matcher = globMatcher(globPattern, ignoreCase); const tilesetFiles = Iterables.filter(allFiles, matcher); let numFiles = 0; let numFilesWithErrors = 0; let numFilesWithWarnings = 0; let numFilesWithInfos = 0; for (const tilesetFile of tilesetFiles) { let reportFileName = undefined; if (writeReports) { reportFileName = ValidatorMain.deriveReportFileName(tilesetFile); } const validationResult = await ValidatorMain.validateTilesetFile( tilesetFile, reportFileName, options ); numFiles++; if (validationResult.numErrors > 0) { numFilesWithErrors++; } if (validationResult.numWarnings > 0) { numFilesWithWarnings++; } if (validationResult.numInfos > 0) { numFilesWithInfos++; } } console.log(`Validated ${numFiles} files`); console.log(` ${numFilesWithErrors} files with errors`); console.log(` ${numFilesWithWarnings} files with warnings`); console.log(` ${numFilesWithInfos} files with infos`); } static async validateTileContentFile( fileName: string, reportFileName: string | undefined, options: ValidationOptions | undefined ): Promise { console.log("Validating tile content " + fileName); const validationResult = await Validators.validateTileContentFile( fileName, options ); if (defined(reportFileName)) { await writeUnchecked(reportFileName, validationResult.serialize()); } else { console.log("Validation result:"); console.log(validationResult.serialize()); } return validationResult; } static async validateSchemaFile( fileName: string, reportFileName: string | undefined ): Promise { console.log("Validating schema " + fileName); const validationResult = await Validators.validateSchemaFile(fileName); if (defined(reportFileName)) { await writeUnchecked(reportFileName, validationResult.serialize()); } else { console.log("Validation result:"); console.log(validationResult.serialize()); } return validationResult; } static async validateSubtreeFile( fileName: string, schemaState: ValidatedElement, implicitTiling: TileImplicitTiling | undefined, reportFileName: string | undefined ): Promise { console.log("Validating subtree " + fileName); const validationResult = await Validators.validateSubtreeFile( fileName, schemaState, implicitTiling ); if (defined(reportFileName)) { await writeUnchecked(reportFileName, validationResult.serialize()); } else { console.log("Validation result:"); console.log(validationResult.serialize()); } return validationResult; } static async validateAllTilesetSpecFiles( writeReports: boolean ): Promise { const recurse = true; const allSpecFiles = Iterables.overFiles( ValidatorMain.specsDataRootDir + "/tilesets", recurse ); const ignoreCase = true; const matcher = globMatcher("**/*.json", ignoreCase); const specFiles = Iterables.filter(allSpecFiles, matcher); for (const specFile of specFiles) { let reportFileName = undefined; if (writeReports) { reportFileName = ValidatorMain.deriveReportFileName(specFile); } await ValidatorMain.validateTilesetFile( specFile, reportFileName, undefined ); } } static async validateAllMetadataSchemaSpecFiles( writeReports: boolean ): Promise { const recurse = false; const allSpecFiles = Iterables.overFiles( ValidatorMain.specsDataRootDir + "schemas", recurse ); const ignoreCase = true; const matcher = globMatcher("**/*.json", ignoreCase); const specFiles = Iterables.filter(allSpecFiles, matcher); for (const specFile of specFiles) { let reportFileName = undefined; if (writeReports) { reportFileName = ValidatorMain.deriveReportFileName(specFile); } await ValidatorMain.validateSchemaFile(specFile, reportFileName); } } static async validateAllSubtreeSpecFiles( writeReports: boolean ): Promise { const recurse = false; const allSpecFiles = Iterables.overFiles( ValidatorMain.specsDataRootDir + "subtrees", recurse ); const ignoreCase = true; const matcher = globMatcher("**/{*.json,*.subtree}", ignoreCase); const specFiles = Iterables.filter(allSpecFiles, matcher); for (const specFile of specFiles) { let reportFileName = undefined; if (writeReports) { reportFileName = ValidatorMain.deriveReportFileName(specFile); } await ValidatorMain.validateSubtreeSpecFile(specFile, reportFileName); } } static async validateSubtreeSpecFile( fileName: string, reportFileName: string | undefined ): Promise { // The schema for the subtrees in the specs directory const specSchema: Schema = await readJsonUnchecked( "specs/data/schemas/validSchema.json" ); const specSchemaState: ValidatedElement = { wasPresent: true, validatedElement: specSchema, }; // The `TileImplicitTiling` object that defines the // structure of subtrees in the specs directory const specImplicitTiling = await readJsonUnchecked( "specs/data/subtrees/validSubtreeImplicitTiling.json.input" ); await ValidatorMain.validateSubtreeFile( fileName, specSchemaState, specImplicitTiling, reportFileName ); } /** * Derives a file name for a report from the given input file name. * The resulting file name will be a file in the same directory as * the given one. Further details are intentionally not specified here. * * @param inputFileName - The input file name * @returns The report file name */ static deriveReportFileName(inputFileName: string): string | undefined { const basename = path.basename(inputFileName, path.extname(inputFileName)); const extension = ".report.json"; return path.join(path.dirname(inputFileName), basename + extension); } } ================================================ FILE: src/archives/ArchiveValidation3tz.ts ================================================ import fs from "fs"; import crypto from "crypto"; import StreamZip = require("node-stream-zip"); import { IndexEntry } from "3d-tiles-tools"; import { ArchiveFunctions3tz } from "3d-tiles-tools"; // NOTE: These functions are carved out and ported to TypeScript from // https://github.com/bjornblissing/3d-tiles-tools/blob/2f4844d5bdd704509bff65199898981228594aaa/validator/lib/archive.js // TODO: The given implementation does not handle hash collisions! export class ArchiveValidation3tz { private static slowValidateIndex( zipIndex: IndexEntry[], zipFilePath: string ): Promise { // eslint-disable-next-line @typescript-eslint/no-unused-vars return new Promise((resolve, reject) => { let zipFileEntriesCount = 0; const zip = new StreamZip({ file: zipFilePath, storeEntries: false, }); zip.on("error", (err: any) => { throw err; }); zip.on("ready", () => { // console.log(`Total zip entries: ${zip.entriesCount} file entries: ${zipFileEntriesCount}`); zip.close(); if (zipIndex.length !== zipFileEntriesCount) { throw Error( `Zip index has too few entries, expected ${zipFileEntriesCount} but got ${zipIndex.length}.` ); } resolve(true); }); zip.on("entry", (entry: any) => { if (entry.isFile && entry.name !== "@3dtilesIndex1@") { zipFileEntriesCount++; //console.log(`Validating index entry for ${entry.name}`); const hash = crypto.createHash("md5").update(entry.name).digest(); const index = ArchiveFunctions3tz.zipIndexFind(zipIndex, hash); if (index === -1) { throw Error(`${entry.name} - ${hash} not found in index.`); } else { const indexEntryOffset = zipIndex[index].offset; if (Number(entry.offset) !== Number(indexEntryOffset)) { throw Error( `${entry.name} - ${hash} had incorrect offset ${indexEntryOffset}, expected ${entry.offset}` ); } } } }); }).catch((err) => { console.error(`Zip index validation failed: ${err}`); return false; }); } private static md5AsUInt64(md5hashBuffer: Buffer) { return [md5hashBuffer.readBigUInt64LE(0), md5hashBuffer.readBigUInt64LE(8)]; } static async validateIndex( zipIndex: IndexEntry[], zipFilePath: string, quick: boolean ) { console.time("validate index"); let valid = true; const numItems = zipIndex.length; if (numItems > 1) { const errors: { collisions: number[][] } = { collisions: [], }; for (let i = 1; i < numItems; i++) { const prevEntry = zipIndex[i - 1]; const curEntry = zipIndex[i]; const [curHashHi, curHashLo] = ArchiveValidation3tz.md5AsUInt64( curEntry.hash ); if (prevEntry.hash.compare(curEntry.hash) === 0) { errors.collisions.push([i - 1, i]); } const [prevHashHi, prevHashLo] = ArchiveValidation3tz.md5AsUInt64( prevEntry.hash ); if (!ArchiveFunctions3tz.md5LessThan(prevEntry.hash, curEntry.hash)) { console.warn( `Wrong sort order\n${i}: ${curEntry.hash.toString( "hex" )} (${curHashHi} ${curHashLo}) should be smaller than\n${ i - 1 }: ${prevEntry.hash.toString("hex")} (${prevHashHi} ${prevHashLo})` ); valid = false; } } if (errors.collisions.length) { for (const c of errors.collisions) { console.warn(`Got hash collision at index ${c[0]} and ${c[1]}`); } } } const rootHash = crypto.createHash("md5").update("tileset.json").digest(); const rootIndex = ArchiveFunctions3tz.zipIndexFind(zipIndex, rootHash); if (rootIndex === -1) { valid = false; console.error("Index has no key for the root tileset"); } else { const fd = fs.openSync(zipFilePath, "r"); try { ArchiveFunctions3tz.readZipLocalFileHeader( fd, zipIndex[rootIndex].offset, "tileset.json" ); } catch (err) { valid = false; console.error(`${err}`); } fs.closeSync(fd); } if (!quick && valid) { valid = await ArchiveValidation3tz.slowValidateIndex( zipIndex, zipFilePath ); } console.log(`Zip index is ${valid ? "valid" : "invalid"}`); console.timeEnd("validate index"); return valid; } } ================================================ FILE: src/base/ResourceError.ts ================================================ /** * An error that may be thrown to indicate that an expected * resource could not be resolved. */ export class ResourceError extends Error { constructor(message: string) { super(message); // See https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes // #extending-built-ins-like-error-array-and-map-may-no-longer-work Object.setPrototypeOf(this, ResourceError.prototype); } override toString = (): string => { return `${this.name}: ${this.message}`; }; } ================================================ FILE: src/base/globMatcher.ts ================================================ import minimatch from "minimatch"; /** * Returns a function that receives a string, and returns whether * the string matches the given glob * * @param glob - The glob expression * @param ignoreCase - Whether the matching should be case-insensitive * @returns The matcher */ export function globMatcher( glob: string, ignoreCase = true ): (s: string) => boolean { const Minimatch = minimatch.Minimatch; const mm = new Minimatch(glob, { nocase: ignoreCase }); return (s: string) => mm.match(s); } ================================================ FILE: src/base/readJsonUnchecked.ts ================================================ import fs from "fs"; import { defined } from "3d-tiles-tools"; /** * Only for internal use and basic tests: * * Reads a JSON file, parses it, and returns the result. * If the file cannot be read or parsed, then an error * message will be printed and `undefined` is returned. * * @param filePath - The path to the file * @returns A promise that resolves with the result or `undefined` */ export async function readJsonUnchecked(filePath: string): Promise { try { const data = fs.readFileSync(filePath); if (!defined(data)) { console.error("Could not read " + filePath); return undefined; } const jsonString = data.toString(); const result = JSON.parse(jsonString); return result; } catch (error) { console.error("Could not parse JSON", error); return undefined; } } ================================================ FILE: src/base/writeUnchecked.ts ================================================ import fs from "fs"; /** * Only for internal use: * * Writes the given string to the given file. * If the file cannot be written, then an error * message will be printed. * * @param filePath - The path to the file * @param data - The string * @returns A promise that resolves when the data is written */ export async function writeUnchecked( filePath: string, data: string ): Promise { try { fs.writeFileSync(filePath, data, "utf8"); } catch (error) { console.log(error); } } ================================================ FILE: src/index.ts ================================================ export * from "./validation/Validators"; export * from "./validation/ValidationResult"; export * from "./validation/ValidationOptions"; export * from "./validation/ValidationIssue"; export * from "./validation/ValidationIssueSeverity"; export * from "./validation/ValidationIssueFilter"; export * from "./validation/ValidationIssueFilters"; ================================================ FILE: src/issues/BinaryValidationIssues.ts ================================================ import { ValidationIssue } from "../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../validation/ValidationIssueSeverity"; /** * Methods to create `ValidationIssue` instances that describe * issues related to binary data of tile content or subtree files. */ export class BinaryValidationIssues { /** * Indicates that the binary data was fundamentally invalid (usually * caused by not even being able to read a header) * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static BINARY_INVALID(path: string, message: string) { const type = "BINARY_INVALID"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that an unexpected value was found in the binary - * for example, an unexpected magic value or version. * * @param path - The path for the `ValidationIssue` * @param name - The name of the value * @param expected - The expected value * @param actual - The actual value * @returns The `ValidationIssue` */ static BINARY_INVALID_VALUE( path: string, name: string, expected: any, actual: any ) { const message = `The ${name} must be ${expected} but is ${actual}`; return BinaryValidationIssues._BINARY_INVALID_VALUE(path, message); } // Internal method for BINARY_INVALID_VALUE private static _BINARY_INVALID_VALUE(path: string, message: string) { const type = "BINARY_INVALID_VALUE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the byte length information that was read from * binary was inconsistent. For example, when the total byte length * from the header does not match the length of the binary blob. * * @param path - The path for the `ValidationIssue` * @param name - A short name for the length * @param expectedLength - The expected length * @param actualLength - The actual length * @returns The `ValidationIssue` */ static BINARY_INVALID_LENGTH( path: string, name: string, expectedLength: number | bigint, actualLength: number | bigint ) { const message = `The length of ${name} must be ${expectedLength} ` + `but is ${actualLength}`; return BinaryValidationIssues._BINARY_INVALID_LENGTH(path, message); } // Internal method for BINARY_INVALID_LENGTH private static _BINARY_INVALID_LENGTH(path: string, message: string) { const type = "BINARY_INVALID_LENGTH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that an alignment requirement for a part of the * binary data was not met. * * @param path - The path for the `ValidationIssue` * @param name - A short name for the part of the binary data * @param expectedAlignment - The expected alignment * @returns The `ValidationIssue` */ static BINARY_INVALID_ALIGNMENT( path: string, name: string, expectedAlignment: number | bigint, actualValue: number | bigint, misalignment: number | bigint ) { const message = `The ${name} must be aligned to ${expectedAlignment} bytes, ` + `but is ${actualValue}, causing a misalignment of ${misalignment}`; return BinaryValidationIssues._BINARY_INVALID_ALIGNMENT(path, message); } // Internal method for BINARY_INVALID_ALIGNMENT static _BINARY_INVALID_ALIGNMENT(path: string, message: string) { const type = "BINARY_INVALID_ALIGNMENT"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that an alignment requirement for a part of the * binary data was not met. * * This is only used for the legacy tile formats validations. * New alignment checks should use the convenience method * `BinaryValidator#validateAlignment`, which creates more * elaborate messages. * * @param path - The path for the `ValidationIssue` * @param name - A short name for the part of the binary data * @param expectedAlignment - The expected alignment * @returns The `ValidationIssue` */ static BINARY_INVALID_ALIGNMENT_legacy( path: string, name: string, expectedAlignment: number ) { const message = `The ${name} must be aligned to ${expectedAlignment} bytes`; return BinaryValidationIssues._BINARY_INVALID_ALIGNMENT(path, message); } } ================================================ FILE: src/issues/ContentValidationIssues.ts ================================================ import { ValidationIssue } from "../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../validation/ValidationIssueSeverity"; import { ValidationResult } from "../validation/ValidationResult"; /** * Methods to create `ValidationIssue` instances that describe * issues related to (binary) tile content. */ export class ContentValidationIssues { /** * Creates a new `ValidationIssue` that summarizes the * given `ValidationResult`, or `undefined` if the given * result is empty. * * The returned issue will have the issues from the given * result as its 'causes'. * * The type of the returned issue will be of the form * "CONTENT_VALIDATION_", with the 'severity' * being the highest severity of any issue in the given * result (ERROR, WARNING, or INFO). * * @param path - The path * @param result - The `ValidationResult` * @returns The `ValidationIssue`, or `undefined` */ static createForContent( path: string, result: ValidationResult ): ValidationIssue | undefined { return ContentValidationIssues.createFrom( path, result, "CONTENT_VALIDATION" ); } /** * Creates a new `ValidationIssue` that summarizes the * given `ValidationResult`, or `undefined` if the given * result is empty. * * The returned issue will have the issues from the given * result as its 'causes'. * * The type of the returned issue will be of the form * "EXTERNAL_TILESET_VALIDATION_", with the 'severity' * being the highest severity of any issue in the given * result (ERROR, WARNING, or INFO). * * @param path - The path * @param result - The `ValidationResult` * @returns The `ValidationIssue`, or `undefined` */ static createForExternalTileset( path: string, result: ValidationResult ): ValidationIssue | undefined { return ContentValidationIssues.createFrom( path, result, "EXTERNAL_TILESET_VALIDATION" ); } /** * Creates a new `ValidationIssue` that summarizes the * given `ValidationResult`, or `undefined` if the given * result is empty. * * The returned issue will have the issues from the given * result as its 'causes'. * * The severity of the returned issue will be the highest * severity of any issue in the given result (ERROR, WARNING, * or INFO). * * The type of the resulting issue will be of the form * "_". * * @param path - The path * @param result - The `ValidationResult` * @returns The `ValidationIssue`, or `undefined` */ private static createFrom( path: string, result: ValidationResult, prefix: string ): ValidationIssue | undefined { let hasErrors = false; let hasWarnings = false; let hasInfos = false; for (let i = 0; i < result.length; i++) { const issue = result.get(i); if (issue.severity == ValidationIssueSeverity.ERROR) { hasErrors = true; } if (issue.severity == ValidationIssueSeverity.WARNING) { hasWarnings = true; } if (issue.severity == ValidationIssueSeverity.INFO) { hasInfos = true; } } if (!hasErrors && !hasWarnings && !hasInfos) { return undefined; } let resultIssue; if (hasErrors) { const message = `${path} caused validation errors`; resultIssue = ContentValidationIssues.createIssue( prefix, ValidationIssueSeverity.ERROR, path, message ); } else if (hasWarnings) { const message = `${path} caused validation warnings`; resultIssue = ContentValidationIssues.createIssue( prefix, ValidationIssueSeverity.WARNING, path, message ); } else { const message = `${path} caused validation infos`; resultIssue = ContentValidationIssues.createIssue( prefix, ValidationIssueSeverity.INFO, path, message ); } for (let i = 0; i < result.length; i++) { const issue = result.get(i); resultIssue.addCause(issue); } return resultIssue; } /** * Creates a new issue from the given input, with * the type of the resulting issue being of the * form "_". * @param prefix - The prefix for the 'type' * @param severity - The severity * @param path - The path * @param message - The message * @returns The new validation issue */ private static createIssue( prefix: string, severity: ValidationIssueSeverity, path: string, message: string ) { const type = prefix + "_" + severity; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the validation of content caused an error. * * The returned issue may receive `causes` that summarize * the issues that eventually caused this issue. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static CONTENT_VALIDATION_ERROR(path: string, message: string) { const type = "CONTENT_VALIDATION_ERROR"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the validation of content caused a warning. * * The returned issue may receive `causes` that summarize * the issues that eventually caused this issue. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static CONTENT_VALIDATION_WARNING(path: string, message: string) { const type = "CONTENT_VALIDATION_WARNING"; const severity = ValidationIssueSeverity.WARNING; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the validation of content caused an issue * with severity level 'INFO'. * * The returned issue may receive `causes` that summarize * the issues that eventually caused this issue. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static CONTENT_VALIDATION_INFO(path: string, message: string) { const type = "CONTENT_VALIDATION_INFO"; const severity = ValidationIssueSeverity.INFO; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the JSON part of a tile content was invalid. * * This may refer to not being able to parse the JSON data * from a binary blob, or that the validation of the JSON * structure itself (using the legacy validation) caused an * error. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static CONTENT_JSON_INVALID(path: string, message: string) { const type = "CONTENT_JSON_INVALID"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/issues/GltfExtensionValidationIssues.ts ================================================ import { ValidationIssue } from "../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../validation/ValidationIssueSeverity"; /** * Methods to create `ValidationIssue` instances that describe * issues related to the validation of glTF extensions. */ export class GltfExtensionValidationIssues { /** * Indicates that the glTF was fundamentally invalid * (i.e. generally not a valid GLB/glTF asset at all) * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static GLTF_INVALID(path: string, message: string) { const type = "GLTF_INVALID"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the extension referred to an element in the * glTF asset that did not match the requirements of the * extension specification. (For example, a 'texCoord' that * referred to a VEC3 accessor). Further details should be * encoded in the 'message'. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static INVALID_GLTF_STRUCTURE(path: string, message: string) { const type = "INVALID_GLTF_STRUCTURE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the feature ID texture or property texture 'channels' * property had a structure that did not match the actual image data, * meaning that the `channels` array contained an element* that was * not smaller than the number of actual channels in the image. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static TEXTURE_CHANNELS_OUT_OF_RANGE(path: string, message: string) { const type = "TEXTURE_CHANNELS_OUT_OF_RANGE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the feature ID texture or property texture 'channels' * property had a structure that will likely not match the expected * data type. For example, when a 16-bit value was represented with * a single channel. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static TEXTURE_CHANNELS_SIZE_MISMATCH(path: string, message: string) { const type = "TEXTURE_CHANNELS_SIZE_MISMATCH"; const severity = ValidationIssueSeverity.WARNING; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the featureCount of a feature ID did not * match the actual number of IDs * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static FEATURE_COUNT_MISMATCH(path: string, message: string) { const type = "FEATURE_COUNT_MISMATCH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain property was defined in a context where * this type is not allowed. For example, when a variable-length * array or a 'STRING' property are used in a property texture. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static INVALID_METADATA_PROPERTY_TYPE(path: string, message: string) { const type = "INVALID_METADATA_PROPERTY_TYPE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/issues/IoValidationIssue.ts ================================================ import { ValidationIssue } from "../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../validation/ValidationIssueSeverity"; /** * Methods to create `ValidationIssue` instances that describe * issues on the level of input/output operations. */ export class IoValidationIssues { /** * Indicates that a required input could not be read. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static IO_ERROR(path: string, message: string) { const type = "IO_ERROR"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a required input could not be read. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static IO_WARNING(path: string, message: string) { const type = "IO_WARNING"; const severity = ValidationIssueSeverity.WARNING; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that an input that was expected to contain * JSON data could not be parsed. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static JSON_PARSE_ERROR(path: string, message: string) { const type = "JSON_PARSE_ERROR"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/issues/JsonValidationIssues.ts ================================================ import { ValidationIssue } from "../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../validation/ValidationIssueSeverity"; import { ValidationIssueUtils } from "./ValidationIssueUtils"; /** * Methods to create `ValidationIssue` instances that describe * issues on the level of JSON schema constraints. * * Most of the issues in this class are generated by the * `BasicValidator` functions. */ export class JsonValidationIssues { /** * Indicates that a property that is marked as 'required' in the * schema was missing. * * @param path - The path for the `ValidationIssue` * @param name - The name of the missing property * @returns The `ValidationIssue` */ static PROPERTY_MISSING(path: string, name: string) { const message = `The '${name}' property is required`; return JsonValidationIssues._PROPERTY_MISSING(path, message); } // Internal method for PROPERTY_MISSING private static _PROPERTY_MISSING(path: string, message: string) { const type = "PROPERTY_MISSING"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a property had a type that was different * than the one in the JSON schema. * * @param path - The path for the `ValidationIssue` * @param name - The name of the property * @param expectedType - The expected type * @param actualType - The actual type * @returns The `ValidationIssue` */ static TYPE_MISMATCH( path: string, name: string, expectedType: string, actualType: string ) { const message = `The '${name}' property must have ` + `type '${expectedType}', but has type '${actualType}'`; return JsonValidationIssues._TYPE_MISMATCH(path, message); } // Internal method for TYPE_MISMATCH private static _TYPE_MISMATCH(path: string, message: string) { const type = "TYPE_MISMATCH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that an array element had a type that was different * than the one in the JSON schema. * * @param path - The path for the `ValidationIssue` * @param name - The name of the array property * @param index - The index of the element * @param expectedType - The expected type * @param actualType - The actual type * @returns The `ValidationIssue` */ static ARRAY_ELEMENT_TYPE_MISMATCH( path: string, name: string, index: number, expectedType: string, actualType: string ) { const message = `The element at index ${index} of '${name}' must have type ` + `'${expectedType}', but has type '${actualType}'`; return JsonValidationIssues._ARRAY_ELEMENT_TYPE_MISMATCH(path, message); } // Internal method for ARRAY_ELEMENT_TYPE_MISMATCH private static _ARRAY_ELEMENT_TYPE_MISMATCH(path: string, message: string) { const type = "ARRAY_ELEMENT_TYPE_MISMATCH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a value in an array was not unique, even though * the items are required to be unique due to `uniqueItems:true` * in the JSON schema. * * @param path - The path for the `ValidationIssue` * @param name - The name of the array property * @param item - The duplicate item * @returns The `ValidationIssue` */ static ARRAY_ELEMENT_NOT_UNIQUE(path: string, name: string, item: any) { const type = "ARRAY_ELEMENT_NOT_UNIQUE"; const severity = ValidationIssueSeverity.ERROR; const message = `The element '${item}' in array '${name}' is not unique`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a numeric value was not in the range that * is specified by the JSON schema via the `minimum` and * `maximum` constraints. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static VALUE_NOT_IN_RANGE(path: string, message: string) { const type = "VALUE_NOT_IN_RANGE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a value was not in the set of allowed * values. This usually refers to enum values. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static VALUE_NOT_IN_LIST(path: string, message: string) { const type = "VALUE_NOT_IN_LIST"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the length of an array does not match the length * that is specified via the JSON schema, using the `minItems` * and `maxItems` constraints. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static ARRAY_LENGTH_MISMATCH(path: string, message: string) { const type = "ARRAY_LENGTH_MISMATCH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * A warning that indicates that an array SHOULD have had a * certain length, but had a different length. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static ARRAY_LENGTH_UNEXPECTED(path: string, message: string) { const type = "ARRAY_LENGTH_UNEXPECTED"; const severity = ValidationIssueSeverity.WARNING; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the length of a string does not match the length * that is specified via the JSON schema, using the `minLength` * and `maxLength` constraints. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static STRING_LENGTH_MISMATCH(path: string, message: string) { const type = "STRING_LENGTH_MISMATCH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the number of properties of an object does not match * meet the constraints that are specified via the JSON schema, using * the `minProperties` and `maxProperties` properties. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static NUMBER_OF_PROPERTIES_MISMATCH(path: string, message: string) { const type = "NUMBER_OF_PROPERTIES_MISMATCH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the pattern of a string property does not match the * required regular expression. * * @param path - The path for the `ValidationIssue` * @param name - The name of the property * @param value - The value of the property * @param pattern - A string representation of the expected pattern * @returns The `ValidationIssue` */ static STRING_PATTERN_MISMATCH( path: string, name: string, value: string, pattern: string ) { const message = `Property '${name}' must match the pattern '${pattern}', ` + `but has the value '${value}'`; return this._STRING_PATTERN_MISMATCH(path, message); } // Internal method for STRING_PATTERN_MISMATCH private static _STRING_PATTERN_MISMATCH(path: string, message: string) { const type = "STRING_PATTERN_MISMATCH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the the value of a string property does not meet * the necessary requirements. This refers to constraints about * the structure of the string value, e.g. when it has to be * a valid ISO8601 string. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static STRING_VALUE_INVALID(path: string, message: string) { const type = "STRING_VALUE_INVALID"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that multiple properties have been defined, when * only one of them should have been defined. * * @param path - The path for the `ValidationIssue` * @param name - The name of the containing object * @param properties - The names of the properties * @returns The `ValidationIssue` */ static ONE_OF_ERROR(path: string, name: string, ...properties: string[]) { const options = ValidationIssueUtils.joinNames("or", ...properties); const message = `The '${name}' may define ${options}, but not all of them`; return JsonValidationIssues._ONE_OF_ERROR(path, message); } // Internal method for ONE_OF_ERROR private static _ONE_OF_ERROR(path: string, message: string) { const type = "ONE_OF_ERROR"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that one of several properties must be defined, * but none of them was defined. * * @param path - The path for the `ValidationIssue` * @param name - The name of the containing object * @param properties - The names of the properties * @returns The `ValidationIssue` */ static ANY_OF_ERROR(path: string, name: string, ...properties: string[]) { const options = ValidationIssueUtils.joinNames("or", ...properties); const message = `The '${name}' must define ${options}, ` + `but not does not define any of them`; return JsonValidationIssues._ANY_OF_ERROR(path, message); } // Internal method for ANY_OF_ERROR private static _ANY_OF_ERROR(path: string, message: string) { const type = "ANY_OF_ERROR"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a property had a type that it should not have. * * This is ONLY used for the `rootProperty.extras` validation: * While the `extras` may have any type, a general best practice * is to let it be a dictionary (and not, for example, a string) * * @param path - The path for the `ValidationIssue` * @param name - The name of the property * @param expectedType - The expected type * @param actualType - The actual type * @returns The `ValidationIssue` */ static TYPE_UNEXPECTED( path: string, name: string, expectedType: string, actualType: string ) { const message = `The '${name}' property should have ` + `type '${expectedType}', but has type '${actualType}'`; return JsonValidationIssues._TYPE_UNEXPECTED(path, message); } // Internal method for TYPE_UNEXPECTED private static _TYPE_UNEXPECTED(path: string, message: string) { const type = "TYPE_UNEXPECTED"; const severity = ValidationIssueSeverity.WARNING; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/issues/MetadataValidationIssues.ts ================================================ import { ValidationIssue } from "../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../validation/ValidationIssueSeverity"; /** * Methods to create `ValidationIssue` instances that describe * issues related to metadata */ export class MetadataValidationIssues { /** * Indicates an invalid byte length in binary metadata. * * This is used for the case that a buffer view of a property table * has a size that does not match the expected size for the data * that it should contain. * * @param path - The path for the `ValidationIssue` * @param message - The message of the `ValidationIssue` * @returns The `ValidationIssue` */ static METADATA_INVALID_LENGTH(path: string, message: string) { const type = "METADATA_INVALID_LENGTH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the alignment requirements for binary metadata * have not been met. * * This is used when the byte offset of a buffer view is not * divisible by the size of the component type. * * @param path - The path for the `ValidationIssue` * @param message - The message of the `ValidationIssue` * @returns The `ValidationIssue` */ static METADATA_INVALID_ALIGNMENT(path: string, message: string) { const type = "METADATA_INVALID_ALIGNMENT"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the 'arrayOffsets' or 'stringOffsets' in * a binary property table property are invalid. * * This usually means that the offsets are not in ascending order. * * @param path - The path for the `ValidationIssue` * @param message - The message of the `ValidationIssue` * @returns The `ValidationIssue` */ static METADATA_INVALID_OFFSETS(path: string, message: string) { const type = "METADATA_INVALID_OFFSETS"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a value that was found in binary metadata is * not in the valid range. * * This means that the value is smaller than the minimum or * larger than the maximum, for the minimum/maximum either * being defined in the 'class property' or in the 'property * table property'. * * @param path - The path for the `ValidationIssue` * @param message - The message of the `ValidationIssue` * @returns The `ValidationIssue` */ static METADATA_VALUE_NOT_IN_RANGE(path: string, message: string) { const type = "METADATA_VALUE_NOT_IN_RANGE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a value that was found in binary metadata does * not match an expected value. * * This may be used, for example, when the minimum/maximum value * that is computed from the values in a property table does not * match the minimum/maximum that was defined for that * property table property. * * @param path - The path for the `ValidationIssue` * @param message - The message of the `ValidationIssue` * @returns The `ValidationIssue` */ static METADATA_VALUE_MISMATCH(path: string, message: string) { const type = "METADATA_VALUE_MISMATCH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a value of a property that was marked as * 'required' in the schema was not defined for a metadata * entity. * * @param path - The path for the `ValidationIssue` * @param propertyName - The name of the property * @returns The `ValidationIssue` */ static METADATA_VALUE_REQUIRED_BUT_MISSING( path: string, propertyName: string ) { const type = "METADATA_VALUE_REQUIRED_BUT_MISSING"; const severity = ValidationIssueSeverity.ERROR; const message = `The property '${propertyName}' is 'required', but ` + `no value has been given`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a class property in the metadata schema had * a 'semantic' that was not known. * * @param path - The path for the `ValidationIssue` * @param propertyName - The name of the property * @param semantic - The semantic that was assigned to the property * @returns The `ValidationIssue` */ static METADATA_SEMANTIC_UNKNOWN( path: string, propertyName: string, semantic: string ) { const type = "METADATA_SEMANTIC_UNKNOWN"; const severity = ValidationIssueSeverity.INFO; const message = `The property '${propertyName}' has unknown semantic '${semantic}'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a property had a semantic that was not valid for this * property. * * This means that the metadata schema defined a class property with a * certain 'semantic'. The 'semantic' was a known semantic, meaning * that it was associated with expectations about the property type * (e.g. that it should be a 'SCALAR' 'FLOAT32' value), and the * property definition did not match the structure that was expected * according to the semantic. * * @param path - The path for the `ValidationIssue` * @param message - The message of the `ValidationIssue` * @returns The `ValidationIssue` */ static METADATA_SEMANTIC_INVALID(path: string, message: string) { const type = "METADATA_SEMANTIC_INVALID"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a class property defined a 'componentType', even * though the 'type' did not indicate a numeric type. * * The 'componentType' may only be defined for 'SCALAR', 'VECn', * and 'MATn' types. * * @param path - The path for the `ValidationIssue` * @param componentType - The component type * @param theType - The type * @returns The `ValidationIssue` */ static CLASS_PROPERTY_COMPONENT_TYPE_FOR_NON_NUMERIC_TYPE( path: string, componentType: string, theType: string ) { const type = "CLASS_PROPERTY_COMPONENT_TYPE_FOR_NON_NUMERIC_TYPE"; const severity = ValidationIssueSeverity.ERROR; const message = `The 'componentType' was defined to be '${componentType}', but ` + `must be undefined for a property with type '${theType}'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a class property did not define a 'componentType', * even though the 'type' did indicate a numeric type. * * The 'componentType' must be defined for 'SCALAR', 'VECn', * and 'MATn' types. * * @param path - The path for the `ValidationIssue` * @param theType - The type * @returns The `ValidationIssue` */ static CLASS_PROPERTY_COMPONENT_TYPE_MISSING(path: string, theType: string) { const type = "CLASS_PROPERTY_COMPONENT_TYPE_MISSING"; const severity = ValidationIssueSeverity.ERROR; const message = `The 'componentType' must be defined for a ` + `property with type '${theType}'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a class property defined an 'enumType', even though * its 'type' was not 'ENUM'. * * @param path - The path for the `ValidationIssue` * @param enumType - The enumType * @param theType - The type * @returns The `ValidationIssue` */ static CLASS_PROPERTY_ENUMTYPE_WITH_NON_ENUM_TYPE( path: string, enumType: string, theType: string ) { const type = "CLASS_PROPERTY_ENUMTYPE_WITH_NON_ENUM_TYPE"; const severity = ValidationIssueSeverity.ERROR; const message = `The 'enumType' was defined to be '${enumType}', but ` + `must be undefined for a property with type '${theType}'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a class property did not define an 'enumType', * even though its 'type' was 'ENUM'. * * @param path - The path for the `ValidationIssue` * @returns The `ValidationIssue` */ static CLASS_PROPERTY_ENUM_TYPE_WITHOUT_ENUMTYPE(path: string) { const type = "CLASS_PROPERTY_ENUM_TYPE_WITHOUT_ENUMTYPE"; const severity = ValidationIssueSeverity.ERROR; const message = `The property has the type 'ENUM', but no 'enumType' was defined`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a class property defined an 'enumType' which was * not found in the schema definition. * * The 'enumType' must be the name of one of the enums that are * defined in the 'schema.enums' dictionary. * * @param path - The path for the `ValidationIssue` * @param enumType - The enumType * @returns The `ValidationIssue` */ static CLASS_PROPERTY_ENUMTYPE_NOT_FOUND(path: string, enumType: string) { const type = "CLASS_PROPERTY_ENUMTYPE_NOT_FOUND"; const severity = ValidationIssueSeverity.ERROR; const message = `The property refers to the 'enumType' to be '${enumType}', ` + `but the schema does not define this 'enumType'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a string that was given as an enum value was * not found in the enum definition. * * The valid names for enum values for a class property are defined * as the 'schema.enums[classProperty.enumType].values[i].name' values. * * This issue indicates that a string that was supposed to represent * an enum value (e.g. when it was given in a JSON-based metadata * entity, or as a 'noData' value of the property) did not appear in * this list of valid names. * * @param path - The path for the `ValidationIssue` * @param name - The name of the field or property that contained * the invalid enum value name (for example, 'noData') * @param propertyName - The property name * @param enumType - The enumType * @param enumValueName - The invalid enum value name * @returns The `ValidationIssue` */ static CLASS_PROPERTY_ENUM_VALUE_NAME_NOT_FOUND( path: string, name: string, propertyName: string, enumType: string | undefined, enumValueName: string ) { const type = "CLASS_PROPERTY_ENUM_VALUE_NAME_NOT_FOUND"; const severity = ValidationIssueSeverity.ERROR; const message = `The value '${name}' of property '${propertyName}' refers to a value ` + `with the name '${enumValueName}' of the enum '${enumType}', but this ` + `enum does not define a value with this name`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the 'count' property of a class property was * defined, even though it was not defined to be an 'array'. * * @param path - The path for the `ValidationIssue` * @param propertyName - The property name * @returns The `ValidationIssue` */ static CLASS_PROPERTY_COUNT_FOR_NON_ARRAY( path: string, propertyName: string ) { const type = "CLASS_PROPERTY_COUNT_FOR_NON_ARRAY"; const severity = ValidationIssueSeverity.ERROR; const message = `The property '${propertyName}' defines a 'count', but ` + `the property is not an array`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the 'normalized' property of a class property was * truthy, but its 'type' does not allow normalization. * * Normalization may only be applied when the 'type' is 'SCALAR', * 'VECn' or MATn'. * * @param path - The path for the `ValidationIssue` * @param propertyName - The property name * @param propertyType - The property type * @returns The `ValidationIssue` */ static CLASS_PROPERTY_NORMALIZED_FOR_NON_NORMALIZABLE_TYPE( path: string, propertyName: string, propertyType: string ) { const type = "CLASS_PROPERTY_NORMALIZED_FOR_NON_NORMALIZABLE_TYPE"; const severity = ValidationIssueSeverity.ERROR; const message = `The property '${propertyName}' is defined to be 'normalized', ` + `but the type '${propertyType}' can not be normalized`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the 'normalized' property of a class property was * truthy, but its 'componentType' does not allow normalization. * * Normalization may only be applied when the 'componentType' is * an integer type. * * @param path - The path for the `ValidationIssue` * @param propertyName - The property name * @param componentType - The component type * @returns The `ValidationIssue` */ static CLASS_PROPERTY_NORMALIZED_FOR_NON_INTEGER_COMPONENT_TYPE( path: string, propertyName: string, componentType: string ) { const type = "CLASS_PROPERTY_NORMALIZED_FOR_NON_NORMALIZABLE_TYPE"; const severity = ValidationIssueSeverity.ERROR; const message = `The property '${propertyName}' is defined to be 'normalized', ` + `but the component type '${componentType}' is not an integer type`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the 'offset' or 'scale' property of a class property * or property table property was defined, but its type is not effectively * a floating point type. * * A type is 'effectively floating point' when * - The 'type' is 'SCALAR', 'VECn', or 'MATn' * - AND: * - The 'componentType' is 'FLOATn' * - OR the 'componentType' is an integer type, and 'normalized' * * @param path - The path for the `ValidationIssue` * @param propertyName - The property name * @param offsetOrScale - The property ('offset' or 'scale') * @param propertyType - The property type * @param componentType - The component type * @param normalized - The value of the 'normalized' property * @returns The `ValidationIssue` */ static METADATA_OFFSET_SCALE_FOR_NON_FLOATING_POINT_TYPE( path: string, propertyName: string, offsetOrScale: string, propertyType: string, componentType: string | undefined, normalized: boolean | undefined ) { const type = "METADATA_OFFSET_SCALE_FOR_NON_FLOATING_POINT_TYPE"; const severity = ValidationIssueSeverity.ERROR; const message = `The property '${propertyName}' is defines '${offsetOrScale}', ` + `which is only applicable to properties with types 'SCALAR', ` + `'VEC2', 'VEC3', 'VEC4', 'MAT2', 'MAT3', or 'MAT4' when they have ` + `component types 'FLOAT32' or 'FLOAT64', or when they are normalized ` + `and have component types 'INT8', 'UINT8', 'INT16', 'UINT16', 'INT32', ` + `'UINT32', 'INT64', or 'UINT64', but the property has type ` + `'${propertyType}' with component type '${componentType}' and ` + `'normalized' is '${normalized}`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the 'min' or 'max' property of a class property * or property table property was defined, but its type is not a * numeric type * * A type is numeric when the 'type' is 'SCALAR', 'VECn', or 'MATn'. * * @param path - The path for the `ValidationIssue` * @param propertyName - The property name * @param minOrMax - The property ('min' or 'max') * @param propertyType - The property type * @returns The `ValidationIssue` */ static METADATA_MIN_MAX_FOR_NON_NUMERIC_TYPE( path: string, propertyName: string, minOrMax: string, propertyType: string ) { const type = "METADATA_MIN_MAX_FOR_NON_NUMERIC_TYPE"; const severity = ValidationIssueSeverity.ERROR; const message = `The property '${propertyName}' is defines '${minOrMax}', ` + `which is only applicable to properties with types 'SCALAR', ` + `'VEC2', 'VEC3', 'VEC4', 'MAT2', 'MAT3', or 'MAT4', but the ` + `property has type '${propertyType}'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates an inconsistency in a class property definition. * * This indicates that * - a 'noData' value was defined for a 'required' property * - a 'noData' value was defined for a 'BOOLEAN' property * - a 'default' value was defined for a 'required' property * * @param path - The path for the `ValidationIssue` * @param message - The message of the `ValidationIssue` * @returns The `ValidationIssue` */ static CLASS_PROPERTY_INCONSISTENT(path: string, message: string) { const type = "CLASS_PROPERTY_INCONSISTENT"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain property was defined for a variable-length * array property, but must be undefined for variable-length * array properties. * * This refers to * - the 'offset' and 'scale' * - the 'min' and 'max' * for both a 'class property' and a 'property table property' * * @param path - The path for the `ValidationIssue` * @param propertyName - The property name * @param invalidPropertyName - The name of the property that should * not be present ('min', 'max', 'offset', or 'scale') * @returns The `ValidationIssue` */ static METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY( path: string, propertyName: string, invalidPropertyName: string ) { const type = "METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY"; const severity = ValidationIssueSeverity.ERROR; const message = `The property '${propertyName}' defines '${invalidPropertyName}', ` + `which is not applicable to variable-length arrays`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain semantic was assigned to multiple properties. * * The class properties inside a schema may have a certain 'semantic'. * But each semantic may only be applied to one property within each * class. * * @param path - The path for the `ValidationIssue` * @param propertyNameA - The name of the first property * @param propertyNameB - The name of the second property * @param semantic - The semantic that was assigned to both properties * @returns The `ValidationIssue` */ static CLASS_PROPERTIES_DUPLICATE_SEMANTIC( path: string, propertyNameA: string, propertyNameB: string, semantic: string ) { const type = "CLASS_PROPERTIES_DUPLICATE_SEMANTIC"; const severity = ValidationIssueSeverity.ERROR; const message = `The semantic '${semantic}' was assigned to property ` + `'${propertyNameA}' and property '${propertyNameB}'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain name was used for multiple enum values. * * The 'enums[e].values[i].name' values must be unique for all 'i'. * * @param path - The path for the `ValidationIssue` * @param name - The name that appeared more than once * @returns The `ValidationIssue` */ static ENUM_VALUE_DUPLICATE_NAME(path: string, name: string) { const type = "ENUM_VALUE_DUPLICATE_NAME"; const severity = ValidationIssueSeverity.ERROR; const message = `There enum value name '${name}' is not unique`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain value was used for multiple enum values. * * The 'enums[e].values[i].value' values must be unique for all 'i'. * * @param path - The path for the `ValidationIssue` * @param value - The value that appeared more than once * @returns The `ValidationIssue` */ static ENUM_VALUE_DUPLICATE_VALUE(path: string, value: number) { const type = "ENUM_VALUE_DUPLICATE_VALUE"; const severity = ValidationIssueSeverity.ERROR; const message = `There enum value '${value}' is not unique`; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/issues/SemanticValidationIssues.ts ================================================ import { ValidationIssue } from "../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../validation/ValidationIssueSeverity"; import { ValidationIssueUtils } from "./ValidationIssueUtils"; /** * Methods to create `ValidationIssue` instances that describe * issues related to the semantical validity of tilesets. */ export class SemanticValidationIssues { /** * Indicates that the 'version' string of a tileset asset * had an unknown value. * * (The known values are defined by the 'AssetValidator' class) * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static ASSET_VERSION_UNKNOWN(path: string, message: string) { const type = "ASSET_VERSION_UNKNOWN"; const severity = ValidationIssueSeverity.WARNING; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the 'refine' value of a tile was valid, but * had an unexpected case. * * This only a warning, intended for legacy tilesets, where a * value like 'Replace' was still valid. Current tilesets should * always use uppercase values like 'REPLACE'. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static TILE_REFINE_WRONG_CASE(path: string, message: string) { const type = "TILE_REFINE_WRONG_CASE"; const severity = ValidationIssueSeverity.WARNING; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the 'refine' value was not given for a root * tile of a tileset. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static TILE_REFINE_MISSING_IN_ROOT(path: string, message: string) { const type = "TILE_REFINE_MISSING_IN_ROOT"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the root tile of an implicit tileset was invalid. * * This is caused by the root tile of an implicit tileset defining * one of the properties that are disallowed for implicit roots: * - tile.children * - tile.metadata * - tile.content.boundingVolume * * It may also indicate that the required subtree information * could not be created (for example, when the subtree data * could not be read) * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static TILE_IMPLICIT_ROOT_INVALID(path: string, message: string) { const type = "TILE_IMPLICIT_ROOT_INVALID"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a single bounding volume was invalid. * * This refers to certain constraints that are applied to * specific bounding volume types. For example, that the * radius of a bounding sphere may not be negative, or * that the borders of a bounding regions are within * valid ranges. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static BOUNDING_VOLUME_INVALID(path: string, message: string) { const type = "BOUNDING_VOLUME_INVALID"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a bounding volume structure was inconsistent. * * For now, this only means that a content bounding volume was * not fully contained in the tile bounding volume. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static BOUNDING_VOLUMES_INCONSISTENT(path: string, message: string) { const type = "BOUNDING_VOLUMES_INCONSISTENT"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a geometry type is invalid for the specific context. * * This is used for geometric validation where certain geometry types * are not allowed or supported. For example, when an extension requires * only specific geometry types like Polygon or MultiPolygon, but other * types like Point or LineString are found. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static INVALID_GEOMETRY_TYPE(path: string, message: string) { const type = "INVALID_GEOMETRY_TYPE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a geometry has an invalid size or insufficient data. * * This is used for geometric validation where geometries do not meet * minimum size requirements. For example, when a polygon ring has * insufficient coordinates to form a valid polygon, or when geometric * structures are too small to be meaningful. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static INVALID_GEOMETRY_SIZE(path: string, message: string) { const type = "INVALID_GEOMETRY_SIZE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a geometry has an invalid structure or topology. * * This is used for geometric validation where geometries have structural * problems that make them invalid. For example, when a polygon ring is * self-intersecting, has invalid winding order, or contains topological * inconsistencies that violate geometric constraints. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static INVALID_GEOMETRY_STRUCTURE(path: string, message: string) { const type = "INVALID_GEOMETRY_STRUCTURE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the minimum value of a 'tileset.properties' * element was larger than the maximum. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static PROPERTIES_MINIMUM_LARGER_THAN_MAXIMUM(path: string, message: string) { const type = "PROPERTIES_MINIMUM_LARGER_THAN_MAXIMUM"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates a warning that the geometric error of a tile was larger than * the geometric error of its parent. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static TILE_GEOMETRIC_ERRORS_INCONSISTENT(path: string, message: string) { const type = "TILE_GEOMETRIC_ERRORS_INCONSISTENT"; const severity = ValidationIssueSeverity.WARNING; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a template URI contained an invalid variable name. * * The template URIs that are used for contents or subtree files * in implicit tiling may contain variables like \{level\}, and * this issue indicates that there was an invalid variable name. * * @param path - The path for the `ValidationIssue` * @param variableName - The variable name * @param validVariableNames - The valid variable names * @returns The `ValidationIssue` */ static TEMPLATE_URI_INVALID_VARIABLE_NAME( path: string, variableName: string, validVariableNames: string[] ) { const type = "TEMPLATE_URI_INVALID_VARIABLE_NAME"; const severity = ValidationIssueSeverity.ERROR; const names = ValidationIssueUtils.joinNames("and", ...validVariableNames); const message = `The template URI refers to the variable '${variableName}', but ` + `may only refer to ${names}`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a template URI did not contain an expected variable name. * * The template URIs that are used for contents or subtree files * in implicit tiling are expected to contain certain variable * names. This issue is only a 'WARNING' for the case that an * expected name was not used. * * @param path - The path for the `ValidationIssue` * @param missingVVariableNames - The missing variable names * @returns The `ValidationIssue` */ static TEMPLATE_URI_MISSING_VARIABLE_NAME( path: string, missingVVariableNames: string[] ) { const type = "TEMPLATE_URI_MISSING_VARIABLE_NAME"; const severity = ValidationIssueSeverity.WARNING; const names = ValidationIssueUtils.joinNames( "and", ...missingVVariableNames ); const message = `The template URI does not use the variable names ${names}`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates an error in an implicit tileset structure. * * This is a generic error indicating that the internal structures * for traversing the implicit tileset could not be created. * Clients should rarely see this message, because errors that * prevent the traversal should be caught earlier (and prevent * the traversal attempts). But if it happens, the 'message' * should contain further information about the reason for * the error. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static IMPLICIT_TILING_ERROR(path: string, message: string) { const type = "IMPLICIT_TILING_ERROR"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates an inconsistency of buffers and buffer views. * * This mainly refers to the 'buffers' and 'bufferViews' of * an implicit subtree. It may, for example, indicate that a * buffer view does not fit into the buffer that it refers to. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static BUFFERS_INCONSISTENT(path: string, message: string) { const type = "BUFFERS_INCONSISTENT"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a binary buffer structure (like the 'buffers' and * 'bufferViews' of a subtree) contained `buffers`, but no `bufferViews`. * * This is only a WARNING, because it does not violate the specification, * but is certainly not intended. * * @param path - The path for the `ValidationIssue` * @returns The `ValidationIssue` */ static BUFFERS_WITHOUT_BUFFER_VIEWS(path: string) { const type = "BUFFERS_WITHOUT_BUFFER_VIEWS"; const message = "The object contained 'buffers' but no 'bufferViews'"; const severity = ValidationIssueSeverity.WARNING; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a binary buffer structure (like the 'buffers' and * 'bufferViews' of a subtree) contained `bufferViews`, but no `buffers` * * @param path - The path for the `ValidationIssue` * @returns The `ValidationIssue` */ static BUFFER_VIEWS_WITHOUT_BUFFERS(path: string) { const type = "BUFFER_VIEWS_WITHOUT_BUFFERS"; const message = "The object contained 'bufferViews' but no 'buffers'"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates an inconsistency in availability information. * * The availability information for tiles, content, and child * subtrees that is stored as part of an implicit tileset has * to obey certain constraints. For example: * - When a content is available, then the tile must be available * - When a tile is available, then the parent tile must be available * * More specific information about the inconsistency is given * in the error message. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static SUBTREE_AVAILABILITY_INCONSISTENT(path: string, message: string) { const type = "SUBTREE_AVAILABILITY_INCONSISTENT"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a tile transform was invalid. * * The exact constraints for being 'valid' are not specified. * For now, this indicates that the transform matrix was * the zero-matrix. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static TRANSFORM_INVALID(path: string, message: string) { const type = "TRANSFORM_INVALID"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain extension was listed in the * 'extensionsRequired', but not in the 'extensionsUsed' * of a tileset. * * @param path - The path for the `ValidationIssue` * @param extensionName - The extension name * @returns The `ValidationIssue` */ static EXTENSION_REQUIRED_BUT_NOT_USED(path: string, extensionName: string) { const type = "EXTENSION_REQUIRED_BUT_NOT_USED"; const severity = ValidationIssueSeverity.ERROR; const message = `The extension '${extensionName}' was declared in ` + `'extensionsRequired' but not in 'extensionsUsed'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain extension would be required * to be listed in the `extensionsRequired`, but was not * declared there. * * @param path - The path for the `ValidationIssue` * @param extensionName - The extension name * @returns The `ValidationIssue` */ static EXTENSION_REQUIRED_BUT_NOT_DECLARED( path: string, extensionName: string ) { const type = "EXTENSION_REQUIRED_BUT_NOT_DECLARED"; const severity = ValidationIssueSeverity.ERROR; const message = `The extension '${extensionName}' is required, but ` + `was not declared in 'extensionsRequired'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain extension was found, but was not * listed in the 'extensionsUsed' of a tileset. * * An extension is 'found' when it is encountered in any * 'someRootProperty.extensions' dictionary during the * traversal, or when it is an extension that allows a * new content type, and this type has been encountered * as a tile content. * * @param path - The path for the `ValidationIssue` * @param extensionName - The extension name * @returns The `ValidationIssue` */ static EXTENSION_FOUND_BUT_NOT_USED(path: string, extensionName: string) { const type = "EXTENSION_FOUND_BUT_NOT_USED"; const severity = ValidationIssueSeverity.ERROR; const message = `The extension '${extensionName}' was found, but not ` + `declared in 'extensionsUsed'`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain extension was listed in the * 'extensionsUsed' of a tileset, but not found during * the traversal. * * An extension is 'found' when it is encountered in any * 'someRootProperty.extensions' dictionary during the * traversal. * * NOTE: The exact mechanism for an extension being "used" may have to be * reviewed. See https://github.com/CesiumGS/3d-tiles-validator/issues/231 * * @param path - The path for the `ValidationIssue` * @param extensionName - The extension name * @returns The `ValidationIssue` */ static EXTENSION_USED_BUT_NOT_FOUND(path: string, extensionName: string) { const type = "EXTENSION_USED_BUT_NOT_FOUND"; const severity = ValidationIssueSeverity.WARNING; const message = `The extension '${extensionName}' was declared in ` + `'extensionsUsed', but not found`; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a certain extension was found during * the traversal, but is not known or handled by the * validator in any way. * * @param path - The path for the `ValidationIssue` * @param extensionName - The extension name * @returns The `ValidationIssue` */ static EXTENSION_NOT_SUPPORTED(path: string, extensionName: string) { const type = "EXTENSION_NOT_SUPPORTED"; const severity = ValidationIssueSeverity.WARNING; const message = `The extension '${extensionName}' was used, but is not supported`; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/issues/StructureValidationIssues.ts ================================================ import { ValidationIssue } from "../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../validation/ValidationIssueSeverity"; /** * Methods to create `ValidationIssue` instances that describe * generic, structural errors. */ export class StructureValidationIssues { /** * Indicates that a certain identifier was not found as * a key in a dictionary. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static IDENTIFIER_NOT_FOUND(path: string, message: string) { const type = "IDENTIFIER_NOT_FOUND"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a value that is required based on the presence * or absence of another value has not been defined. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static REQUIRED_VALUE_NOT_FOUND(path: string, message: string) { const type = "REQUIRED_VALUE_NOT_FOUND"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that a value that is disallowed based on the presence * or absence of another value has been defined. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static DISALLOWED_VALUE_FOUND(path: string, message: string) { const type = "DISALLOWED_VALUE_FOUND"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/issues/ValidationIssueUtils.ts ================================================ import { defined } from "3d-tiles-tools"; /** * Internal utility methods for validation issues * * @internal */ export class ValidationIssueUtils { /** * Creates a short string with a verbal description of the * given range. This requires at least one of the given * arguments to be defined. * * @param min - The minimum * @param max - The maximum * @returns The description */ static describeSimpleRange( min: number | undefined, max: number | undefined ): string { if (defined(min) && defined(max)) { if (min == max) { return `${min}`; } else { return `at least ${min} and at most ${max}`; } } else if (defined(min)) { return `at least ${min}`; } else if (defined(max)) { return `at most ${max}`; } // Should never happen return ""; } /** * Joins the given strings, enclosed in single quotes, * using commas and the given conjunction ("and" or "or"). * * Examples: * * undefined : undefined * [] : "" * ["a"] : "'a'" * ["a", "b"] : "'a' and 'b'" * ["a", "b", "c"] : "'a', 'b', and 'c'" * * @param conjunction - The conjunction to use * @param s - The strings * @returns The joined names */ static joinNames(conjunction: string, ...s: string[]) { if (!defined(s)) { return undefined; } if (s.length === 0) { return ""; } const t = s.map((e) => "'" + e + "'"); if (t.length === 1) { return t[0]; } if (t.length === 2) { return t[0] + " " + conjunction + " " + t[1]; } return ( t.slice(0, -1).join(", ") + ", " + conjunction + " " + t[t.length - 1] ); } } ================================================ FILE: src/issues/ValidationIssues.ts ================================================ import { ValidationIssue } from "../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../validation/ValidationIssueSeverity"; /** * Methods to create generic `ValidationIssue` instances */ export class ValidationIssues { /** * An issue that describes an internal error in the validator. * Clients should usually not receive this issue. It is used * as a last resort to gracefully handle internal issues * without breaking the validation process. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static INTERNAL_ERROR(path: string, message: string) { const type = "INTERNAL_ERROR"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/main.ts ================================================ //eslint-disable-next-line const yargs = require("yargs/yargs"); import { readJsonUnchecked } from "./base/readJsonUnchecked"; import { ValidationOptions } from "./validation/ValidationOptions"; import { ValidatorMain } from "./ValidatorMain"; import path from "path"; const args = yargs(process.argv.slice(1)) .help("help") .alias("help", "h") .options({ tilesetFile: { type: "string", alias: "t", describe: "The tileset input file path", }, tilesetsDirectory: { type: "string", alias: "T", describe: "The tileset input directory. This will validate all files " + "in the given directory and its subdirectories that match " + "the tilesetGlobPattern", }, tilesetGlobPattern: { type: "string", alias: "g", default: "**/*tileset*.json", describe: "The glob pattern for matching tileset input files from directories", }, reportFile: { type: "string", alias: "r", describe: "The name of the file where the report of a single " + "validated input file should be written", }, writeReports: { type: "boolean", alias: "w", describe: "Write one report file for each validated file. The file name " + "of the report will be derived from the input file name, " + "and be written into the same directory as the input file.", }, tileContentFile: { type: "string", alias: "f", describe: "The tile content input file path", }, optionsFile: { type: "string", alias: "o", describe: "The options file for the validation process", }, configFile: { type: "string", alias: "c", describe: "The configuration file for the validator run", }, metadataSchemaFile: { type: "string", describe: "(Internal) The metadata schema input file path", }, tilesetSpecs: { type: "boolean", describe: "(Internal) Validate all tileset spec files", }, metadataSchemaSpecs: { type: "boolean", describe: "(Internal) Validate all metadata schema spec files", }, subtreeSpecs: { type: "boolean", describe: "(Internal) Validate all subtree spec files", }, }) .demandCommand(); const argv = args.argv; /** * Read the specified options file and return the `ValidationOptions`. * If the file cannot be read, a warning will be printed and * default validation options will be returned. * * @param configFile - The name of the config file * @returns The `ValidationOptions`. */ async function readOptionsFile( optionsFile: string ): Promise { const validationOptionsObject = await readJsonUnchecked(optionsFile); if (!validationOptionsObject) { return new ValidationOptions(); } // Resolve semanticSchemaFileNames relative to the options file location const baseDir = path.dirname(optionsFile); if (Array.isArray(validationOptionsObject.semanticSchemaFileNames)) { validationOptionsObject.semanticSchemaFileNames = validationOptionsObject.semanticSchemaFileNames.map((p: string) => path.isAbsolute(p) ? p : path.resolve(baseDir, p) ); } const validationOptions = ValidationOptions.fromJson(validationOptionsObject); return validationOptions; } async function main() { const config = { options: new ValidationOptions(), }; if (argv.configFile) { const configFileData = await readJsonUnchecked(argv.configFile); if (!configFileData) { return; } Object.assign(config, configFileData); } else { Object.assign(config, argv); } if (argv.optionsFile) { config.options = await readOptionsFile(argv.optionsFile); } await ValidatorMain.performValidation(args, config); } void main(); ================================================ FILE: src/tileFormats/B3dmValidator.ts ================================================ // This was, to some extent, "ported" (or at least "inspired") from // https://github.com/CesiumGS/3d-tiles-validator/blob/e84202480eb6572383008076150c8e52c99af3c3/validator/lib/validateB3dm.js // It still contains legacy elements that may be cleaned up at some point. import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../validation/ValidationContext"; import { Validator } from "../validation/Validator"; import { GltfValidator } from "./GltfValidator"; import { TileFormatValidator } from "./TileFormatValidator"; import { IoValidationIssues } from "../issues/IoValidationIssue"; import { BinaryValidationIssues } from "../issues/BinaryValidationIssues"; import { ContentValidationIssues } from "../issues/ContentValidationIssues"; import { validateBatchTable } from "./legacy/validateBatchTable"; import { validateFeatureTable } from "./legacy/validateFeatureTable"; const featureTableSemantics = { BATCH_LENGTH: { global: true, type: "SCALAR", componentType: "UNSIGNED_INT", }, RTC_CENTER: { global: true, type: "VEC3", componentType: "FLOAT", }, }; /** * A class that can perform validation of B3DM data that is * given as a Buffer. * * @internal */ export class B3dmValidator implements Validator { async validateObject( uri: string, input: Buffer, context: ValidationContext ): Promise { const headerByteLength = 28; if ( !TileFormatValidator.validateHeader( uri, input, headerByteLength, "b3dm", context ) ) { return false; } // Legacy header #1: [batchLength] [batchTableByteLength] // Legacy header #2: [batchTableJsonByteLength] [batchTableBinaryByteLength] [batchLength] // Current header: [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] // If the header is in the first legacy format 'batchTableJsonByteLength' will // be the start of the JSON string (a quotation mark) or the glTF magic. // Accordingly its first byte will be either 0x22 or 0x67, and so the // minimum uint32 expected is 0x22000000 = 570425344 = 570MB. It is // unlikely that the batch table JSON will exceed this length. // The check for the second legacy format is similar, except it checks // 'batchTableBinaryByteLength' instead const batchTableJsonByteLength = input.readUInt32LE(20); const batchTableBinaryByteLength = input.readUInt32LE(24); if (batchTableJsonByteLength >= 570425344) { const message = `Header is using the legacy format [batchLength] ` + `[batchTableByteLength]. The new format is ` + `[featureTableJsonByteLength] [featureTableBinaryByteLength] ` + `[batchTableJsonByteLength] [batchTableBinaryByteLength].`; const issue = BinaryValidationIssues.BINARY_INVALID(uri, message); context.addIssue(issue); return false; } if (batchTableBinaryByteLength >= 570425344) { const message = `Header is using the legacy format [batchTableJsonByteLength] ` + `[batchTableBinaryByteLength] [batchLength]. The new format is ` + `[featureTableJsonByteLength] [featureTableBinaryByteLength] ` + `[batchTableJsonByteLength] [batchTableBinaryByteLength].`; const issue = BinaryValidationIssues.BINARY_INVALID(uri, message); context.addIssue(issue); return false; } const binaryTableDataState = TileFormatValidator.extractBinaryTableData( uri, input, headerByteLength, true, context ); const binaryTableData = binaryTableDataState.binaryTableData; if (!defined(binaryTableData)) { return false; } const featureTableJson = binaryTableData.featureTableJson; const featureTableBinary = binaryTableData.featureTableBinary; const batchTableJson = binaryTableData.batchTableJson; const batchTableBinary = binaryTableData.batchTableBinary; const glbData = binaryTableData.glbData; const featuresLength = featureTableJson.BATCH_LENGTH; if (!defined(featuresLength)) { const message = `Feature table must contain a BATCH_LENGTH property.`; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); return false; } const featureTableMessage = validateFeatureTable( featureTableJson, featureTableBinary, featuresLength, featureTableSemantics ); if (defined(featureTableMessage)) { const issue = ContentValidationIssues.CONTENT_JSON_INVALID( uri, featureTableMessage ); context.addIssue(issue); return false; } const batchTableMessage = validateBatchTable( batchTableJson, batchTableBinary, featuresLength ); if (defined(batchTableMessage)) { const issue = ContentValidationIssues.CONTENT_JSON_INVALID( uri, batchTableMessage ); context.addIssue(issue); return false; } if (defined(batchTableJson.extensions)) { const extensionNames = Object.keys(batchTableJson.extensions); for (const extensionFound of extensionNames) { context.addExtensionFound(extensionFound); } } const gltfValidator = new GltfValidator(); const gltfResult = await gltfValidator.validateObject( uri, glbData, context ); if (binaryTableDataState.isValid !== true) { return false; } return gltfResult; } } ================================================ FILE: src/tileFormats/CmptValidator.ts ================================================ // This was, to some extent, "ported" (or at least "inspired") from // https://github.com/CesiumGS/3d-tiles-validator/blob/e84202480eb6572383008076150c8e52c99af3c3/validator/lib/validateCmpt.js // It still contains legacy elements that may be cleaned up at some point. import { ValidationContext } from "../validation/ValidationContext"; import { Validator } from "../validation/Validator"; import { I3dmValidator } from "./I3dmValidator"; import { PntsValidator } from "./PntsValidator"; import { B3dmValidator } from "./B3dmValidator"; import { TileFormatValidator } from "./TileFormatValidator"; import { BinaryValidationIssues } from "../issues/BinaryValidationIssues"; /** * A class that can perform validation of CMPT data that is * given as a Buffer. * * @internal */ export class CmptValidator implements Validator { async validateObject( uri: string, input: Buffer, context: ValidationContext ): Promise { const headerByteLength = 16; if ( !TileFormatValidator.validateHeader( uri, input, headerByteLength, "cmpt", context ) ) { return false; } const byteLength = input.readUInt32LE(8); const tilesLength = input.readUInt32LE(12); let result = true; let byteOffset = headerByteLength; for (let i = 0; i < tilesLength; i++) { if (byteOffset + 12 > byteLength) { const message = "Cannot read byte length from inner tile, exceeds cmpt tile's byte length."; const issue = BinaryValidationIssues.BINARY_INVALID(uri, message); context.addIssue(issue); return false; } if (byteOffset % 8 > 0) { const message = "Inner tile must be aligned to an 8-byte boundary"; const issue = BinaryValidationIssues.BINARY_INVALID(uri, message); context.addIssue(issue); return false; } const innerTileMagic = input.toString("utf8", byteOffset, byteOffset + 4); const innerTileByteLength = input.readUInt32LE(byteOffset + 8); const innerTile = input.slice( byteOffset, byteOffset + innerTileByteLength ); if (innerTileMagic === "b3dm") { const innerValidator = new B3dmValidator(); const innerResult = await innerValidator.validateObject( uri, innerTile, context ); if (!innerResult) { result = false; } } else if (innerTileMagic === "i3dm") { const innerValidator = new I3dmValidator(); const innerResult = await innerValidator.validateObject( uri, innerTile, context ); if (!innerResult) { result = false; } } else if (innerTileMagic === "pnts") { const innerValidator = new PntsValidator(); const innerResult = await innerValidator.validateObject( uri, innerTile, context ); if (!innerResult) { result = false; } } else if (innerTileMagic === "cmpt") { const innerValidator = new CmptValidator(); const innerResult = await innerValidator.validateObject( uri, innerTile, context ); if (!innerResult) { result = false; } } else { const message = `Invalid inner tile magic: ${innerTileMagic}`; const issue = BinaryValidationIssues.BINARY_INVALID(uri, message); context.addIssue(issue); result = false; } byteOffset += innerTileByteLength; } return result; } } ================================================ FILE: src/tileFormats/GeojsonValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Validator } from "../validation/Validator"; import { ValidationContext } from "../validation/ValidationContext"; import { BasicValidator } from "../validation/BasicValidator"; import { JsonValidationIssues } from "../issues/JsonValidationIssues"; import { ContentValidationIssues } from "../issues/ContentValidationIssues"; /** * Validation strictness modes for GeoJSON content */ export enum GeojsonValidationMode { /** * Consumer mode - Only FeatureCollection is allowed at root level. * * This mode is appropriate for: * - Web mapping applications that expect collections of features * - APIs that serve GeoJSON data to web clients * - Systems that need to iterate over multiple geographic features * - Applications that display feature properties in UI components * * Most GeoJSON consumers (mapping libraries, web apps, servers) expect * a FeatureCollection as the root object because it provides a consistent * structure for handling multiple features with properties. */ CONSUMER = "consumer", /** * Strict mode - All valid GeoJSON types can be used at root level. * * This mode is appropriate for: * - Data interchange between GIS systems * - Scientific applications that work with raw geometric data * - Systems that need to validate against the official GeoJSON specification * - Applications that handle single geometric objects without properties * * The official GeoJSON specification (RFC 7946) allows any of these types * at the root level: Point, LineString, Polygon, MultiPoint, MultiLineString, * MultiPolygon, GeometryCollection, Feature, or FeatureCollection. */ STRICT = "strict", } /** * A class for validating GeoJSON content data. * * This validator parses JSON from buffer data and validates it against * the GeoJSON specification schema (geojson.schema.json), ensuring proper * structure and types for all GeoJSON objects including Feature, * FeatureCollection, and all geometry types. * * @internal */ export class GeojsonValidator implements Validator { async validateObject( uri: string, input: Buffer, context: ValidationContext ): Promise { // Parse the JSON from the buffer let geojsonObject: any; try { const jsonString = input.toString("utf-8"); geojsonObject = JSON.parse(jsonString); } catch (error) { const message = `Invalid JSON in GeoJSON file: ${error}`; const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( uri, message ); context.addIssue(issue); return false; } // Validate the GeoJSON structure using consumer mode by default // Consumer mode is appropriate for 3D Tiles as it expects FeatureCollections const result = await GeojsonValidator.validateGeojsonObject( uri, geojsonObject, context, GeojsonValidationMode.CONSUMER ); return result; } /** * Validates a GeoJSON object against the GeoJSON specification * * @param path - The path for ValidationIssue instances * @param geojson - The GeoJSON object to validate * @param context - The ValidationContext that any issues will be added to * @param mode - The validation mode to use (consumer or strict) * @returns Whether the GeoJSON object was valid */ static async validateGeojsonObject( path: string, geojson: any, context: ValidationContext, mode: GeojsonValidationMode = GeojsonValidationMode.CONSUMER ): Promise { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "geojson", geojson, context)) { return false; } // Validate required 'type' property if ( !BasicValidator.validateString( path + "/type", "type", geojson.type, context ) ) { return false; } // Validate based on GeoJSON type and validation mode let validTypes: string[]; if (mode === GeojsonValidationMode.CONSUMER) { // Consumer mode: Only FeatureCollection is allowed at root level // This is appropriate for web mapping applications and most GeoJSON consumers validTypes = ["FeatureCollection"]; } else { // Strict mode: All valid GeoJSON types are allowed at root level // This follows the official GeoJSON specification (RFC 7946) validTypes = [ "Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", "MultiPolygon", "GeometryCollection", "Feature", "FeatureCollection", ]; } if ( !BasicValidator.validateEnum( path + "/type", "type", geojson.type, validTypes, context ) ) { return false; } // Validate based on GeoJSON type switch (geojson.type) { case "Point": return GeojsonValidator.validatePoint(path, geojson, context); case "LineString": return GeojsonValidator.validateLineString(path, geojson, context); case "Polygon": return GeojsonValidator.validatePolygon(path, geojson, context); case "MultiPoint": return GeojsonValidator.validateMultiPoint(path, geojson, context); case "MultiLineString": return GeojsonValidator.validateMultiLineString(path, geojson, context); case "MultiPolygon": return GeojsonValidator.validateMultiPolygon(path, geojson, context); case "GeometryCollection": return GeojsonValidator.validateGeometryCollection( path, geojson, context ); case "Feature": return GeojsonValidator.validateFeature(path, geojson, context); case "FeatureCollection": return GeojsonValidator.validateFeatureCollection( path, geojson, context ); default: { // This should not be reached due to validateEnum above, but kept for safety const message = `Invalid GeoJSON type: ${ geojson.type }. Must be one of: ${validTypes.join(", ")}`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); return false; } } } /** * Validates coordinates array with minimum items requirement */ private static validateCoordinatesArray( path: string, coordinates: any, minItems: number, context: ValidationContext ): boolean { if ( !BasicValidator.validateArray( path, "coordinates", coordinates, minItems, undefined, undefined, context ) ) { return false; } return true; } /** * Validates a position array (array of numbers with at least 2 items) */ private static validatePosition( path: string, position: any, context: ValidationContext ): boolean { if ( !GeojsonValidator.validateCoordinatesArray(path, position, 2, context) ) { return false; } for (let i = 0; i < position.length; i++) { if ( !BasicValidator.validateNumber( path + `[${i}]`, `coordinate ${i}`, position[i], context ) ) { return false; } } return true; } /** * Validates optional bbox property */ private static validateBbox( path: string, bbox: any, context: ValidationContext ): boolean { if (!defined(bbox)) { return true; // bbox is optional } if ( !GeojsonValidator.validateCoordinatesArray( path + "/bbox", bbox, 4, context ) ) { return false; } for (let i = 0; i < bbox.length; i++) { if ( !BasicValidator.validateNumber( path + `/bbox[${i}]`, `bbox coordinate ${i}`, bbox[i], context ) ) { return false; } } return true; } /** * Validates a Point geometry according to the GeoJSON schema */ private static validatePoint( path: string, point: any, context: ValidationContext ): boolean { let result = true; // Validate required type property (must be "Point") if ( !BasicValidator.validateString( path + "/type", "type", point.type, context ) ) { result = false; } else if (point.type !== "Point") { const message = `Point type must be "Point", but was "${point.type}"`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); result = false; } // Validate required coordinates if (!defined(point.coordinates)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/coordinates", "coordinates" ); context.addIssue(issue); result = false; } else if ( !GeojsonValidator.validatePosition( path + "/coordinates", point.coordinates, context ) ) { result = false; } // Validate optional bbox if (!GeojsonValidator.validateBbox(path, point.bbox, context)) { result = false; } return result; } /** * Validates a LineString geometry according to the GeoJSON schema */ private static validateLineString( path: string, lineString: any, context: ValidationContext ): boolean { let result = true; // Validate required type property (must be "LineString") if ( !BasicValidator.validateString( path + "/type", "type", lineString.type, context ) ) { result = false; } else if (lineString.type !== "LineString") { const message = `LineString type must be "LineString", but was "${lineString.type}"`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); result = false; } // Validate required coordinates if (!defined(lineString.coordinates)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/coordinates", "coordinates" ); context.addIssue(issue); result = false; } else if ( !GeojsonValidator.validateCoordinatesArray( path + "/coordinates", lineString.coordinates, 2, context ) ) { result = false; } else { for (let i = 0; i < lineString.coordinates.length; i++) { if ( !GeojsonValidator.validatePosition( path + `/coordinates[${i}]`, lineString.coordinates[i], context ) ) { result = false; } } } // Validate optional bbox if (!GeojsonValidator.validateBbox(path, lineString.bbox, context)) { result = false; } return result; } /** * Validates a Polygon geometry according to the GeoJSON schema */ private static validatePolygon( path: string, polygon: any, context: ValidationContext ): boolean { let result = true; // Validate required type property (must be "Polygon") if ( !BasicValidator.validateString( path + "/type", "type", polygon.type, context ) ) { result = false; } else if (polygon.type !== "Polygon") { const message = `Polygon type must be "Polygon", but was "${polygon.type}"`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); result = false; } // Validate required coordinates if (!defined(polygon.coordinates)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/coordinates", "coordinates" ); context.addIssue(issue); result = false; } else if ( !BasicValidator.validateArray( path + "/coordinates", "coordinates", polygon.coordinates, undefined, undefined, undefined, context ) ) { result = false; } else { for (let i = 0; i < polygon.coordinates.length; i++) { const ringPath = path + `/coordinates[${i}]`; if ( !GeojsonValidator.validateCoordinatesArray( ringPath, polygon.coordinates[i], 4, context ) ) { result = false; } else { for (let j = 0; j < polygon.coordinates[i].length; j++) { if ( !GeojsonValidator.validatePosition( ringPath + `[${j}]`, polygon.coordinates[i][j], context ) ) { result = false; } } } } } // Validate optional bbox if (!GeojsonValidator.validateBbox(path, polygon.bbox, context)) { result = false; } return result; } /** * Validates a MultiPoint geometry according to the GeoJSON schema */ private static validateMultiPoint( path: string, multiPoint: any, context: ValidationContext ): boolean { let result = true; // Validate required type property (must be "MultiPoint") if ( !BasicValidator.validateString( path + "/type", "type", multiPoint.type, context ) ) { result = false; } else if (multiPoint.type !== "MultiPoint") { const message = `MultiPoint type must be "MultiPoint", but was "${multiPoint.type}"`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); result = false; } // Validate required coordinates if (!defined(multiPoint.coordinates)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/coordinates", "coordinates" ); context.addIssue(issue); result = false; } else if ( !BasicValidator.validateArray( path + "/coordinates", "coordinates", multiPoint.coordinates, undefined, undefined, undefined, context ) ) { result = false; } else { for (let i = 0; i < multiPoint.coordinates.length; i++) { if ( !GeojsonValidator.validatePosition( path + `/coordinates[${i}]`, multiPoint.coordinates[i], context ) ) { result = false; } } } // Validate optional bbox if (!GeojsonValidator.validateBbox(path, multiPoint.bbox, context)) { result = false; } return result; } /** * Validates a MultiLineString geometry according to the GeoJSON schema */ private static validateMultiLineString( path: string, multiLineString: any, context: ValidationContext ): boolean { let result = true; // Validate required type property (must be "MultiLineString") if ( !BasicValidator.validateString( path + "/type", "type", multiLineString.type, context ) ) { result = false; } else if (multiLineString.type !== "MultiLineString") { const message = `MultiLineString type must be "MultiLineString", but was "${multiLineString.type}"`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); result = false; } // Validate required coordinates if (!defined(multiLineString.coordinates)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/coordinates", "coordinates" ); context.addIssue(issue); result = false; } else if ( !BasicValidator.validateArray( path + "/coordinates", "coordinates", multiLineString.coordinates, undefined, undefined, undefined, context ) ) { result = false; } else { for (let i = 0; i < multiLineString.coordinates.length; i++) { const lineStringPath = path + `/coordinates[${i}]`; if ( !GeojsonValidator.validateCoordinatesArray( lineStringPath, multiLineString.coordinates[i], 2, context ) ) { result = false; } else { for (let j = 0; j < multiLineString.coordinates[i].length; j++) { if ( !GeojsonValidator.validatePosition( lineStringPath + `[${j}]`, multiLineString.coordinates[i][j], context ) ) { result = false; } } } } } // Validate optional bbox if (!GeojsonValidator.validateBbox(path, multiLineString.bbox, context)) { result = false; } return result; } /** * Validates a MultiPolygon geometry according to the GeoJSON schema */ private static validateMultiPolygon( path: string, multiPolygon: any, context: ValidationContext ): boolean { let result = true; // Validate required type property (must be "MultiPolygon") if ( !BasicValidator.validateString( path + "/type", "type", multiPolygon.type, context ) ) { result = false; } else if (multiPolygon.type !== "MultiPolygon") { const message = `MultiPolygon type must be "MultiPolygon", but was "${multiPolygon.type}"`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); result = false; } // Validate required coordinates if (!defined(multiPolygon.coordinates)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/coordinates", "coordinates" ); context.addIssue(issue); result = false; } else if ( !BasicValidator.validateArray( path + "/coordinates", "coordinates", multiPolygon.coordinates, undefined, undefined, undefined, context ) ) { result = false; } else { for (let i = 0; i < multiPolygon.coordinates.length; i++) { const polygonPath = path + `/coordinates[${i}]`; if ( !BasicValidator.validateArray( polygonPath, "polygon", multiPolygon.coordinates[i], undefined, undefined, undefined, context ) ) { result = false; } else { for (let j = 0; j < multiPolygon.coordinates[i].length; j++) { const ringPath = polygonPath + `[${j}]`; if ( !GeojsonValidator.validateCoordinatesArray( ringPath, multiPolygon.coordinates[i][j], 4, context ) ) { result = false; } else { for (let k = 0; k < multiPolygon.coordinates[i][j].length; k++) { if ( !GeojsonValidator.validatePosition( ringPath + `[${k}]`, multiPolygon.coordinates[i][j][k], context ) ) { result = false; } } } } } } } // Validate optional bbox if (!GeojsonValidator.validateBbox(path, multiPolygon.bbox, context)) { result = false; } return result; } /** * Validates a GeometryCollection according to the GeoJSON schema */ private static validateGeometryCollection( path: string, geometryCollection: any, context: ValidationContext ): boolean { let result = true; // Validate required type property (must be "GeometryCollection") if ( !BasicValidator.validateString( path + "/type", "type", geometryCollection.type, context ) ) { result = false; } else if (geometryCollection.type !== "GeometryCollection") { const message = `GeometryCollection type must be "GeometryCollection", but was "${geometryCollection.type}"`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); result = false; } // Validate required geometries if (!defined(geometryCollection.geometries)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/geometries", "geometries" ); context.addIssue(issue); result = false; } else if ( !BasicValidator.validateArray( path + "/geometries", "geometries", geometryCollection.geometries, undefined, undefined, undefined, context ) ) { result = false; } else { for (let i = 0; i < geometryCollection.geometries.length; i++) { const geometryPath = path + `/geometries[${i}]`; if ( !GeojsonValidator.validateGeometry( geometryPath, geometryCollection.geometries[i], context ) ) { result = false; } } } // Validate optional bbox if ( !GeojsonValidator.validateBbox(path, geometryCollection.bbox, context) ) { result = false; } return result; } /** * Validates a properties object (used within Feature) */ private static validateProperties( path: string, properties: any, context: ValidationContext ): boolean { if (properties === null) { return true; // null properties are allowed in Features } if ( !BasicValidator.validateObject(path, "properties", properties, context) ) { return false; } return true; } /** * Validates a geometry object (used within GeometryCollection and Feature) */ private static validateGeometry( path: string, geometry: any, context: ValidationContext ): boolean { if (geometry === null) { return true; // null geometry is allowed in Features } if (!BasicValidator.validateObject(path, "geometry", geometry, context)) { return false; } if ( !BasicValidator.validateString( path + "/type", "type", geometry.type, context ) ) { return false; } // Validate geometry type against allowed values const type = geometry.type; const validGeometryTypes = [ "Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", "MultiPolygon", ]; // Special handling for GeometryCollection to provide a more specific error message if (type === "GeometryCollection") { const message = `GeometryCollection is not supported by the MAXAR_content_geojson extension. Supported geometry types are: ${validGeometryTypes.join( ", " )}`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); return false; } if ( !BasicValidator.validateEnum( path + "/type", "type", type, validGeometryTypes, context ) ) { return false; } switch (type) { case "Point": return GeojsonValidator.validatePoint(path, geometry, context); case "LineString": return GeojsonValidator.validateLineString(path, geometry, context); case "Polygon": return GeojsonValidator.validatePolygon(path, geometry, context); case "MultiPoint": return GeojsonValidator.validateMultiPoint(path, geometry, context); case "MultiLineString": return GeojsonValidator.validateMultiLineString( path, geometry, context ); case "MultiPolygon": return GeojsonValidator.validateMultiPolygon(path, geometry, context); default: { // This should not be reached due to validateEnum above, but kept for safety const message = `Invalid geometry type: ${type}. Must be one of: ${validGeometryTypes.join( ", " )}`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); return false; } } } /** * Validates a Feature object according to the GeoJSON schema */ private static validateFeature( path: string, feature: any, context: ValidationContext ): boolean { let result = true; // Validate required type property (must be "Feature") if ( !BasicValidator.validateString( path + "/type", "type", feature.type, context ) ) { result = false; } else if (feature.type !== "Feature") { const message = `Feature type must be "Feature", but was "${feature.type}"`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); result = false; } // Validate required properties (can be null or object) if (!defined(feature.properties)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/properties", "properties" ); context.addIssue(issue); result = false; } else if ( !GeojsonValidator.validateProperties( path + "/properties", feature.properties, context ) ) { result = false; } // Validate required geometry (can be null or geometry object) if (!defined(feature.geometry)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/geometry", "geometry" ); context.addIssue(issue); result = false; } else if ( !GeojsonValidator.validateGeometry( path + "/geometry", feature.geometry, context ) ) { result = false; } // Validate optional id (must be string or number if present) if (defined(feature.id)) { if (typeof feature.id !== "string" && typeof feature.id !== "number") { const issue = JsonValidationIssues.TYPE_MISMATCH( path + "/id", "id", "string or number", typeof feature.id ); context.addIssue(issue); result = false; } } // Validate optional bbox if (!GeojsonValidator.validateBbox(path, feature.bbox, context)) { result = false; } return result; } /** * Validates a FeatureCollection object according to the GeoJSON schema */ private static validateFeatureCollection( path: string, featureCollection: any, context: ValidationContext ): boolean { let result = true; // Validate required type property (must be "FeatureCollection") if ( !BasicValidator.validateString( path + "/type", "type", featureCollection.type, context ) ) { result = false; } else if (featureCollection.type !== "FeatureCollection") { const message = `FeatureCollection type must be "FeatureCollection", but was "${featureCollection.type}"`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST( path + "/type", message ); context.addIssue(issue); result = false; } // Validate required features array if (!defined(featureCollection.features)) { const issue = JsonValidationIssues.PROPERTY_MISSING( path + "/features", "features" ); context.addIssue(issue); result = false; } else if ( !BasicValidator.validateArray( path + "/features", "features", featureCollection.features, undefined, undefined, undefined, context ) ) { result = false; } else { // Validate each feature in the collection for (let i = 0; i < featureCollection.features.length; i++) { const featurePath = path + `/features[${i}]`; const feature = featureCollection.features[i]; if ( !BasicValidator.validateObject( featurePath, "feature", feature, context ) ) { result = false; continue; } if (!GeojsonValidator.validateFeature(featurePath, feature, context)) { result = false; } } } // Validate optional bbox if (!GeojsonValidator.validateBbox(path, featureCollection.bbox, context)) { result = false; } return result; } } ================================================ FILE: src/tileFormats/GltfValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Validator } from "../validation/Validator"; import { ValidationContext } from "../validation/ValidationContext"; import { ValidationIssue } from "../validation/ValidationIssue"; import { ContentValidationIssues } from "../issues/ContentValidationIssues"; import { GltfExtensionValidators } from "../validation/gltf/GltfExtensionValidators"; // eslint-disable-next-line @typescript-eslint/no-var-requires const validator = require("gltf-validator"); /** * A thin wrapper around the `gltf-validator`, implementing the * `Validator` interface for glTF- and GLB data that is given * in a Buffer. * * @internal */ export class GltfValidator implements Validator { /** * The maximum number of issues that should be reported by * the glTF validator. For large glTF assets that contain * "completely invalid" data, a large number of issues * can cause out-of-memory errors. * See https://github.com/CesiumGS/3d-tiles-validator/issues/290 */ private static readonly MAX_ISSUES = 1000; /** * Creates a `ValidationIssue` object for the given 'message' object * that appears in the output of the glTF validator. * * @param gltfMessage - The glTF validator message * @returns The `ValidationIssue` */ private static createValidationIssueFromGltfMessage( gltfMessage: any ): ValidationIssue { const path = gltfMessage.pointer; const message = gltfMessage.message; if (gltfMessage.severity == 0) { const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( path, message ); return issue; } if (gltfMessage.severity == 1) { const issue = ContentValidationIssues.CONTENT_VALIDATION_WARNING( path, message ); return issue; } const issue = ContentValidationIssues.CONTENT_VALIDATION_INFO( path, message ); return issue; } /** * The data that is given as the `input` to `validateObject` might * contain padding bytes (for example, when it was extracted * from a B3DM file). * * If the given input is GLB data, then this method will strip * any padding bytes, by restricting the buffer to the length * that was obtained from the GLB header. * * If the given data is not GLB data (for example, it might be * glTF JSON data!), then the buffer is returned, unmodified. * * @param input - The buffer, including possible padding * @returns The resulting buffer */ private static stripPadding(input: Buffer): Buffer { // Handle the cases that indicate that the data is // not GLB data. These cases do actually indicate // errors, but will be handled by the glTF validator. if (input.length < 12) { return input; } const magic = input.readInt32LE(0); if (magic !== 0x46546c67) { return input; } const length = input.readInt32LE(8); if (length >= input.length) { return input; } const inputWithoutPadding = input.subarray(0, length); return inputWithoutPadding; } async validateObject( uri: string, input: Buffer, context: ValidationContext ): Promise { const inputWithoutPadding = GltfValidator.stripPadding(input); const resourceResolver = context.getResourceResolver(); let gltfResult = undefined; try { gltfResult = await validator.validateBytes(inputWithoutPadding, { uri: uri, maxIssues: GltfValidator.MAX_ISSUES, externalResourceFunction: (gltfUri: string) => { const resolvedDataPromise = resourceResolver.resolveData(gltfUri); return resolvedDataPromise.then((resolvedData: any) => { if (!defined(resolvedData)) { throw "Could not resolve data from " + gltfUri; } return resolvedData; }); }, }); } catch (error) { const message = `Content ${uri} caused internal validation error: ${error}`; const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( uri, message ); context.addIssue(issue); return false; } // If there are any errors, then summarize ALL issues from the glTF // validation as 'internal issues' in a CONTENT_VALIDATION_ERROR if (gltfResult.issues.numErrors > 0) { const path = uri; const message = `Content ${uri} caused validation errors`; const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( path, message ); for (const gltfMessage of gltfResult.issues.messages) { //console.log(gltfMessage); const cause = GltfValidator.createValidationIssueFromGltfMessage(gltfMessage); issue.addCause(cause); } context.addIssue(issue); // Consider the object to be invalid return false; } // If there are any warnings, then summarize them in a // CONTENT_VALIDATION_WARNING, but still consider the // object to be valid. if (gltfResult.issues.numWarnings > 0) { const path = uri; const message = `Content ${uri} caused validation warnings`; const issue = ContentValidationIssues.CONTENT_VALIDATION_WARNING( path, message ); for (const gltfMessage of gltfResult.issues.messages) { //console.log(gltfMessage); const cause = GltfValidator.createValidationIssueFromGltfMessage(gltfMessage); issue.addCause(cause); } context.addIssue(issue); } else if (gltfResult.issues.numInfos > 0) { // If there are no warnings, but infos, then summarize them in a // CONTENT_VALIDATION_INFO, but still consider the // object to be valid. const path = uri; const message = `Content ${uri} caused validation infos`; const issue = ContentValidationIssues.CONTENT_VALIDATION_INFO( path, message ); for (const gltfMessage of gltfResult.issues.messages) { const cause = GltfValidator.createValidationIssueFromGltfMessage(gltfMessage); issue.addCause(cause); } context.addIssue(issue); } // When the glTF itself is considered to be valid, then perform // the validation of the Cesium glTF metadata extensions const extensionsValid = await GltfExtensionValidators.validateGltfExtensions(uri, input, context); if (!extensionsValid) { return false; } return true; } } ================================================ FILE: src/tileFormats/I3dmValidator.ts ================================================ // This was, to some extent, "ported" (or at least "inspired") from // https://github.com/CesiumGS/3d-tiles-validator/blob/e84202480eb6572383008076150c8e52c99af3c3/validator/lib/validateI3dm.js // It still contains legacy elements that may be cleaned up at some point. import path from "path"; import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../validation/ValidationContext"; import { Validator } from "../validation/Validator"; import { GltfValidator } from "./GltfValidator"; import { TileFormatValidator } from "./TileFormatValidator"; import { IoValidationIssues } from "../issues/IoValidationIssue"; import { BinaryValidationIssues } from "../issues/BinaryValidationIssues"; import { ContentValidationIssues } from "../issues/ContentValidationIssues"; import { validateFeatureTable } from "./legacy/validateFeatureTable"; import { validateBatchTable } from "./legacy/validateBatchTable"; const featureTableSemantics = { POSITION: { global: false, type: "VEC3", componentType: "FLOAT", }, POSITION_QUANTIZED: { global: false, type: "VEC3", componentType: "UNSIGNED_SHORT", }, NORMAL_UP: { global: false, type: "VEC3", componentType: "FLOAT", }, NORMAL_RIGHT: { global: false, type: "VEC3", componentType: "FLOAT", }, NORMAL_UP_OCT32P: { global: false, type: "VEC2", componentType: "UNSIGNED_SHORT", }, NORMAL_RIGHT_OCT32P: { global: false, type: "VEC2", componentType: "UNSIGNED_SHORT", }, SCALE: { global: false, type: "SCALAR", componentType: "FLOAT", }, SCALE_NON_UNIFORM: { global: false, type: "VEC3", componentType: "FLOAT", }, BATCH_ID: { global: false, type: "SCALAR", componentType: "UNSIGNED_SHORT", componentTypeOptions: ["UNSIGNED_BYTE", "UNSIGNED_SHORT", "UNSIGNED_INT"], }, INSTANCES_LENGTH: { global: true, type: "SCALAR", componentType: "UNSIGNED_INT", }, RTC_CENTER: { global: true, type: "VEC3", componentType: "FLOAT", }, QUANTIZED_VOLUME_OFFSET: { global: true, type: "VEC3", componentType: "FLOAT", }, QUANTIZED_VOLUME_SCALE: { global: true, type: "VEC3", componentType: "FLOAT", }, EAST_NORTH_UP: { global: true, type: "boolean", }, }; /** * A class that can perform validation of I3DM data that is * given as a Buffer. * * @internal */ export class I3dmValidator implements Validator { async validateObject( uri: string, input: Buffer, context: ValidationContext ): Promise { const headerByteLength = 32; if ( !TileFormatValidator.validateHeader( uri, input, headerByteLength, "i3dm", context ) ) { return false; } const gltfFormat = input.readUInt32LE(28); if (gltfFormat > 1) { const issue = BinaryValidationIssues.BINARY_INVALID_VALUE( uri, "gltfFormat", "<=1", gltfFormat ); context.addIssue(issue); return false; } const hasEmbeddedGlb = gltfFormat === 1; const binaryTableDataState = TileFormatValidator.extractBinaryTableData( uri, input, headerByteLength, hasEmbeddedGlb, context ); const binaryTableData = binaryTableDataState.binaryTableData; if (!defined(binaryTableData)) { return false; } const featureTableJson = binaryTableData.featureTableJson; const featureTableBinary = binaryTableData.featureTableBinary; const batchTableJson = binaryTableData.batchTableJson; const batchTableBinary = binaryTableData.batchTableBinary; const glbData = binaryTableData.glbData; let result = binaryTableDataState.isValid; const featuresLength = featureTableJson.INSTANCES_LENGTH; if (!defined(featuresLength)) { const message = `Feature table must contain a INSTANCES_LENGTH property.`; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); } if ( !defined(featureTableJson.POSITION) && !defined(featureTableJson.POSITION_QUANTIZED) ) { const message = "Feature table must contain either the POSITION or POSITION_QUANTIZED property."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( defined(featureTableJson.NORMAL_UP) && !defined(featureTableJson.NORMAL_RIGHT) ) { const message = "Feature table property NORMAL_RIGHT is required when NORMAL_UP is present."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( !defined(featureTableJson.NORMAL_UP) && defined(featureTableJson.NORMAL_RIGHT) ) { const message = "Feature table property NORMAL_UP is required when NORMAL_RIGHT is present."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( defined(featureTableJson.NORMAL_UP_OCT32P) && !defined(featureTableJson.NORMAL_RIGHT_OCT32P) ) { const message = "Feature table property NORMAL_RIGHT_OCT32P is required when NORMAL_UP_OCT32P is present."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( !defined(featureTableJson.NORMAL_UP_OCT32P) && defined(featureTableJson.NORMAL_RIGHT_OCT32P) ) { const message = "Feature table property NORMAL_UP_OCT32P is required when NORMAL_RIGHT_OCT32P is present."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( defined(featureTableJson.POSITION_QUANTIZED) && (!defined(featureTableJson.QUANTIZED_VOLUME_OFFSET) || !defined(featureTableJson.QUANTIZED_VOLUME_SCALE)) ) { const message = "Feature table properties QUANTIZED_VOLUME_OFFSET and QUANTIZED_VOLUME_SCALE are required when POSITION_QUANTIZED is present."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } const featureTableMessage = validateFeatureTable( featureTableJson, featureTableBinary, featuresLength, featureTableSemantics ); if (defined(featureTableMessage)) { const issue = ContentValidationIssues.CONTENT_JSON_INVALID( uri, featureTableMessage ); context.addIssue(issue); result = false; } const batchTableMessage = validateBatchTable( batchTableJson, batchTableBinary, featuresLength ); if (defined(batchTableMessage)) { const issue = ContentValidationIssues.CONTENT_JSON_INVALID( uri, batchTableMessage ); context.addIssue(issue); result = false; } // If the GLB data was embedded, validate it directly if (hasEmbeddedGlb) { const gltfValidator = new GltfValidator(); const gltfResult = await gltfValidator.validateObject( uri, glbData, context ); if (!gltfResult) { result = false; } } else { // The GLB data was a URI, as indicated by `gltfFormat === 0`. // The padding bytes in this case should be 0x20 (space) bytes, // so issue a warning if the buffer contains 0x00 (zero) bytes. if (glbData.includes("\0")) { const message = `The field containing the URI of the glTF asset contained ` + `0x00 (zero)-bytes, but should only be padded with 0x20 (space) bytes`; const issue = ContentValidationIssues.CONTENT_VALIDATION_WARNING( uri, message ); context.addIssue(issue); } // Create the URI from the buffer, and remove any bytes (zeros // or trailing) that may be introduced by padding. const glbUri = glbData.toString().replace(/\0/g, "").trim(); const resourceResolver = context.getResourceResolver(); const resolvedGlbData = await resourceResolver.resolveData(glbUri); if (!defined(resolvedGlbData)) { const message = `Could not resolve GLB URI ${glbUri} from I3DM`; const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( uri, message ); context.addIssue(issue); result = false; } else { // Create a new context to collect the issues that are // found in the data. If there are issues, then they // will be stored as the 'internal issues' of a // single content validation issue. const glbDirectory = path.dirname(glbUri); const derivedContext = context.deriveFromUri(glbDirectory); const gltfValidator = new GltfValidator(); const gltfResult = await gltfValidator.validateObject( uri, resolvedGlbData, derivedContext ); if (!gltfResult) { result = false; } const derivedResult = derivedContext.getResult(); const issue = ContentValidationIssues.createForContent( uri, derivedResult ); if (issue) { context.addIssue(issue); } return result; } } return result; } } ================================================ FILE: src/tileFormats/PntsValidator.ts ================================================ // This was, to some extent, "ported" (or at least "inspired") from // https://github.com/CesiumGS/3d-tiles-validator/blob/e84202480eb6572383008076150c8e52c99af3c3/validator/lib/validatePnts.js // It still contains legacy elements that may be cleaned up at some point. import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "../validation/ValidationContext"; import { Validator } from "../validation/Validator"; import { TileFormatValidator } from "./TileFormatValidator"; import { IoValidationIssues } from "../issues/IoValidationIssue"; import { ContentValidationIssues } from "../issues/ContentValidationIssues"; import { validateBatchTable } from "./legacy/validateBatchTable"; import { validateFeatureTable } from "./legacy/validateFeatureTable"; const featureTableSemantics = { POSITION: { global: false, type: "VEC3", componentType: "FLOAT", }, POSITION_QUANTIZED: { global: false, type: "VEC3", componentType: "UNSIGNED_SHORT", }, RGBA: { global: false, type: "VEC4", componentType: "UNSIGNED_BYTE", }, RGB: { global: false, type: "VEC3", componentType: "UNSIGNED_BYTE", }, RGB565: { global: false, type: "SCALAR", componentType: "UNSIGNED_SHORT", }, NORMAL: { global: false, type: "VEC3", componentType: "FLOAT", }, NORMAL_OCT16P: { global: false, type: "VEC2", componentType: "UNSIGNED_BYTE", }, BATCH_ID: { global: false, type: "SCALAR", componentType: "UNSIGNED_SHORT", componentTypeOptions: ["UNSIGNED_BYTE", "UNSIGNED_SHORT", "UNSIGNED_INT"], }, POINTS_LENGTH: { global: true, type: "SCALAR", componentType: "UNSIGNED_INT", }, RTC_CENTER: { global: true, type: "VEC3", componentType: "FLOAT", }, QUANTIZED_VOLUME_OFFSET: { global: true, type: "VEC3", componentType: "FLOAT", }, QUANTIZED_VOLUME_SCALE: { global: true, type: "VEC3", componentType: "FLOAT", }, CONSTANT_RGBA: { global: true, type: "VEC4", componentType: "UNSIGNED_BYTE", }, BATCH_LENGTH: { global: true, type: "SCALAR", componentType: "UNSIGNED_INT", }, }; /** * A class that can perform validation of PNTS data that is * given as a Buffer. * * @internal */ export class PntsValidator implements Validator { async validateObject( uri: string, input: Buffer, context: ValidationContext ): Promise { const headerByteLength = 28; if ( !TileFormatValidator.validateHeader( uri, input, headerByteLength, "pnts", context ) ) { return false; } const binaryTableDataState = TileFormatValidator.extractBinaryTableData( uri, input, headerByteLength, false, context ); const binaryTableData = binaryTableDataState.binaryTableData; if (!defined(binaryTableData)) { return false; } const featureTableJson = binaryTableData.featureTableJson; const featureTableBinary = binaryTableData.featureTableBinary; const batchTableJson = binaryTableData.batchTableJson; const batchTableBinary = binaryTableData.batchTableBinary; let result = binaryTableDataState.isValid; const batchLength = defaultValue(featureTableJson.BATCH_LENGTH, 0); const pointsLength = featureTableJson.POINTS_LENGTH; if (!defined(pointsLength)) { const message = "Feature table must contain a POINTS_LENGTH property."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( !defined(featureTableJson.POSITION) && !defined(featureTableJson.POSITION_QUANTIZED) ) { const message = "Feature table must contain either the POSITION or POSITION_QUANTIZED property."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( defined(featureTableJson.POSITION_QUANTIZED) && (!defined(featureTableJson.QUANTIZED_VOLUME_OFFSET) || !defined(featureTableJson.QUANTIZED_VOLUME_SCALE)) ) { const message = "Feature table properties QUANTIZED_VOLUME_OFFSET and QUANTIZED_VOLUME_SCALE are required when POSITION_QUANTIZED is present."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( defined(featureTableJson.BATCH_ID) && !defined(featureTableJson.BATCH_LENGTH) ) { const message = "Feature table property BATCH_LENGTH is required when BATCH_ID is present."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( !defined(featureTableJson.BATCH_ID) && defined(featureTableJson.BATCH_LENGTH) ) { const message = "Feature table property BATCH_ID is required when BATCH_LENGTH is present."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if (batchLength > pointsLength) { const message = "Feature table property BATCH_LENGTH must be less than or equal to POINTS_LENGTH."; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); result = false; } if ( defined(featureTableJson.BATCH_ID) && !hasDracoBatchIds(featureTableJson) ) { /* TODO Revive this part of the validation const featureTable = new Cesium3DTileFeatureTable(featureTableJson, featureTableBinary); featureTable.featuresLength = pointsLength; const componentDatatype = ComponentDatatype.fromName(defaultValue(featureTableJson.BATCH_ID.componentType, 'UNSIGNED_SHORT')); const batchIds = featureTable.getPropertyArray('BATCH_ID', componentDatatype, 1); const length = batchIds.length; for (let i = 0; i < length; i++) { if (batchIds[i] >= featureTableJson.BATCH_LENGTH) { const message = 'All the BATCH_IDs must have values less than feature table property BATCH_LENGTH.'; const issue = IoValidationIssues.JSON_PARSE_ERROR(uri, message); context.addIssue(issue); } } */ } const featureTableMessage = validateFeatureTable( featureTableJson, featureTableBinary, pointsLength, featureTableSemantics ); if (defined(featureTableMessage)) { const issue = ContentValidationIssues.CONTENT_JSON_INVALID( uri, featureTableMessage ); context.addIssue(issue); result = false; } // If the BATCH_ID semantic is defined, the Batch Table stores metadata // for each batchId, and the length of the Batch Table arrays will // equal BATCH_LENGTH. Otherwise, it will store per-point metadata, // and the length will be POINTS_LENGTH. let batchTableArraysLength = pointsLength; if (defined(featureTableJson.BATCH_ID)) { batchTableArraysLength = batchLength; } const batchTableMessage = validateBatchTable( batchTableJson, batchTableBinary, batchTableArraysLength ); if (defined(batchTableMessage)) { const issue = ContentValidationIssues.CONTENT_JSON_INVALID( uri, batchTableMessage ); context.addIssue(issue); result = false; } return result; } } function hasDracoBatchIds(featureTableJson: any) { const extensions = featureTableJson.extensions; if (defined(extensions)) { const dracoExtension = extensions["3DTILES_draco_point_compression"]; if (defined(dracoExtension)) { return defined(dracoExtension.properties.BATCH_ID); } } return false; } ================================================ FILE: src/tileFormats/TileFormatValidator.ts ================================================ import { Buffers } from "3d-tiles-tools"; import { ValidationContext } from "../validation/ValidationContext"; import { BinaryValidationIssues } from "../issues/BinaryValidationIssues"; import { IoValidationIssues } from "../issues/IoValidationIssue"; /** * An interface describing the table data that was read from * a tile content. * * @internal */ export interface BinaryTableData { featureTableJson: any; featureTableBinary: Buffer; batchTableJson: any; batchTableBinary: Buffer; glbData: Buffer; } /** * Methods to validate and extract the binary table data from * tile content. * * @internal */ export class TileFormatValidator { /** * Validates the common part of all tile format headers. * * This validates that the given input has at least the * given header byte length, and whether the 'magic', * and 'byteLength' fields of the header have the expected * values. (The 'version' is validated to always be '1') * * @param path - The path for `ValidationIssue` instances * @param input - The input buffer * @param headerByteLength - The header byte length * @param expectedMagic - The expected magic value * @param context - The `ValidationContext` * @returns Whether the header was valid */ static validateHeader( path: string, input: Buffer, headerByteLength: number, expectedMagic: string, context: ValidationContext ) { if (input.length < headerByteLength) { const message = `The input must have at least ${headerByteLength} bytes, ` + `but only has ${input.length} bytes`; const issue = BinaryValidationIssues.BINARY_INVALID(path, message); context.addIssue(issue); return false; } const magic = input.toString("utf8", 0, 4); const version = input.readUInt32LE(4); const byteLength = input.readUInt32LE(8); if (magic !== expectedMagic) { const issue = BinaryValidationIssues.BINARY_INVALID_VALUE( path, "magic", expectedMagic, magic ); context.addIssue(issue); return false; } if (version !== 1) { const issue = BinaryValidationIssues.BINARY_INVALID_VALUE( path, "version", 1, version ); context.addIssue(issue); return false; } if (byteLength !== input.length) { const issue = BinaryValidationIssues.BINARY_INVALID_LENGTH( path, "content", byteLength, input.length ); context.addIssue(issue); return false; } return true; } /** * Extracts the binary table data from the given tile content, * if it is valid. * * This is used for B3DM, I3DM and PNTS tile content. * * This assumes that the length of the given buffer has already * been validated to be sufficient for the respective header * data. * * It validates the feature- and batch table JSON- and binary * offsets, extracts the respective JSON- and binary data, * parses the JSON data, and returns the result. * * If no valid binary table data can be extracted from the * given input, then the `binaryTableData` of the returned * object will be `undefined`, and `isValid` will be `false`. * * If valid binary table data CAN be extracted, but one of * the offsets does not meet the alignment requirements from * the specification, then the appropriate validation issue will * be added to the given context, and the `isValid` property of * the returned object will be `false`. * * @param path - The path for `ValidationIssue` instances * @param input - The input buffer * @param headerByteLength - The length of the tile format header * @param hasEmbeddedGlb - Whether the input is expected to have * embedded GLB data. This is `true` for B3DM, `false` for PNTS, * and `gltfFormat===1` for I3DM. * @param context - The `ValidationContext` * @returns The `BinaryTableData` and its validity status */ static extractBinaryTableData( path: string, input: Buffer, headerByteLength: number, hasEmbeddedGlb: boolean, context: ValidationContext ): { binaryTableData: BinaryTableData | undefined; isValid: boolean } { const byteLength = input.readUInt32LE(8); const featureTableJsonByteLength = input.readUInt32LE(12); const featureTableBinaryByteLength = input.readUInt32LE(16); const batchTableJsonByteLength = input.readUInt32LE(20); const batchTableBinaryByteLength = input.readUInt32LE(24); const featureTableJsonByteOffset = headerByteLength; const featureTableBinaryByteOffset = featureTableJsonByteOffset + featureTableJsonByteLength; const batchTableJsonByteOffset = featureTableBinaryByteOffset + featureTableBinaryByteLength; const batchTableBinaryByteOffset = batchTableJsonByteOffset + batchTableJsonByteLength; const glbByteOffset = batchTableBinaryByteOffset + batchTableBinaryByteLength; const glbByteLength = Math.max(byteLength - glbByteOffset, 0); let isValid = true; if (featureTableBinaryByteOffset % 8 > 0) { const issue = BinaryValidationIssues.BINARY_INVALID_ALIGNMENT_legacy( path, "feature table binary", 8 ); context.addIssue(issue); isValid = false; } if (batchTableJsonByteOffset % 8 > 0) { const issue = BinaryValidationIssues.BINARY_INVALID_ALIGNMENT_legacy( path, "batch table JSON", 8 ); context.addIssue(issue); isValid = false; } if (batchTableBinaryByteOffset % 8 > 0) { const issue = BinaryValidationIssues.BINARY_INVALID_ALIGNMENT_legacy( path, "batch table binary", 8 ); context.addIssue(issue); isValid = false; } if (hasEmbeddedGlb && glbByteOffset % 8 > 0) { const issue = BinaryValidationIssues.BINARY_INVALID_ALIGNMENT_legacy( path, "GLB data", 8 ); context.addIssue(issue); isValid = false; } if (byteLength % 8 > 0) { const issue = BinaryValidationIssues.BINARY_INVALID_ALIGNMENT_legacy( path, "byte length", 8 ); context.addIssue(issue); isValid = false; } const computedByteLength = headerByteLength + featureTableJsonByteLength + featureTableBinaryByteLength + batchTableJsonByteLength + batchTableBinaryByteLength + glbByteLength; if (computedByteLength > byteLength) { const issue = BinaryValidationIssues.BINARY_INVALID_LENGTH( path, "header, feature table, batch table, and GLB", byteLength, computedByteLength ); context.addIssue(issue); return { binaryTableData: undefined, isValid: false, }; } const featureTableJsonBuffer = input.subarray( featureTableJsonByteOffset, featureTableBinaryByteOffset ); const featureTableBinary = input.subarray( featureTableBinaryByteOffset, batchTableJsonByteOffset ); const batchTableJsonBuffer = input.subarray( batchTableJsonByteOffset, batchTableBinaryByteOffset ); const batchTableBinary = input.subarray( batchTableBinaryByteOffset, glbByteOffset ); const glbData = input.subarray( glbByteOffset, glbByteOffset + glbByteLength ); let featureTableJson: any; let batchTableJson: any; try { featureTableJson = Buffers.getJson(featureTableJsonBuffer); } catch (error) { const message = `Could not parse feature table JSON: ${error}`; const issue = IoValidationIssues.JSON_PARSE_ERROR(path, message); context.addIssue(issue); return { binaryTableData: undefined, isValid: false, }; } try { batchTableJson = Buffers.getJson(batchTableJsonBuffer); } catch (error) { const message = `Could not parse batch table JSON: ${error}`; const issue = IoValidationIssues.JSON_PARSE_ERROR(path, message); context.addIssue(issue); return { binaryTableData: undefined, isValid: false, }; } const binaryTableData = { featureTableJson: featureTableJson, featureTableBinary: featureTableBinary, batchTableJson: batchTableJson, batchTableBinary: batchTableBinary, glbData: glbData, }; return { binaryTableData: binaryTableData, isValid: isValid, }; } } ================================================ FILE: src/tileFormats/legacy/utility.ts ================================================ // Ported from https://github.com/CesiumGS/3d-tiles-validator/tree/e84202480eb6572383008076150c8e52c99af3c3 // (Some parts of that state have been omitted here) function typeToComponentsLength(type: string): number | undefined { switch (type) { case "SCALAR": return 1; case "VEC2": return 2; case "VEC3": return 3; case "VEC4": return 4; default: return undefined; } } function componentTypeToByteLength(componentType: string): number | undefined { switch (componentType) { case "BYTE": case "UNSIGNED_BYTE": return 1; case "SHORT": case "UNSIGNED_SHORT": return 2; case "INT": case "UNSIGNED_INT": case "FLOAT": return 4; case "DOUBLE": return 8; default: return undefined; } } export { typeToComponentsLength, componentTypeToByteLength }; ================================================ FILE: src/tileFormats/legacy/validateBatchTable.ts ================================================ // Mostly ported from https://github.com/CesiumGS/3d-tiles-validator/tree/e84202480eb6572383008076150c8e52c99af3c3 import { defined } from "3d-tiles-tools"; import { typeToComponentsLength } from "./utility"; import { componentTypeToByteLength } from "./utility"; /** * Checks if the batch table JSON and batch table binary are valid * * @param batchTableJson - Batch table JSON. * @param batchTableBinary - Batch table binary. * @param featuresLength - The number of features. * @returns An error message if validation fails, otherwise undefined. * * @internal */ function validateBatchTable( batchTableJson: any, batchTableBinary: Buffer, featuresLength: number ): string | undefined { for (const name in batchTableJson) { if (Object.prototype.hasOwnProperty.call(batchTableJson, name)) { if (name === "extensions" || name === "extras") { continue; } if (hasDracoProperty(batchTableJson, name)) { continue; } const property = batchTableJson[name]; const byteOffset = property.byteOffset; if (defined(byteOffset)) { if (typeof byteOffset !== "number") { return `Batch table binary property "${name}" byteOffset must be a number.`; } const componentType = property.componentType; const type = property.type; if (!defined(type)) { return `Batch table binary property "${name}" must have a type.`; } if (!defined(componentType)) { return `Batch table binary property "${name}" must have a componentType.`; } const componentsLength = typeToComponentsLength(type); const componentByteLength = componentTypeToByteLength(componentType); if (!defined(componentsLength)) { return `Batch table binary property "${name}" has invalid type "${type}".`; } if (!defined(componentByteLength)) { return `Batch table binary property "${name}" has invalid componentType "${componentType}".`; } if (byteOffset % componentByteLength > 0) { return `Batch table binary property "${name}" must be aligned to a ${componentByteLength}-byte boundary.`; } const propertyByteLength = componentsLength * componentByteLength * featuresLength; if (byteOffset + propertyByteLength > batchTableBinary.length) { return `Batch table binary property "${name}" exceeds batch table binary byte length.`; } } else { if (!Array.isArray(property)) { return `Batch table property "${name}" must be an array.`; } if (property.length !== featuresLength) { return `Batch table property "${name}" array length must equal features length ${featuresLength}.`; } } } } } function hasDracoProperty(batchTableJson: any, propertyName: string): boolean { const extensions = batchTableJson.extensions; if (defined(extensions)) { const dracoExtension = extensions["3DTILES_draco_point_compression"]; if (defined(dracoExtension)) { return defined(dracoExtension.properties[propertyName]); } } return false; } export { validateBatchTable }; ================================================ FILE: src/tileFormats/legacy/validateFeatureTable.ts ================================================ // Mostly ported from https://github.com/CesiumGS/3d-tiles-validator/tree/e84202480eb6572383008076150c8e52c99af3c3 import { defaultValue } from "3d-tiles-tools"; import { defined } from "3d-tiles-tools"; import { typeToComponentsLength } from "./utility"; import { componentTypeToByteLength } from "./utility"; /** * Checks if the feature table JSON and feature table binary are valid * * @param featureTableJson - Feature table JSON. * @param featureTableBinary - Feature table binary. * @param featuresLength - The number of features. * @param featureTableSemantics - An object containing semantic information for each feature table property, specific to the tile format. * @returns An error message if validation fails, otherwise undefined. * * @internal */ function validateFeatureTable( featureTableJson: any, featureTableBinary: Buffer, featuresLength: number, featureTableSemantics: any ): string | undefined { for (const name in featureTableJson) { if (Object.prototype.hasOwnProperty.call(featureTableJson, name)) { if (name === "extensions" || name === "extras") { continue; } const property = featureTableJson[name]; const definition = featureTableSemantics[name]; if (!defined(definition)) { return `Invalid feature table property "${name}".`; } if (hasDracoProperty(featureTableJson, name)) { continue; } const byteOffset = property.byteOffset; const componentType = defaultValue( property.componentType, definition.componentType ); const componentTypeOptions = definition.componentTypeOptions; const type = definition.type; const componentsLength = typeToComponentsLength(type); const componentByteLength = componentTypeToByteLength(componentType); const itemsLength = definition.global ? 1 : featuresLength; if (defined(byteOffset)) { if (!defined(componentsLength)) { return `Feature table binary property "${name}" has invalid type "${type}".`; } if (!defined(componentByteLength)) { return `Feate table binary property "${name}" has invalid componentType "${componentType}".`; } if (typeof byteOffset !== "number") { return `Feature table binary property "${name}" byteOffset must be a number.`; } if ( defined(componentTypeOptions) && defined(componentTypeOptions) && componentTypeOptions.indexOf(componentType) === -1 ) { return `Feature table binary property "${name}" has invalid componentType "${componentType}".`; } if (byteOffset % componentByteLength > 0) { return `Feature table binary property "${name}" must be aligned to a ${componentByteLength}-byte boundary.`; } const propertyByteLength = componentsLength * componentByteLength * itemsLength; if (byteOffset + propertyByteLength > featureTableBinary.length) { return `Feature table binary property "${name}" exceeds feature table binary byte length.`; } } else if (type === "boolean") { if (typeof property !== "boolean") { return `Feature table property "${name}" must be a boolean.`; } } else { if (!defined(componentsLength)) { return `Feature table binary property "${name}" has invalid type "${type}".`; } const arrayLength = componentsLength * itemsLength; if (definition.global && arrayLength === 1) { if (typeof property !== "number") { return `Feature table property "${name}" must be a number.`; } } else { if (!Array.isArray(property)) { return `Feature table property "${name}" must be an array.`; } if (property.length !== arrayLength) { return `Feature table property "${name}" must be an array of length ${arrayLength}.`; } for (let i = 0; i < arrayLength; i++) { if (typeof property[i] !== "number") { return `Feature table property "${name}" array must contain numbers only.`; } } } } } } } function hasDracoProperty( featureTableJson: any, propertyName: string ): boolean { const extensions = featureTableJson.extensions; if (defined(extensions)) { const dracoExtension = extensions["3DTILES_draco_point_compression"]; if (defined(dracoExtension)) { return defined(dracoExtension.properties[propertyName]); } } return false; } export { validateFeatureTable }; ================================================ FILE: src/validation/AssetValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { Asset } from "3d-tiles-tools"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; /** * A class for validations related to `asset` objects. * * @internal */ export class AssetValidator { /** * The set of "known" asset versions. When encountering a version * that is not in this list, a warning will be created. */ static knownAssetVersions: string[] = ["0.0", "1.0", "1.1"]; /** * Performs the validation to ensure that the given object is a * valid `asset` object. * * @param asset - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateAsset(asset: Asset, context: ValidationContext): boolean { const path = "/asset"; // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "asset", asset, context)) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty(path, "asset", asset, context) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject(path, asset, context) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(asset)) { return result; } // Validate the version const version = asset.version; const versionPath = "/asset/version"; // The version MUST be defined // The version MUST be a string if ( !BasicValidator.validateString(versionPath, "version", version, context) ) { result = false; } else { // The version SHOULD be one of the `knownAssetVersions` if (!AssetValidator.knownAssetVersions.includes(version)) { const message = `The asset version is ${version}, ` + `known versions are ${AssetValidator.knownAssetVersions}`; const issue = SemanticValidationIssues.ASSET_VERSION_UNKNOWN( versionPath, message ); context.addIssue(issue); } } // Validate the tilesetVersion const tilesetVersion = asset.tilesetVersion; const tilesetVersionPath = "/asset/tilesetVersion"; if (defined(tilesetVersion)) { // The tilesetVersion MUST be a string if ( !BasicValidator.validateString( tilesetVersionPath, "tilesetVersion", tilesetVersion, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/BasicValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { JsonValidationIssues } from "../issues/JsonValidationIssues"; import { ValidationIssueUtils } from "../issues/ValidationIssueUtils"; // TODO Some of these functions are not as regular as they should be. // For example, validateString expects the string, whereas // validateOptionalString expects the containing object and // does the lookup internally. This should be made more consistent, // and better aligned with the actual, final issues that are // defined in `JsonValidationIssues` /** * A class for generic, basic validations. These are mainly checks for * definedness of values, their types, and their ranges, that may lead * to different `JsonValidationIssues`. * * @internal */ export class BasicValidator { /** * Validate that the specified value has the type `"string"`, * if it is present. * * If the value has the expected type, then `true` is returned. * * If the value does not have the expected type, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` * is returned. * * @param containingPath - The path of the object containing * the property, for the `ValidationIssue` message * @param containingObject - The object that may contain the * property * @param name - The name of the property * @param context - The `ValidationContext` to add the issue to * @returns Whether the specified value has the expected type */ static validateOptionalString( containingPath: string, containingObject: any, name: string, context: ValidationContext ): boolean { const value = containingObject[name]; if (defined(value)) { const path = containingPath + "/" + name; return BasicValidator.validateString(path, name, value, context); } return true; } /** * Validate that the given value is defined. * * If the value is defined, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is defined */ static validateDefined( path: string, name: string, value: any, context: ValidationContext ): boolean { if (defined(value)) { return true; } const issue = JsonValidationIssues.PROPERTY_MISSING(path, name); context.addIssue(issue); return false; } /** * Validate that the given value is an array. * * If the value is an array with the expected length, then `true` is * returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the value is not an array, then a `TYPE_MISMATCH` validation * issue is added to the given context, and `false` is returned. * * If the expected length is given, and the array does not have * this length, then an `ARRAY_LENGTH_MISMATCH` validation issue * is added to the given context, and `false` is returned. * * If the expected type is given, and any element of the array does * not have the expected type, then a `TYPE_MISMATCH` validation * issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param minLength - The optional minimum length * @param maxLength - The optional maximum length * @param expectedElementType - The optional expected element type * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is an array with the expected * length */ static validateArray( path: string, name: string, value: any, minLength: number | undefined, maxLength: number | undefined, expectedElementType: string | undefined, context: ValidationContext ): boolean { if (!BasicValidator.validateDefined(path, name, value, context)) { return false; } if (!Array.isArray(value)) { const issue = JsonValidationIssues.TYPE_MISMATCH( path, name, "Array", typeof value ); context.addIssue(issue); return false; } if ( (defined(minLength) && value.length < minLength) || (defined(maxLength) && value.length > maxLength) ) { const rangeDescription = ValidationIssueUtils.describeSimpleRange( minLength, maxLength ); const message = `Array '${name}' must have a length of ${rangeDescription}, ` + `but the actual length is ${value.length}`; const issue = JsonValidationIssues.ARRAY_LENGTH_MISMATCH(path, message); context.addIssue(issue); return false; } if (defined(expectedElementType)) { for (let index = 0; index < value.length; index++) { const element = value[index]; if (typeof element !== expectedElementType) { const issue = JsonValidationIssues.ARRAY_ELEMENT_TYPE_MISMATCH( path + "/" + index, name, index, expectedElementType, typeof element ); context.addIssue(issue); return false; } } } return true; } /** * Validate that the given value is an index array. * * If the value is not defined, then `false` is returned. * * If the value is not an array, does not have a length of at least 1, * or contains an element that is not a number, then an error will * be added to the given context, and `false` is returned. * * If any of the elements of the array is not an integer, or it * is negative, then an error will be added to the given context, * and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param maximumValue - The maximum value (EXCLUSIVE) that any * array element may have (or `undefined` if there is no * upper limit) * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is an index array */ static validateIndexArray( path: string, name: string, value: any, maximumValueExclusive: number | undefined, context: ValidationContext ): boolean { const basicValidity = BasicValidator.validateArray( path, name, value, 1, undefined, "number", context ); if (!basicValidity) { return false; } for (let index = 0; index < value.length; index++) { const element = value[index]; const elementPath = path + "/" + index; const elementValid = BasicValidator.validateIntegerRange( elementPath, name + "[" + index + "]", element, 0, true, maximumValueExclusive, false, context ); if (!elementValid) { return false; } } return true; } /** * Validates that the elements in the given array are unique. * * This assumes that the basic validation of the array has already * been performed. It **ONLY** checks the uniqueness of the elements. * * If the elements are unique, then `true` is returned. * * Otherwise, one `ARRAY_ELEMENT_NOT_UNIQUE` issue will be added * for each non-unique element, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param array - The array * @param context - The `ValidationContext` to add the issue to * @returns Whether the elements have been unique */ static validateArrayElementsUnique( path: string, name: string, array: any, context: ValidationContext ): boolean { let result = true; for (let i = 0; i < array.length; i++) { const value = array[i]; const index = array.indexOf(value); if (index != i) { const issue = JsonValidationIssues.ARRAY_ELEMENT_NOT_UNIQUE( path, name, value ); context.addIssue(issue); result = false; } } return result; } /** * Validate that the given value has the type `"object"`. * * If the value has the expected type, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object does not have the expected type, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value has the expected type */ static validateObject( path: string, name: string, value: any, context: ValidationContext ): value is { [key: string]: any } { if (!BasicValidator.validateDefined(path, name, value, context)) { return false; } return BasicValidator.validateType(path, name, value, "object", context); } /** * Validate that the given value has the type `"string"`. * * If the value has the expected type, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object does not have the expected type, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value has the expected type */ static validateString( path: string, name: string, value: any, context: ValidationContext ): value is string { if (!BasicValidator.validateDefined(path, name, value, context)) { return false; } return BasicValidator.validateType(path, name, value, "string", context); } /** * Validate that the given value has the type `"number"`. * * If the value has the expected type, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object does not have the expected type, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value has the expected type */ static validateNumber( path: string, name: string, value: any, context: ValidationContext ): value is number { if (!BasicValidator.validateDefined(path, name, value, context)) { return false; } return BasicValidator.validateType(path, name, value, "number", context); } /** * Validate that the given value has the type `"boolean"`. * * If the value has the expected type, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object does not have the expected type, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value has the expected type */ static validateBoolean( path: string, name: string, value: any, context: ValidationContext ): value is boolean { if (!BasicValidator.validateDefined(path, name, value, context)) { return false; } return BasicValidator.validateType(path, name, value, "boolean", context); } /** * Validate that the given object has the expected type. * * If the value has the expected type, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object does not have the expected type, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param expectedType - The expected type * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value has the expected type */ static validateType( path: string, name: string, value: any, expectedType: string, context: ValidationContext ): boolean { if (!BasicValidator.validateDefined(path, name, value, context)) { return false; } if (typeof value === expectedType) { return true; } const issue = JsonValidationIssues.TYPE_MISMATCH( path, name, expectedType, typeof value ); context.addIssue(issue); return false; } /** * Validate that the given value is an integer. * * If the value has the expected type, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object does not have the expected type, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value has the expected type */ static validateInteger( path: string, name: string, value: any, context: ValidationContext ): boolean { if (!BasicValidator.validateDefined(path, name, value, context)) { return false; } if (Number.isInteger(value)) { return true; } const issue = JsonValidationIssues.TYPE_MISMATCH( path, name, "integer", typeof value ); context.addIssue(issue); return false; } /** * Validate that the given value is in the specified range. * * If the value is in the specified range, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object is not a number, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` is returned. * * If the value is not in the required range, `VALUE_NOT_IN_RANGE` * validation issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param min - The minimum value (optional) * @param minInclusive - Whether the minimum value is inclusive * @param max - The maximum value (optional) * @param maxInclusive - Whether the maximum value is inclusive * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is in the expected range */ static validateNumberRange( path: string, name: string, value: number, min: number | bigint | undefined, minInclusive: boolean, max: number | bigint | undefined, maxInclusive: boolean, context: ValidationContext ): boolean { if (!BasicValidator.validateNumber(path, name, value, context)) { return false; } return BasicValidator._validateNumberRangeInternal( path, name, value, min, minInclusive, max, maxInclusive, context ); } /** * Validate that the given value is in the specified range. * * If the value is in the specified range, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object is not an integer, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` is returned. * * If the value is not in the required range, `VALUE_NOT_IN_RANGE` * validation issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param min - The minimum value (optional) * @param minInclusive - Whether the minimum value is inclusive * @param max - The maximum value (optional) * @param maxInclusive - Whether the maximum value is inclusive * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is in the expected range */ static validateIntegerRange( path: string, name: string, value: number, min: number | undefined, minInclusive: boolean, max: number | undefined, maxInclusive: boolean, context: ValidationContext ): boolean { if (!BasicValidator.validateInteger(path, name, value, context)) { return false; } return BasicValidator._validateNumberRangeInternal( path, name, value, min, minInclusive, max, maxInclusive, context ); } /** * Validate that the given number is in the specified range. * * This function assumes the given value to be defined and * to be a number. * * If the value is not in the required range, `VALUE_NOT_IN_RANGE` * validation issue is added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param min - The minimum value (optional) * @param minInclusive - Whether the minimum value is inclusive * @param max - The maximum value (optional) * @param maxInclusive - Whether the maximum value is inclusive * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is in the expected range */ static _validateNumberRangeInternal( path: string, name: string, value: number, min: number | bigint | undefined, minInclusive: boolean, max: number | bigint | undefined, maxInclusive: boolean, context: ValidationContext ): boolean { if (defined(min) && defined(max)) { const validMin = minInclusive ? value >= min : value > min; const validMax = maxInclusive ? value <= max : value < max; if (!validMin || !validMax) { const minBracket = minInclusive ? "[" : "("; const maxBracket = maxInclusive ? "]" : ")"; const rangeDescription = `in ${minBracket}${min},${max}${maxBracket}`; const message = `The '${name}' property must be ${rangeDescription}, but is ${value}`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); return false; } } else if (defined(min)) { const validMin = minInclusive ? value >= min : value > min; if (!validMin) { const minComparison = minInclusive ? "greater than or equal to" : "greater than"; const message = `The '${name}' property must be ` + `${minComparison} ${min}, but is ${value}`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); return false; } } else if (defined(max)) { const validMax = maxInclusive ? value <= max : value < max; if (!validMax) { const maxComparison = maxInclusive ? "less than or equal to" : "less than"; const message = `The '${name}' property must be ` + `${maxComparison} ${max}, but is ${value}`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); return false; } } return true; } /** * Validate that the given value is a valid enum value. * * If the value is valid, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object is not contained in the given array of * allowed values, then a `VALUE_NOT_IN_LIST` validation issue is * added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param allowedValues - The array of allowed values * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is one of the allowed values */ static validateEnum( path: string, name: string, value: any, allowedValues: any[], context: ValidationContext ): boolean { if (!BasicValidator.validateDefined(path, name, value, context)) { return false; } if (!allowedValues.includes(value)) { const message = `The '${name}' property has the value ` + `${value}, but must be one of ${allowedValues}`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST(path, message); context.addIssue(issue); return false; } return true; } /** * Validate that the given object has the required number of properties. * * If the object has the required number, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the value is not an object, then a `TYPE_MISMATCH` validation * issue is added to the given context, and `false` is returned. * * If the given value does not have the required number of properties, * then a `NUMBER_OF_PROPERTIES_MISMATCH` issue is added to the given * context, and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param minProperties - The minimum number of properties * @param maxProperties - The maximum number of properties * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value has the expected number of properties */ static validateNumberOfProperties( path: string, name: string, value: any, minProperties: number | undefined, maxProperties: number | undefined, context: ValidationContext ): boolean { if (!BasicValidator.validateObject(path, name, value, context)) { return false; } const numProperties = Object.keys(value).length; if ( (defined(minProperties) && numProperties < minProperties) || (defined(maxProperties) && numProperties > maxProperties) ) { const rangeDescription = ValidationIssueUtils.describeSimpleRange( minProperties, maxProperties ); const message = `Object '${name}' must have ${rangeDescription} ` + `properties, but has ${numProperties} properties`; const issue = JsonValidationIssues.NUMBER_OF_PROPERTIES_MISMATCH( path, message ); context.addIssue(issue); return false; } return true; } /** * Validate that the given value is a string with the required length. * * If the value has the expected length, then `true` is returned. * * If the given value is not defined, a `PROPERTY_MISSING` validation * issue is added to the given context, and `false` is returned. * * If the given object does not have the type `"string"`, a `TYPE_MISMATCH` * validation issue is added to the given context, and `false` is returned. * * If the given object does not have the required length, then a * `STRING_LENGTH_MISMATCH` issue will be added to the given context, * and `false` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param minLength - The optional minimum length * @param maxLength - The optional maximum length * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value has the expected type */ static validateStringLength( path: string, name: string, value: any, minLength: number | undefined, maxLength: number | undefined, context: ValidationContext ): boolean { if (!BasicValidator.validateString(path, name, value, context)) { return false; } if ( (defined(minLength) && value.length < minLength) || (defined(maxLength) && value.length > maxLength) ) { const rangeDescription = ValidationIssueUtils.describeSimpleRange( minLength, maxLength ); const message = `String '${name}' must have a length of ${rangeDescription}, ` + `but the actual length is ${value.length}`; const issue = JsonValidationIssues.STRING_LENGTH_MISMATCH(path, message); context.addIssue(issue); return false; } return true; } } ================================================ FILE: src/validation/BinaryBufferStructureValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { BufferObject } from "3d-tiles-tools"; import { BufferView } from "3d-tiles-tools"; import { BinaryBufferStructure } from "3d-tiles-tools"; import { StructureValidationIssues } from "../issues/StructureValidationIssues"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; /** * A class for validations related to binary buffer structures. * * This is the information that is stored in a `BinaryBufferStructure`, * namely the `buffers` and `bufferViews`, which may be part of a `Subtree`. * * The validation here is split into two parts: * * - validateBinaryBufferStructure Performs the JSON-level validation * of the `buffer` and `bufferView` objects * * - validateBinaryBufferStructureConsistency Performs the consistency * validation of the buffers and buffer views in terms of the * memory layout, and is supposed to be called only after the * JSON-level validation has been performed * * @internal */ export class BinaryBufferStructureValidator { /** * Performs the validation of the given elements of a `BinaryBufferStructure`. * * @param path - The path for `ValidationIssue` instances * @param buffers - The buffers * @param bufferViews - The buffer views * @param firstBufferUriIsRequired - If this is `false`, then the * first buffer may omit the `uri` property, namely when it refers * to a binary chunk, for example, of a binary `.subtree` file. * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateBinaryBufferStructure( path: string, buffers: BufferObject[] | undefined, bufferViews: BufferView[] | undefined, firstBufferUriIsRequired: boolean, context: ValidationContext ): boolean { let result = true; // Validate the buffers const buffersPath = path + "/buffers"; if (defined(buffers)) { // The buffers MUST be an array of at least 1 objects if ( !BasicValidator.validateArray( buffersPath, "buffers", buffers, 1, undefined, "object", context ) ) { result = false; return result; } else { // Validate each buffer for (let i = 0; i < buffers.length; i++) { const buffer = buffers[i]; const bufferPath = buffersPath + "/" + i; const bufferUriIsRequired = firstBufferUriIsRequired || i > 0; if ( !this.validateBuffer( bufferPath, "buffers/" + i, buffer, bufferUriIsRequired, context ) ) { result = false; } } } } // If the buffers are invalid, bail out early if (!result) { return false; } // Validate the bufferViews const bufferViewsPath = path + "/bufferViews"; if (!defined(bufferViews)) { // When there are bufferViews, but (unused) buffers, issue a warning if (defined(buffers)) { const issue = SemanticValidationIssues.BUFFERS_WITHOUT_BUFFER_VIEWS(path); context.addIssue(issue); } } else { // When there are bufferViews, but no buffers, issue an error if (!defined(buffers)) { const issue = SemanticValidationIssues.BUFFER_VIEWS_WITHOUT_BUFFERS(path); context.addIssue(issue); return false; } // Here, bufferViews and buffers are defined. const numBuffers = buffers.length; //The bufferViews MUST be an array of at least 1 objects if ( !BasicValidator.validateArray( bufferViewsPath, "bufferViews", bufferViews, 1, undefined, "object", context ) ) { result = false; } else { // Validate each bufferView for (let i = 0; i < bufferViews.length; i++) { const bufferView = bufferViews[i]; const bufferViewPath = bufferViewsPath + "/" + i; if ( !BinaryBufferStructureValidator.validateBufferView( bufferViewPath, "bufferViews/" + i, bufferView, numBuffers, context ) ) { result = false; } } } } return result; } /** * Performs the validation to ensure that the given object is a * valid `BufferObject` object. * * @param path - The path for the `ValidationIssue` instances * @param name - The name of the object * @param buffer - The `BufferObject` object * @param bufferUriIsRequired - Whether the buffer must have a `uri` * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateBuffer( path: string, name: string, buffer: BufferObject, bufferUriIsRequired: boolean, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, buffer, context)) { return false; } let result = true; // Validate the uri const uri = buffer.uri; const uriPath = path + "/uri"; // When the bufferUriIsRequired, then the uri MUST be defined if (bufferUriIsRequired && !defined(uri)) { const message = `The 'uri' property of the buffer is required`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( uriPath, message ); context.addIssue(issue); result = false; } if (defined(uri)) { // The uri MUST be a string if (!BasicValidator.validateString(uriPath, "uri", uri, context)) { result = false; } } // Validate the byteLength // The byteLength MUST be defined // The byteLength MUST be an integer of at least 1 const byteLength = buffer.byteLength; const byteLengthPath = path + "/byteLength"; if ( !BasicValidator.validateIntegerRange( byteLengthPath, "byteLength", byteLength, 1, true, undefined, false, context ) ) { result = false; } // Validate the name const theName = buffer.name; const namePath = path + "/name"; if (defined(theName)) { // The name MUST be a string // The name MUST have a length of at least 1 if ( !BasicValidator.validateStringLength( namePath, "name", theName, 1, undefined, context ) ) { result = false; } } return result; } /** * Performs the validation to ensure that the given object is a * valid `BufferView` object. * * @param path - The path for the `ValidationIssue` instances * @param name - The name of the object * @param bufferView - The `BufferView` object * @param numBuffers - The number of `buffers` * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateBufferView( path: string, name: string, bufferView: BufferView, numBuffers: number, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, bufferView, context)) { return false; } let result = true; // Validate the buffer // The buffer MUST be defined // The buffer MUST be an integer of at least 0 // The buffer MUST be smaller than the number of buffers const buffer = bufferView.buffer; const bufferPath = path + "/buffer"; if ( !BasicValidator.validateIntegerRange( bufferPath, "buffer", buffer, 0, true, numBuffers, false, context ) ) { result = false; } // Validate the byteOffset // The byteOffset MUST be defined // The byteOffset MUST be an integer of at least 0 const byteOffset = bufferView.byteOffset; const byteOffsetPath = path + "/byteOffset"; if ( !BasicValidator.validateIntegerRange( byteOffsetPath, "byteOffset", byteOffset, 0, true, undefined, false, context ) ) { result = false; } // Validate the byteLength // The byteLength MUST be defined // The byteLength MUST be an integer of at least 1 const byteLength = bufferView.byteLength; const byteLengthPath = path + "/byteLength"; if ( !BasicValidator.validateIntegerRange( byteLengthPath, "byteLength", byteLength, 1, true, undefined, false, context ) ) { result = false; } // Validate the name const theName = bufferView.name; const namePath = path + "/name"; if (defined(theName)) { // The name MUST be a string // The name MUST have a length of at least 1 if ( !BasicValidator.validateStringLength( namePath, "name", theName, 1, undefined, context ) ) { result = false; } } return result; } /** * Validate the consistency of the `buffer` and `bufferView` objects * in the given binary buffer structure. * * This assumes that the basic (JSON-level) structural validations * have already been performed. It will only validate the consistency * of the memory layout of buffer views and buffers. * * @param path - The path for the `ValidationIssue` instances * @param binaryBufferStructure - The `BinaryBufferStructure` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateBinaryBufferStructureConsistency( path: string, binaryBufferStructure: BinaryBufferStructure, context: ValidationContext ): boolean { let result = true; // Validate the consistency of the bufferViews const buffers = defaultValue(binaryBufferStructure.buffers, []); const bufferViews = defaultValue(binaryBufferStructure.bufferViews, []); for (let i = 0; i < bufferViews.length; i++) { const bufferView = bufferViews[i]; const bufferViewPath = path + "/bufferViews/" + i; const bufferViewEnd = bufferView.byteOffset + bufferView.byteLength; const buffer = buffers[bufferView.buffer]; // The end of the buffer view MUST be at most the buffer length if (bufferViewEnd > buffer.byteLength) { const message = `The bufferView has an offset of ${bufferView.byteOffset} ` + `and a length of ${bufferView.byteLength}, yielding ` + `${bufferView.byteOffset + bufferView.byteLength}, but buffer ` + `${bufferView.buffer} only has a length of ${buffer.byteLength}`; const issue = SemanticValidationIssues.BUFFERS_INCONSISTENT( bufferViewPath, message ); context.addIssue(issue); result = false; } } // NOTE: One could consider to require bufferViews to NOT overlap. // But there does not seem to be a strong, convincing reason for that... return result; } } ================================================ FILE: src/validation/BinaryValidator.ts ================================================ import { ValidationContext } from "./ValidationContext"; import { BinaryValidationIssues } from "../issues/BinaryValidationIssues"; /** * A class for validations of binary data. * * @internal */ export class BinaryValidator { /** * Validates that the actual length is at least the minimum length. * * This is mainly used for early sanity checks, to make sure * that a buffer contains at least enough data for the * expected header. * * If the length is valid, then `true` is returned. * * If the length is too small, then a `BINARY_INVALID` issue * will be added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` * @param name - The name of the length to be shown in the message * @param minLength - The minimum length, inclusive * @param actualLength - The actual length * @param context - The `ValidationContext` * @returns Whether the length is valid */ static validateMinLength( path: string, name: string, minLength: number | bigint, actualLength: number | bigint, context: ValidationContext ): boolean { if (actualLength < minLength) { const message = `The ${name} must have at least ${minLength} bytes, ` + `but only has ${actualLength} bytes`; const issue = BinaryValidationIssues.BINARY_INVALID(path, message); context.addIssue(issue); return false; } return true; } /** * Validates that the given length is the expected length. * * If the length is valid, then `true` is returned. * * If the length does not match, then a `BINARY_INVALID_LENGTH` issue * will be added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` * @param name - The name of the length to be shown in the message * @param expectedLength - The expected length * @param actualLength - The actual length * @param context - The `ValidationContext` * @returns Whether the length is valid */ static validateLength( path: string, name: string, expectedLength: number | bigint, actualLength: number | bigint, context: ValidationContext ): boolean { if (BigInt(actualLength) !== BigInt(expectedLength)) { const issue = BinaryValidationIssues.BINARY_INVALID_LENGTH( path, name, expectedLength, actualLength ); context.addIssue(issue); return false; } return true; } /** * Validates that the given value is the expected value. * * If the value is valid, then `true` is returned. * * If the values do not match, then a `BINARY_INVALID_VALUE` issue * will be added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` * @param name - The name of the value to be shown in the message * @param expectedValue - The expected value * @param actualValue - The actual value * @param context - The `ValidationContext` * @returns Whether the value is valid */ static validateValue( path: string, name: string, expectedValue: any, actualValue: any, context: ValidationContext ): boolean { if (actualValue !== expectedValue) { const issue = BinaryValidationIssues.BINARY_INVALID_VALUE( path, name, expectedValue, actualValue ); context.addIssue(issue); return false; } return true; } /** * Validates that the given value is properly aligned. * * If the value is properly aligned, then `true` is returned. * * If the value is not aligned, then a `BINARY_INVALID_ALIGNMENT` issue * will be added to the given context, and `false` is returned. * * @param path - The path for the `ValidationIssue` * @param name - The name of the value to be shown in the message * @param value - The actual value * @param expectedAlignment - The expected alignment * @param context - The `ValidationContext` * @returns Whether the value is valid */ static validateAlignment( path: string, name: string, value: number | bigint, expectedAlignment: number | bigint, context: ValidationContext ): boolean { const misalignment = BigInt(value) % BigInt(expectedAlignment); if (misalignment > 0) { const issue = BinaryValidationIssues.BINARY_INVALID_ALIGNMENT( path, name, expectedAlignment, value, misalignment ); context.addIssue(issue); return false; } return true; } } ================================================ FILE: src/validation/BoundingVolumeValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { BoundingVolume } from "3d-tiles-tools"; import { JsonValidationIssues } from "../issues/JsonValidationIssues"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; /** * A class for validations related to `boundingVolume` objects. * * @internal */ export class BoundingVolumeValidator { /** * Performs the validation to ensure that the given object is a * valid `boundingVolume` object. * * @param boundingVolumePath - The path that indicates the location of * the given object, to be used in the validation issue message. * @param boundingVolume - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the given object is valid */ static async validateBoundingVolume( boundingVolumePath: string, boundingVolume: BoundingVolume, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject( boundingVolumePath, "boundingVolume", boundingVolume, context ) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( boundingVolumePath, "boundingVolume", boundingVolume, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( boundingVolumePath, boundingVolume, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(boundingVolume)) { return result; } if ( !BoundingVolumeValidator.validateBoundingVolumeInternal( boundingVolumePath, boundingVolume, context ) ) { result = false; } return result; } /** * Implementation for validateBoundingVolume * * @param boundingVolumePath - The path that indicates the location of * the given object, to be used in the validation issue message. * @param boundingVolume - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the given object is valid */ private static validateBoundingVolumeInternal( boundingVolumePath: string, boundingVolume: BoundingVolume, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( boundingVolumePath, "boundingVolume", boundingVolume, context ) ) { return false; } let result = true; const box = boundingVolume.box; const region = boundingVolume.region; const sphere = boundingVolume.sphere; // The bounding volume MUST contain one of these properties if (!defined(box) && !defined(region) && !defined(sphere)) { const path = boundingVolumePath; const issue = JsonValidationIssues.ANY_OF_ERROR( path, "boundingVolume", "box", "region", "sphere" ); context.addIssue(issue); result = false; } // Validate the box const boxPath = boundingVolumePath + "/box"; if (defined(box)) { if (!BoundingVolumeValidator.validateBoundingBox(boxPath, box, context)) { result = false; } } // Validate the region const regionPath = boundingVolumePath + "/region"; if (defined(region)) { if ( !BoundingVolumeValidator.validateBoundingRegion( regionPath, region, context ) ) { result = false; } } // Validate the sphere const spherePath = boundingVolumePath + "/sphere"; if (defined(sphere)) { if ( !BoundingVolumeValidator.validateBoundingSphere( spherePath, sphere, context ) ) { result = false; } } return result; } /** * Perform a validation of the given `boundingVolume.box` array. * * @param path - The path for the validation issues * @param box - The box array * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateBoundingBox( path: string, box: number[], context: ValidationContext ): boolean { // The box MUST be an array with length 12 // Each element of the box MUST be a number const expectedLength = 12; const expectedElementType = "number"; if ( !BasicValidator.validateArray( path, "box", box, expectedLength, expectedLength, expectedElementType, context ) ) { return false; } return true; } /** * Perform a validation of the given `boundingVolume.sphere` array. * * @param path - The path for the validation issues * @param sphere - The sphere array * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateBoundingSphere( path: string, sphere: number[], context: ValidationContext ): boolean { // The sphere MUST be an array with length 4 // Each element of the sphere MUST be a number const expectedLength = 4; const expectedElementType = "number"; if ( !BasicValidator.validateArray( path, "sphere", sphere, expectedLength, expectedLength, expectedElementType, context ) ) { return false; } // The radius MUST NOT be negative const radius = sphere[3]; if (radius < 0.0) { const message = `The 'radius' entry of the bounding sphere ` + `may not be negative, but is ${radius}`; const issue = SemanticValidationIssues.BOUNDING_VOLUME_INVALID( path + "/3", message ); context.addIssue(issue); return false; } return true; } /** * Perform a validation of the given `boundingVolume.region` array. * * @param path - The path for the validation issues * @param region - The region array * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateBoundingRegion( path: string, region: number[], context: ValidationContext ): boolean { // The region MUST be an array with length 6 // Each element of the region MUST be a number const expectedLength = 6; const expectedElementType = "number"; if ( !BasicValidator.validateArray( path, "region", region, expectedLength, expectedLength, expectedElementType, context ) ) { return false; } const westRad = region[0]; const southRad = region[1]; const eastRad = region[2]; const northRad = region[3]; const minimumHeight = region[4]; const maximumHeight = region[5]; let result = true; if (westRad < -Math.PI || westRad > Math.PI) { const message = `The 'west' entry of the bounding region ` + `must be in [-PI,PI], but is ${westRad}`; const issue = SemanticValidationIssues.BOUNDING_VOLUME_INVALID( path + "/0", message ); context.addIssue(issue); result = false; } if (southRad < -Math.PI / 2 || southRad > Math.PI / 2) { const message = `The 'south' entry of the bounding region ` + `must be in [-PI/2,PI/2], but is ${southRad}`; const issue = SemanticValidationIssues.BOUNDING_VOLUME_INVALID( path + "/1", message ); context.addIssue(issue); result = false; } if (eastRad < -Math.PI || eastRad > Math.PI) { const message = `The 'east' entry of the bounding region ` + `must be in [-PI,PI], but is ${eastRad}`; const issue = SemanticValidationIssues.BOUNDING_VOLUME_INVALID( path + "/2", message ); context.addIssue(issue); result = false; } if (northRad < -Math.PI / 2 || northRad > Math.PI / 2) { const message = `The 'north' entry of the bounding region ` + `must be in [-PI/2,PI/2], but is ${northRad}`; const issue = SemanticValidationIssues.BOUNDING_VOLUME_INVALID( path + "/3", message ); context.addIssue(issue); result = false; } if (southRad > northRad) { const message = `The 'south' entry of the bounding region ` + `may not be larger than the 'north' entry, but the south ` + `is ${southRad} and the north is ${northRad}`; const issue = SemanticValidationIssues.BOUNDING_VOLUME_INVALID( path, message ); context.addIssue(issue); result = false; } if (minimumHeight > maximumHeight) { const message = `The minimum height of the bounding region ` + `may not be larger than the maximum height, but the minimum height ` + `is ${minimumHeight} and the maximum height is ${maximumHeight}`; const issue = SemanticValidationIssues.BOUNDING_VOLUME_INVALID( path, message ); context.addIssue(issue); result = false; } return result; } } ================================================ FILE: src/validation/ContentDataValidator.ts ================================================ import paths from "path"; import { Uris } from "3d-tiles-tools"; import { defined } from "3d-tiles-tools"; import { ContentData } from "3d-tiles-tools"; import { ContentDataTypes } from "3d-tiles-tools"; import { ContentDataTypeRegistry } from "3d-tiles-tools"; import { LazyContentData } from "3d-tiles-tools"; import { Content } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { ContentDataValidators } from "./ContentDataValidators"; import { IoValidationIssues } from "../issues/IoValidationIssue"; import { ContentValidationIssues } from "../issues/ContentValidationIssues"; import { ValidationOptionChecks } from "./ValidationOptionChecks"; import { ValidationIssueFilters } from "./ValidationIssueFilters"; import { ValidationIssueSeverity } from "./ValidationIssueSeverity"; import { ValidationResult } from "./ValidationResult"; import { Validator } from "./Validator"; /** * A class for validation of the data that is pointed to by a `content.uri`. * * @internal */ export class ContentDataValidator { /** * Validate the actual data that is referred to by the URI in the * given content. * * This assumes that the given content has already been validated * to be structurally valid, using the `ContentValidator`. * * @param contentPath - The path for the `ValidationIssue` instances * @param content - The `Content` object * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished */ static async validateContentData( contentPath: string, content: Content, context: ValidationContext ): Promise { // Validate the uri const uri = content.uri; if (Uris.isAbsoluteUri(uri)) { const path = contentPath; const message = `Tile content ${contentPath} refers to absolute URI ${uri}, ` + `which is not validated`; const issue = IoValidationIssues.IO_WARNING(path, message); context.addIssue(issue); return true; } const result = await ContentDataValidator.validateContentDataInternal( contentPath, uri, context ); return result; } /** * Perform the validation of the content data that is pointed to * by the given content URI. * * If the data causes validation issues, they will be summarized * into a `CONTENT_VALIDATION_ERROR` or `CONTENT_VALIDATION_WARNING` * that is added to the given context. * * If the data type cannot be determined, an `CONTENT_VALIDATION_WARNING` * will be added to the given context. * * @param contentPath - The path for the `ValidationIssue` instances. * @param contentUri - The URI of the content * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished */ private static async validateContentDataInternal( contentPath: string, contentUri: string, context: ValidationContext ): Promise { const resourceResolver = context.getResourceResolver(); //console.log('Validating ' +contentPath+" with "+contentUri); // Create the `ContentData` that summarizes all information // that is required for determining the content type const contentData = new LazyContentData(contentUri, resourceResolver); // Make sure that the content data can be resolved at all const dataExists = await contentData.exists(); if (!dataExists) { const path = contentPath; const message = `Tile content ${contentPath} refers to URI ${contentUri}, ` + `which could not be resolved`; const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( path, message ); context.addIssue(issue); return false; } // Check if the content data should be validated const options = context.getOptions(); const shouldValidate = await ValidationOptionChecks.shouldValidate( options, contentData ); if (!shouldValidate) { return true; } // Find the validator for the content data const dataValidator = await ContentDataValidators.findContentDataValidator( contentData ); if (!defined(dataValidator)) { const path = contentPath; const message = `Tile content ${contentPath} refers to URI ${contentUri}, ` + `for which no content type could be determined`; const issue = ContentValidationIssues.CONTENT_VALIDATION_WARNING( path, message ); context.addIssue(issue); return true; } await ContentDataValidator.trackExtensionsFound(contentData, context); const contentDataType = await ContentDataTypeRegistry.findContentDataType( contentData ); const isTileset = contentDataType === ContentDataTypes.CONTENT_TYPE_TILESET; const is3tz = contentDataType === ContentDataTypes.CONTENT_TYPE_3TZ; if (isTileset) { const result = await ContentDataValidator.validateExternalTilesetContent( contentPath, contentUri, contentData, dataValidator, context ); return result; } const result = await ContentDataValidator.validateSimpleContent( contentUri, contentData, dataValidator, is3tz, context ); return result; } /** * Implementation of `validateContentDataInternal` for the case that * the content is an external tileset. * * @param contentPath - The path for the `ValidationIssue` instances. * @param contentUri - The URI of the content * @param context - The `ValidationContext` * @param contentData - The content data * @param dataValidator - The validator for the content data * @returns A promise that resolves when the validation is finished */ private static async validateExternalTilesetContent( contentPath: string, contentUri: string, contentData: ContentData, dataValidator: Validator, context: ValidationContext ): Promise { // Add the resolved URI of the external tileset to the context as // an "activeTilesetUri", to detect cycles const resolvedTilesetContentUri = context.resolveUri(contentUri); if (context.isActiveTilesetUri(resolvedTilesetContentUri)) { const message = `External tileset content ${contentUri} creates a cycle`; const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( contentPath, message ); context.addIssue(issue); return false; } context.addActiveTilesetUri(resolvedTilesetContentUri); // Create a new context to collect the issues that are found in // the external tileset. If there are issues, then they will be // stored as the 'causes' of a single content validation issue. const dirName = paths.dirname(contentData.uri); const derivedContext = context.deriveFromUri(dirName); const result = await dataValidator.validateObject( contentUri, contentData, derivedContext ); const derivedResult = derivedContext.getResult(); // Add all extensions that have been found in the external // tileset to the current context. They also have to appear // in the 'extensionsUsed' of the containing tileset. const derivedExtensionsFound = derivedContext.getExtensionsFound(); for (const derivedExtensionFound of derivedExtensionsFound) { context.addExtensionFound(derivedExtensionFound); } const issue = ContentValidationIssues.createForExternalTileset( contentUri, derivedResult ); if (issue) { context.addIssue(issue); } context.removeActiveTilesetUri(resolvedTilesetContentUri); return result; } /** * Implementation of `validateContentDataInternal` for the case that * the content is NOT an external tileset. * * @param contentUri - The URI of the content * @param context - The `ValidationContext` * @param contentData - The content data * @param dataValidator - The validator for the content data * @param is3tz - Whether the content is a 3TZ package * @returns A promise that resolves when the validation is finished */ private static async validateSimpleContent( contentUri: string, contentData: ContentData, dataValidator: Validator, is3tz: boolean, context: ValidationContext ): Promise { // Special handling for 3TZ: // // The context usually refers to the directory that the content // is contained in (for example, a URI like `../images/image.png` // that is used in a glTF file like `example/directory/file.gltf` // has to be resolved to `example/images/image.png`). // // But for 3TZ, it has to determine the absolute (!) path from // the content URI to even be able to open the 3TZ (because 3TZ // can only be a file in the local file system), and there are no // resources to be resolved FROM the 3TZ that are NOT part of // the 3TZ. let dirName = "."; if (!is3tz) { dirName = paths.dirname(contentData.uri); } const derivedContext = context.deriveFromUri(dirName); const result = await dataValidator.validateObject( contentUri, contentData, derivedContext ); const derivedResult = derivedContext.getResult(); const options = context.getOptions(); const filteredDerivedResult = ContentDataValidator.filterResult( derivedResult, options.contentValidationIssueSeverity ); const issue = ContentValidationIssues.createForContent( contentUri, filteredDerivedResult ); if (issue) { context.addIssue(issue); } return result; } /** * Filter the given result, and return a new result that only contains * validation issues that are at least as severe as the given severity. * * @param result - The validation result * @param severity - The highest validation issue severity that should be included * @returns The filtered result */ private static filterResult( result: ValidationResult, severity: ValidationIssueSeverity ) { const includedSeverities: ValidationIssueSeverity[] = []; if (severity == ValidationIssueSeverity.ERROR) { includedSeverities.push(ValidationIssueSeverity.ERROR); } else if (severity == ValidationIssueSeverity.WARNING) { includedSeverities.push(ValidationIssueSeverity.WARNING); includedSeverities.push(ValidationIssueSeverity.ERROR); } else { includedSeverities.push(ValidationIssueSeverity.INFO); includedSeverities.push(ValidationIssueSeverity.WARNING); includedSeverities.push(ValidationIssueSeverity.ERROR); } const filter = ValidationIssueFilters.byIncludedSeverities( ...includedSeverities ); const filteredResult = result.filter(filter); return filteredResult; } /** * Track the extensions that are used, and which only refer to * allowing certain content data types. * * When a certain content data type that requires an extension * is encountered, then the respective extension will be added * as a "found" extension to the given context. * * @param contentData - The `ContentData` * @param context - The `ValidationContext` */ private static async trackExtensionsFound( contentData: ContentData, context: ValidationContext ) { const contentDataType = await ContentDataTypeRegistry.findContentDataType( contentData ); if (contentDataType === ContentDataTypes.CONTENT_TYPE_GLB) { context.addExtensionFound("3DTILES_content_gltf"); } else if (contentDataType === ContentDataTypes.CONTENT_TYPE_GLTF) { context.addExtensionFound("3DTILES_content_gltf"); } else if (contentDataType === ContentDataTypes.CONTENT_TYPE_3TZ) { context.addExtensionFound("MAXAR_content_3tz"); } else if (contentDataType === ContentDataTypes.CONTENT_TYPE_GEOJSON) { context.addExtensionFound("MAXAR_content_geojson"); } } } ================================================ FILE: src/validation/ContentDataValidators.ts ================================================ import { defined } from "3d-tiles-tools"; import { ContentData } from "3d-tiles-tools"; import { ContentDataTypes } from "3d-tiles-tools"; import { ContentDataTypeRegistry } from "3d-tiles-tools"; import { Validators } from "./Validators"; import { Validator } from "./Validator"; import { ValidationContext } from "./ValidationContext"; import { TilesetPackageValidator } from "./TilesetPackageValidator"; import { B3dmValidator } from "../tileFormats/B3dmValidator"; import { I3dmValidator } from "../tileFormats/I3dmValidator"; import { PntsValidator } from "../tileFormats/PntsValidator"; import { CmptValidator } from "../tileFormats/CmptValidator"; import { GltfValidator } from "../tileFormats/GltfValidator"; import { GeojsonValidator } from "../tileFormats/GeojsonValidator"; import { Tileset } from "3d-tiles-tools"; import { IoValidationIssues } from "../issues/IoValidationIssue"; /** * A class for managing `Validator` instances that are used for * validating the data that is pointed to by a `content.uri`. * * The only public method (for now) is `findContentDataValidator`, * which returns the validator that should be used for a given * `ContentData` object. * * @internal */ export class ContentDataValidators { /** * The validators that have been registered. * * See `registerDefaults` for details. */ private static readonly dataValidators: { [key: string]: Validator; } = {}; /** * Whether the default content data validators have already * been registered by calling 'registerDefaults' * * Note: This could be solved with a static initializer block, but the * unclear initialization order of the classes would make this brittle */ private static _registeredDefaults = false; /** * Registers all default content data validators */ private static registerDefaults() { if (ContentDataValidators._registeredDefaults) { return; } ContentDataValidators.registerForBuffer( ContentDataTypes.CONTENT_TYPE_GLB, new GltfValidator() ); ContentDataValidators.registerForBuffer( ContentDataTypes.CONTENT_TYPE_B3DM, new B3dmValidator() ); ContentDataValidators.registerForBuffer( ContentDataTypes.CONTENT_TYPE_I3DM, new I3dmValidator() ); ContentDataValidators.registerForBuffer( ContentDataTypes.CONTENT_TYPE_CMPT, new CmptValidator() ); ContentDataValidators.registerForBuffer( ContentDataTypes.CONTENT_TYPE_PNTS, new PntsValidator() ); // Certain content types are known to be encountered, // but are not (yet) validated. These can either be // ignored, or cause an info. In the future, this // should be configurable, probably even on a per-type // basis, via the command line or a config file const ignoreUnhandledContentTypes = false; let geomValidator = Validators.createEmptyValidator(); let vctrValidator = Validators.createEmptyValidator(); if (!ignoreUnhandledContentTypes) { geomValidator = Validators.createContentValidationInfo( "Skipping 'geom' validation" ); vctrValidator = Validators.createContentValidationInfo( "Skipping 'vctr' validation" ); } // GeoJSON content requires the MAXAR_content_geojson extension const geojsonValidator = ContentDataValidators.createGeojsonValidator(); ContentDataValidators.register( ContentDataTypes.CONTENT_TYPE_GEOM, geomValidator ); ContentDataValidators.register( ContentDataTypes.CONTENT_TYPE_VCTR, vctrValidator ); ContentDataValidators.register( ContentDataTypes.CONTENT_TYPE_GEOJSON, geojsonValidator ); ContentDataValidators.register( ContentDataTypes.CONTENT_TYPE_3TZ, ContentDataValidators.createPackageValidator() ); ContentDataValidators.register( ContentDataTypes.CONTENT_TYPE_TILESET, ContentDataValidators.createTilesetValidator() ); ContentDataValidators.register( ContentDataTypes.CONTENT_TYPE_GLTF, ContentDataValidators.createGltfJsonValidator() ); ContentDataValidators._registeredDefaults = true; } /** * Creates a validator for GeoJSON content data. * * This validator will parse the JSON from the content data buffer, * validate it as proper GeoJSON according to the GeoJSON specification, * and provide detailed validation feedback. * * @returns The validator */ private static createGeojsonValidator(): Validator { const bufferValidator = new GeojsonValidator(); const contentDataValidator = ContentDataValidators.wrapBufferValidator(bufferValidator); return contentDataValidator; } /** * Creates a validator for content data that refers to a 3TZ package. * * This takes the contentData.uri, resolves it (to obtain an absolute URI), * and assumes that this URI is a path in the local file system, which * is then passed to the `TilesetPackageValidator` * * @returns The validator */ private static createPackageValidator(): Validator { const packageValidator = new TilesetPackageValidator(); const validator = { async validateObject( inputPath: string, input: ContentData, context: ValidationContext ): Promise { const resolvedUri = context.resolveUri(input.uri); const result = await packageValidator.validateObject( inputPath, resolvedUri, context ); return result; }, }; return validator; } /** * Creates a validator for content data that represents an external tileset. * * This validator will parse the JSON from the content data buffer, and * pass it to a default tileset validator. * * @returns The validator */ private static createTilesetValidator(): Validator { const externalValidator = Validators.createDefaultTilesetValidator(); const bufferValidator = Validators.parseFromBuffer(externalValidator); const contentDataValidator = ContentDataValidators.wrapBufferValidator(bufferValidator); return contentDataValidator; } /** * Creates a validator for content data that represents glTF JSON data. * * This validator will pass the buffer with the JSON data to the * standard glTF validator. * * @returns The validator */ private static createGltfJsonValidator(): Validator { const bufferValidator = new GltfValidator(); const contentDataValidator = ContentDataValidators.wrapBufferValidator(bufferValidator); return contentDataValidator; } /** * Tries to find a data validator that can be used for validating * the given content data. If no matching validator can be found, * then `undefined` is returned. * * @param contentData - The `ContentData` * @returns The validator, or `undefined` */ static async findContentDataValidator( contentData: ContentData ): Promise | undefined> { ContentDataValidators.registerDefaults(); const contentDataTypeName = await ContentDataTypeRegistry.findContentDataType(contentData); if (!contentDataTypeName) { return undefined; } const dataValidator = ContentDataValidators.dataValidators[contentDataTypeName]; return dataValidator; } /** * Wraps the given validator for `Buffer` objects into one that * can be applied to `ContentData` objects, and just applies * the given validator to the buffer that is returned by * `ContentData#getData`. * * @param bufferValidator - The validator for `Buffer` objects * @returns The validator for `ContentData` objects */ static wrapBufferValidator( bufferValidator: Validator ): Validator { return { async validateObject( inputPath: string, input: ContentData, context: ValidationContext ): Promise { const data = await input.getData(); if (!defined(data)) { const message = `Could not resolve ${input.uri}`; const issue = IoValidationIssues.IO_WARNING(inputPath, message); context.addIssue(issue); return true; } const result = await bufferValidator.validateObject( inputPath, data, context ); return result; }, }; } /** * Register a validator that should be used for the content * data buffer, when the content data has the type that is * indicated by the given name. * * @param contentDataTypeName - The content data type name * @param bufferValidator - The validator for the buffer data */ private static registerForBuffer( contentDataTypeName: string, bufferValidator: Validator ) { ContentDataValidators.register( contentDataTypeName, ContentDataValidators.wrapBufferValidator(bufferValidator) ); } /** * Registers a data validator that will be used when a * `ContentData` has the type that is indicated by the * given name. * * @param contentDataTypeName - The content data type name * @param dataValidator - The data validator */ private static register( contentDataTypeName: string, dataValidator: Validator ) { ContentDataValidators.dataValidators[contentDataTypeName] = dataValidator; } } ================================================ FILE: src/validation/ContentValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { ValidationState } from "./ValidationState"; import { BoundingVolumeValidator } from "./BoundingVolumeValidator"; import { BasicValidator } from "./BasicValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { MetadataEntityValidator } from "./metadata/MetadataEntityValidator"; import { Content } from "3d-tiles-tools"; import { StructureValidationIssues } from "../issues/StructureValidationIssues"; /** * A class for validations related to `content` objects. * * @internal */ export class ContentValidator { /** * Performs the validation to ensure that the given object is a * valid `content` object. * * This only performs the basic JSON-level and consistency checks. * It does not validate the content data that is referred to by the * `content.uri`. The validation of the content data is done with * `validateContentData`, if and only if this method returned `true`. * * @param contentPath - The path for the `ValidationIssue` instances * @param content - The object to validate * @param validationState - The `ValidationState` * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the given object was valid */ static async validateContent( contentPath: string, content: Content, validationState: ValidationState, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject(contentPath, "content", content, context) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( contentPath, "content", content, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( contentPath, content, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(content)) { return result; } // Validate the group const group = content.group; const groupPath = contentPath + "/group"; if (defined(group)) { // The group MUST be a non-negative integer if ( !BasicValidator.validateIntegerRange( groupPath, "group", group, 0, true, undefined, false, context ) ) { result = false; } else { const groupsState = validationState.groupsState; // When a group is given, the tileset MUST define groups if (!groupsState.wasPresent) { const message = `Tile content has a group index ${group}, ` + `but the containing tileset does not define groups`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( groupPath, message ); context.addIssue(issue); result = false; } else if (defined(groupsState.validatedElement)) { if (group >= groupsState.validatedElement.length) { const message = `Tile content has a group index ${group}, ` + `but the containing tileset only contains ` + `${groupsState.validatedElement.length} groups`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( groupPath, message ); context.addIssue(issue); result = false; } } } } // TODO XXX Temporary, for CesiumJS spec files /*/ const url = (content as any).url; if (defined(url)) { const message = `Using content.url as content.uri`; console.error(message); content.uri = url; } //*/ // Validate the uri const uri = content.uri; const uriPath = contentPath + "/uri"; // The uri MUST be defined // The uri MUST be a string if (!BasicValidator.validateString(uriPath, "uri", uri, context)) { result = false; } // Validate the boundingVolume const boundingVolume = content.boundingVolume; const boundingVolumePath = contentPath + "/boundingVolume"; if (defined(boundingVolume)) { const boundingVolumeValid = await BoundingVolumeValidator.validateBoundingVolume( boundingVolumePath, boundingVolume, context ); if (!boundingVolumeValid) { result = false; } } // Validate the metadata const metadata = content.metadata; const metadataPath = contentPath + "/metadata"; if (defined(metadata)) { const schemaState = validationState.schemaState; if (!schemaState.wasPresent) { // If there is metadata, then there must be a schema definition const message = "The content defines 'metadata' but the tileset does not have a schema"; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( contentPath, message ); context.addIssue(issue); result = false; } else if (defined(schemaState.validatedElement)) { if ( !MetadataEntityValidator.validateMetadataEntity( metadataPath, "content.metadata", metadata, schemaState.validatedElement, context ) ) { result = false; } } } return result; } } ================================================ FILE: src/validation/ExtendedObjectsValidators.ts ================================================ import { defined } from "3d-tiles-tools"; import { Validator } from "./Validator"; import { ValidationContext } from "./ValidationContext"; import { RootProperty } from "3d-tiles-tools"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; /** * A class for managing the validation of objects that contain extensions. * * It allows registering `Validator` objects for specific extension * names. The `validateExtendedObject` function will be called for * each `RootProperty` (i.e. for each object that may contain * extensions). When an object contains an extension with one * of the registered names, then the respective validators will * be applied to that object. * * @internal */ export class ExtendedObjectsValidators { /** * The mapping from extension names to the validators that * are used for objects that contain the respective extension. */ private static readonly extendedObjectValidators = new Map< string, Validator >(); /** * The mapping from extension names to the flag that indicates * whether the corresponding validator should override the * default validation process. */ private static readonly overrides = new Map(); /** * Registers a validator for an object with the specified extension. * * When an object has the specified extension, then the given * validator will be applied to this object. * * @param extensionName - The name of the extension * @param extendedObjectValidator - The `Validator` for the extended objects * @param override - Whether the given validator should replace the * default validation. This can be queried with the `hasOverride` method. */ static register( extensionName: string, extendedObjectValidator: Validator, override: boolean ) { ExtendedObjectsValidators.extendedObjectValidators.set( extensionName, extendedObjectValidator ); ExtendedObjectsValidators.overrides.set(extensionName, override); } /** * Returns whether the default validation of the given object * is overridden. This is the case when the object contains * an extension which has been registered by calling the * `register` method, with the `override` flag being `true`. * * @param rootProperty - The `RootProperty` * @returns Whether the default validation is overridden * by one of the registered validators. */ static hasOverride(rootProperty: RootProperty): boolean { const extensions = rootProperty.extensions; if (!defined(extensions)) { return false; } const extensionNames = Object.keys(extensions); for (const extensionName of extensionNames) { const override = ExtendedObjectsValidators.overrides.get(extensionName); if (override === true) { return true; } } return false; } /** * Perform the validation of the given (possibly extended) object. * * If the given object does not have extensions, then `true` will * be returned. * * If there are extensions, then each of them will be examined: * * If a `Validator` instance has been registered for one of the * extensions (by calling the `register` method), then this * validator will be applied to the given object. * * (If no `Validator` instance has been registered, then * a warning will be added to the given context, indicating * that the extension is not supported) * * If any of the registered validators returns `false`, then * `false` will be returned. If all of them consider the object * to be valid, then `true` will be returned. * * @param path - The path for `ValidationIssue` instances * @param rootProperty - The `RootProperty` that may contain extensions * @param context - The `ValidationContext` * @returns Whether the object is valid */ static async validateExtendedObject( path: string, rootProperty: RootProperty, context: ValidationContext ): Promise { // If there are no extensions, consider the object to be valid const extensions = rootProperty.extensions; if (!defined(extensions)) { return true; } // The extensions MUST be an object. This is checked and reported // by the RootPropertyValidator, and therefore, will not reported // again here if (typeof extensions !== "object") { return true; } let allValid = true; const extensionNames = Object.keys(extensions); for (const extensionName of extensionNames) { const extendedObjectValidator = ExtendedObjectsValidators.extendedObjectValidators.get(extensionName); // If an extension was found, but no validator for // that extension was registered, then issue a // warning. if (!defined(extendedObjectValidator)) { const issue = SemanticValidationIssues.EXTENSION_NOT_SUPPORTED( path, extensionName ); context.addIssue(issue); } else { // Validate the object with the registered Validator const isValid = await extendedObjectValidator.validateObject( path, rootProperty, context ); if (!isValid) { allValid = false; } } } return allValid; } } ================================================ FILE: src/validation/ExtensionsDeclarationsValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; /** * A class for validating extension declarations that may appear * as `extensionsUsed` and `extensionsRequired` arrays in a * tileset or the `3DTILES_content_gltf` extension. * * @internal */ export class ExtensionsDeclarationsValidator { /** * Validate the consistency of the given extension declarations. * * This will check whether the given `extensionsUsed` and * `extensionRequired` declarations are consistent: * * - If the objects are defined, they are string arrays with * at least length 1 * - The elements in these arrays are unique * - Extensions that are "required" are also "used" * * @param path - The path for `ValidationIssue` instances * @param tileset - The `Tileset` * @param context - The `ValidationContext` * @returns Whether the declarations have been valid */ static validateExtensionDeclarationConsistency( path: string, extensionsUsed: any, extensionsRequired: any, context: ValidationContext ): boolean { let result = true; // These are the actual sets of unique string values that // are found in 'extensionsUsed' and 'extensionsRequired' const actualExtensionsUsed = new Set(); const actualExtensionsRequired = new Set(); // Validate the extensionsUsed const extensionsUsedPath = path + "/extensionsUsed"; if (defined(extensionsUsed)) { // The extensionsUsed MUST be an array of strings with // a length of at least 1 if ( !BasicValidator.validateArray( extensionsUsedPath, "extensionsUsed", extensionsUsed, 1, undefined, "string", context ) ) { result = false; } else { extensionsUsed.forEach((e: any) => actualExtensionsUsed.add(e)); // The elements in extensionsUsed MUST be unique const elementsUnique = BasicValidator.validateArrayElementsUnique( extensionsUsedPath, "extensionsUsed", extensionsUsed, context ); if (!elementsUnique) { result = false; } } } // Validate the extensionsRequired const extensionsRequiredPath = path + "/extensionsRequired"; if (defined(extensionsRequired)) { // The extensionsRequired MUST be an array of strings with // a length of at least 1 if ( !BasicValidator.validateArray( extensionsRequiredPath, "extensionsRequired", extensionsRequired, 1, undefined, "string", context ) ) { result = false; } else { extensionsRequired.forEach((e: any) => actualExtensionsRequired.add(e)); // The elements in extensionsRequired MUST be unique const elementsUnique = BasicValidator.validateArrayElementsUnique( extensionsRequiredPath, "extensionsRequired", extensionsRequired, context ); if (!elementsUnique) { result = false; } } } // Each extension in extensionsRequired MUST also // appear in extensionsUsed. for (const extensionName of actualExtensionsRequired) { if (!actualExtensionsUsed.has(extensionName)) { const issue = SemanticValidationIssues.EXTENSION_REQUIRED_BUT_NOT_USED( extensionsUsedPath, extensionName ); context.addIssue(issue); result = false; } } return result; } } ================================================ FILE: src/validation/ImplicitTilingValidator.ts ================================================ import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { TemplateUriValidator } from "./TemplateUriValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { TileImplicitTiling } from "3d-tiles-tools"; /** * A class for validations related to `implicitTiling` objects. * * @internal */ export class ImplicitTilingValidator { /** * The valid values for the `subdivisionScheme` property */ static allSubdivisionSchemes: string[] = ["QUADTREE", "OCTREE"]; /** * Performs the validation to ensure that the given object is a * valid `implicitTiling` object. * * @param path - The path for `ValidationIssue` objects * @param implicitTiling - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateImplicitTiling( path: string, implicitTiling: TileImplicitTiling, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "implicitTiling", implicitTiling, context ) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, "implicitTiling", implicitTiling, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( path, implicitTiling, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(implicitTiling)) { return result; } // Validate the subdivisionScheme // The subdivisionSchemes MUST be defined // The subdivisionSchemes MUST be one of the valid values const subdivisionScheme = implicitTiling.subdivisionScheme; const subdivisionSchemePath = path + "/subdivisionScheme"; if ( !BasicValidator.validateEnum( subdivisionSchemePath, "subdivisionScheme", subdivisionScheme, ImplicitTilingValidator.allSubdivisionSchemes, context ) ) { result = false; } // Validate the subtreeLevels // The subtreeLevels MUST be defined // The subtreeLevels MUST be an integer // The subtreeLevels MUST be at least 1 const subtreeLevels = implicitTiling.subtreeLevels; const subtreeLevelsPath = path + "/subtreeLevels"; if ( !BasicValidator.validateIntegerRange( subtreeLevelsPath, "subtreeLevels", subtreeLevels, 1, true, undefined, false, context ) ) { result = false; } // The availableLevels MUST be defined // The availableLevels MUST be an integer // The availableLevels MUST be at least 1 const availableLevels = implicitTiling.availableLevels; const availableLevelsPath = path + "/availableLevels"; if ( !BasicValidator.validateIntegerRange( availableLevelsPath, "availableLevels", availableLevels, 1, true, undefined, false, context ) ) { result = false; } // Validate the subtrees // The subtrees MUST be an object const subtrees = implicitTiling.subtrees; const subtreesPath = path + "/subtrees"; if ( !BasicValidator.validateObject( subtreesPath, "subtrees", subtrees, context ) ) { result = false; } else { // Validate the subtrees uri // The uri MUST be a template URI const subtreesUri = subtrees.uri; const subtreesUriPath = subtreesPath + "/uri"; if ( !TemplateUriValidator.validateTemplateUri( subtreesUriPath, "uri", subtreesUri, subdivisionScheme, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/NumberValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { ValidationIssues } from "../issues/ValidationIssues"; import { JsonValidationIssues } from "../issues/JsonValidationIssues"; /** * A class for validations related to numbers. Specifically, * for checks whether numbers are in the range that is * determined by a (metadata) component type. * * @internal */ export class NumberValidator { /** * Validates that each element of the given array in is in the range * that is determined by the given component type. * * This assumes that the given `componentType` has already been * determined to be a valid one, i.e. is contained in the set of * `MetadataComponentTypes#allComponentTypes`. * * @param path - The path for `ValidationIssue` instances * @param values - The values * @param componentType - The component type * @param context - The `ValidationContext` * @returns Whether the value was in the required range */ static validateRanges( path: string, values: number[] | bigint[], componentType: string, context: ValidationContext ) { let result = true; for (let i = 0; i < values.length; i++) { const value = values[i]; const valuePath = path + "/" + i; if ( !NumberValidator.validateRange( valuePath, "array element", value, componentType, context ) ) { result = false; } } return result; } /** * Validates that the given value is in the range that is determined * by the given component type. * * This assumes that the given `componentType` has already been * determined to be a valid one, i.e. is contained in the set of * `MetadataComponentTypes#allComponentTypes`. * * @param path - The path for `ValidationIssue` instances * @param name - The name of the value * @param value - The value * @param componentType - The component type * @param context - The `ValidationContext` * @returns Whether the value was in the required range */ static validateRange( path: string, name: string, value: number | bigint, componentType: string, context: ValidationContext ): boolean { const min = NumberValidator.minimumValue(componentType); const max = NumberValidator.maximumValue(componentType); if (!defined(min) || !defined(max)) { const message = `Unexpected invalid component type: ${componentType}`; const issue = ValidationIssues.INTERNAL_ERROR(path, message); context.addIssue(issue); return false; } if (value < min || value > max) { const message = `The ${name} has type ${componentType} and must be ` + `in [${min},${max}], but is ${value}`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); return false; } return true; } // Partially adapted from CesiumJS private static maximumValue( componentType: string | undefined ): number | bigint | undefined { switch (componentType) { case "INT8": return 127; case "UINT8": return 255; case "INT16": return 32767; case "UINT16": return 65535; case "INT32": return 2147483647; case "UINT32": return 4294967295; case "INT64": return BigInt("9223372036854775807"); case "UINT64": return BigInt("18446744073709551615"); case "FLOAT32": return 340282346638528859811704183484516925440.0; case "FLOAT64": return Number.MAX_VALUE; } return undefined; } private static minimumValue( componentType: string | undefined ): number | bigint | undefined { switch (componentType) { case "INT8": return -128; case "UINT8": return 0; case "INT16": return -32768; case "UINT16": return 0; case "INT32": return -2147483648; case "UINT32": return 0; case "INT64": return BigInt("-9223372036854775808"); case "UINT64": return BigInt(0); case "FLOAT32": return -340282346638528859811704183484516925440.0; case "FLOAT64": return -Number.MAX_VALUE; } return undefined; } } ================================================ FILE: src/validation/PropertiesValidator.ts ================================================ import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { Properties } from "3d-tiles-tools"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; /** * A class for validations related to `tileset.properties` objects. Apologies * for the confusing name... * * @internal */ export class PropertiesValidator { /** * Performs the validation to ensure that the given object is a * valid `tileset.properties` object. * * Note that the `tileset.properties` is actually a dictionary, * that maps names to `Properties` objects (which, despite * the name, are actually a single property description) * * @param properties - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateProperties( tilesetProperties: { [key: string]: Properties }, context: ValidationContext ): boolean { const path = "/properties"; // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "properties", tilesetProperties, context ) ) { return false; } let result = true; // Validate all entries of the properties dictionary for (const [key, value] of Object.entries(tilesetProperties)) { // TODO Technically, the key should be validated to be in the batch table... if (PropertiesValidator.validateSingleProperties(key, value, context)) { result = false; } } return result; } /** * Performs the validation to ensure that the given object is a * valid `Properties` object. * * Note that the `Properties` type (despite the name) represents only * a single property - i.e. one value in the `tileset.properties` * dictionary. * * @param name - The property name * @param properties - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateSingleProperties( name: string, properties: Properties, context: ValidationContext ): boolean { const path = "/properties/" + name; // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, properties, context)) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, name, properties, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( path, properties, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(properties)) { return result; } // The minimum and maximum MUST be defined and be numbers const minimum = properties.minimum; const maximum = properties.maximum; const minimumIsValid = BasicValidator.validateNumber( path + "/minimum", "minimum", minimum, context ); const maximumIsValid = BasicValidator.validateNumber( path + "/maximum", "maximum", maximum, context ); if (minimumIsValid && maximumIsValid) { // The MUST NOT be larger than the maximum if (minimum > maximum) { const message = `The minimum may not be larger than the maximum, ` + `but the minimum is ${minimum} and the maximum is ${maximum}`; const issue = SemanticValidationIssues.PROPERTIES_MINIMUM_LARGER_THAN_MAXIMUM( path, message ); context.addIssue(issue); result = false; } } return result; } } ================================================ FILE: src/validation/RootPropertyValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { RootProperty } from "3d-tiles-tools"; import { JsonValidationIssues } from "../issues/JsonValidationIssues"; /** * A class for validations related to `rootProperty` objects. * This is the "base class" of the schema definitions that * nearly all schemas of the 3D Tiles specification refer to, * and which defines the `extensions` and `extras` properties. * * @internal */ export class RootPropertyValidator { /** * Performs the validation to ensure that the given object is a * valid `rootProperty` object. * * This will add all extension names that are found to the * given validation context. * * @param path - The path for `ValidationIssue` instances * @param name - The name of the object * @param rootProperty - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateRootProperty( path: string, name: string, rootProperty: RootProperty, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, rootProperty, context)) { return false; } let result = true; // Validate the extensions const extensions = rootProperty.extensions; const extensionsPath = path + "/extensions"; if (defined(extensions)) { // The extensions MUST be an object if ( !BasicValidator.validateObject( extensionsPath, "extensions", extensions, context ) ) { result = false; } else { // Each value of the extensions MUST be an object const extensionNames = Object.keys(extensions); for (const extensionName of extensionNames) { const extension = extensions[extensionName]; const extensionPath = extensionsPath + "/" + extensionName; if ( !BasicValidator.validateObject( extensionPath, extensionName, extension, context ) ) { result = false; } else { context.addExtensionFound(extensionName); } } } } // Validate the extras const extras = rootProperty.extras; const extrasPath = path + "/extras"; if (defined(extras)) { // The extras may have any type. But when they are // not an object, a warning will be generated. if (typeof extras !== "object") { const issue = JsonValidationIssues.TYPE_UNEXPECTED( extrasPath, "extras", "object", typeof extras ); context.addIssue(issue); } } return result; } } ================================================ FILE: src/validation/StatisticsClassValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { StatisticsClass } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { StructureValidationIssues } from "../issues/StructureValidationIssues"; import { defaultValue } from "3d-tiles-tools"; /** * A class for validations related to `StatisticsClass` objects. * * @internal */ export class StatisticsClassValidator { /** * Performs the validation to ensure that the given object is a * valid `statisticsClass` object. * * @param statisticsClass - The object to validate * @param className - The name of the class, used as the * key in the `statistics.classes` dictionary, as well as the * key in the `schema.classes` dictionary. * @param schema - The `Schema` object. This is either the `tileset.schema`, * or the `Schema` object that was read from the `schemaUri`. * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateStatisticsClass( statisticsClass: StatisticsClass, className: string, schema: Schema, context: ValidationContext ): boolean { const classPath = "/statistics/classes/" + className; // Make sure that the given value is an object if ( !BasicValidator.validateObject( classPath, className, statisticsClass, context ) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( classPath, className, statisticsClass, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( classPath, schema, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(schema)) { return result; } // Each class that appears in the statistics MUST be // one of the classes defined in the schema const metadataClasses: any = defined(schema.classes) ? schema.classes : {}; const metadataClass = metadataClasses[className]; if (!defined(metadataClass)) { const message = `Statistics contain a class name ${className}, ` + `but the schema does not define this class`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( classPath, message ); context.addIssue(issue); result = false; } else { // Each property name of the statistics class MUST be a // property name of the schema class const metadataClassPropertyNames = Object.keys(metadataClass.properties); // The statistics class MUST have at least 1 property const statisticsClassProperties = defaultValue( statisticsClass.properties, {} ); if ( !BasicValidator.validateNumberOfProperties( classPath, "properties", statisticsClassProperties, 1, undefined, context ) ) { result = false; } else { for (const statisticsClassPropertyName of Object.keys( statisticsClassProperties )) { if ( !metadataClassPropertyNames.includes(statisticsClassPropertyName) ) { const message = `Statistics class '${className}' contains a property name ` + `'${statisticsClassPropertyName}', but the schema class does ` + `not define this property`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( classPath, message ); context.addIssue(issue); result = false; } else { // TODO Validate the constraints for the statistics.class.property. // This COULD include checks for (min>max). But first, it should // check the types (e.g. that 'min' is only used for numeric types) } } } } return result; } } ================================================ FILE: src/validation/StatisticsValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { Statistics } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { StatisticsClassValidator } from "./StatisticsClassValidator"; import { ValidatedElement } from "./ValidatedElement"; import { StructureValidationIssues } from "../issues/StructureValidationIssues"; /** * A class for validations related to `statistics` objects. * * @internal */ export class StatisticsValidator { /** * Performs the validation to ensure that the given object is a * valid `statistics` object. * * @param path - The path for `ValidationIssue` instances * @param statistics - The object to validate * @param schemaState - The state of the schema validation. * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateStatistics( path: string, statistics: Statistics, schemaState: ValidatedElement, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, "statistics", statistics, context) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, "statistics", statistics, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( path, statistics, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(statistics)) { return result; } // Validate the classes const classes = statistics.classes; const classesPath = path + "/classes"; if (defined(classes)) { // The classes MUST be an object if ( !BasicValidator.validateObject(classesPath, "classes", classes, context) ) { result = false; } else { // The classes MUST have at least 1 property if ( !BasicValidator.validateNumberOfProperties( classesPath, "classes", classes, 1, undefined, context ) ) { result = false; } // If there are classes, then there must be a schema if (!schemaState.wasPresent) { const message = "The tileset defines 'statistics.classes' but does not have a schema"; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( classesPath, message ); context.addIssue(issue); result = false; } else if (defined(schemaState.validatedElement)) { // Validate all entries of the classes dictionary for (const className of Object.keys(classes)) { const statisticsClass = classes[className]; if ( !StatisticsClassValidator.validateStatisticsClass( statisticsClass, className, schemaState.validatedElement, context ) ) { result = false; } } } } } return result; } } ================================================ FILE: src/validation/StringValidator.ts ================================================ import { ValidationContext } from "./ValidationContext"; import { JsonValidationIssues } from "../issues/JsonValidationIssues"; import { BasicValidator } from "./BasicValidator"; /** * A class for the validation of strings that must follow a * certain pattern. * * @internal */ export class StringValidator { /** * Validate that the given string is a valid identifier string, * as defined in the 3D Metadata Specification. * * If the given value is not defined, then a `PROPERTY_MISSING` * validation issue will be added to the given validation * context, and `false` is returned. * * If the given value is not a string, then a `TYPE_MISMATCH` * validation issue will be added to the given validation * context, and `false` is returned. * * If the given string does not match the regex for a valid * identifier string, then a `STRING_PATTERN_MISMATCH` * validation issue will be added to the given validation * context, and `false` is returned. * * Otherwise, `true` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is an identifier string */ static validateIdentifierString( path: string, name: string, value: string, context: ValidationContext ): boolean { if (!BasicValidator.validateString(path, name, value, context)) { return false; } const idRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/; if (!idRegex.test(value)) { const issue = JsonValidationIssues.STRING_PATTERN_MISMATCH( path, name, value, idRegex.toString() ); context.addIssue(issue); return false; } return true; } /** * Validate that the given string is a valid ISO8601 string. * * If the given value is not defined, then a `PROPERTY_MISSING` * validation issue will be added to the given validation * context, and `false` is returned. * * If the given value is not a string, then a `TYPE_MISMATCH` * validation issue will be added to the given validation * context, and `false` is returned. * * If the given string is not a valid ISO8601 string, then a * `STRING_PATTERN_MISMATCH` validation issue will be added * to the given validation context, and `false` is returned. * * Otherwise, `true` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The value * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is an ISO8601 string */ static validateIso8601String( path: string, name: string, value: string, context: ValidationContext ): boolean { if (!BasicValidator.validateString(path, name, value, context)) { return false; } if (!StringValidator.isValidIso8601String(value)) { const message = `The string property ${name} must be a valid ISO8601 string, ` + `but is '${value}'`; const issue = JsonValidationIssues.STRING_VALUE_INVALID(path, message); context.addIssue(issue); return false; } return true; } /** * Returns whether the given string is a valid ISO8601 string. * * Extracted from the "validator.js" library. * * @param str - The string * @returns Whether the string is a valid ISO8601 string */ private static isValidIso8601String(str: string) { // The following is extracted from the "validator.js" library, at // https://github.com/validatorjs/validator.js/blob/ // f54599c8fbd43b1febb2cbc18190107417fbdd5e/src/lib/isISO8601.js // (with minor adjustments for linting) // // The copyright header of this library: // // Copyright (c) 2018 Chris O'Hara // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // from http://goo.gl/0ejHHW const iso8601 = /^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-3])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/; const check = iso8601.test(str); if (!check) { return false; } // str must have passed the ISO8601 check // this check is meant to catch invalid dates // like 2009-02-31 // first check for ordinal dates const ordinalMatch = str.match(/^(\d{4})-?(\d{3})([ T]{1}\.*|$)/); if (ordinalMatch) { const oYear = Number(ordinalMatch[1]); const oDay = Number(ordinalMatch[2]); // if is leap year if ((oYear % 4 === 0 && oYear % 100 !== 0) || oYear % 400 === 0) return oDay <= 366; return oDay <= 365; } const matches = str.match(/(\d{4})-?(\d{0,2})-?(\d*)/); if (!matches) { return false; } const match = matches.map(Number); const year = match[1]; const month = match[2]; const day = match[3]; const monthString = month ? `0${month}`.slice(-2) : month; const dayString = day ? `0${day}`.slice(-2) : day; // create a date object and compare const d = new Date(`${year}-${monthString || "01"}-${dayString || "01"}`); if (month && day) { return ( d.getUTCFullYear() === year && d.getUTCMonth() + 1 === month && d.getUTCDate() === day ); } return true; } } ================================================ FILE: src/validation/StructureValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { StructureValidationIssues } from "../issues/StructureValidationIssues"; /** * A class for the validation of JSON structures. * * This checks for the presence of properties that are required * and the absence of properties that are disallowed, based on * the absence or presence of other properties or their values. * * @internal */ export class StructureValidator { /** * Validate that the given value does not have any of the * given disallowed properties. * * If the given value is an object that contains any of the disallowed * properties, then a `DISALLOWED_VALUE_FOUND` issue is added to the * given validation context (for each of them), and `false` is * returned. * * Otherwise, `true` is returned. * * @param path - The path for the `ValidationIssue` message * @param name - The name for the `ValidationIssue` message * @param value - The object that may contain the properties * @param disallowedProperties - The array of names of properties * that may not be defined * @param context - The `ValidationContext` to add the issue to * @returns Whether the given value is one of the allowed values */ static validateDisallowedProperties( path: string, name: string, value: any, disallowedProperties: string[], context: ValidationContext ) { let result = true; for (const propertyName of disallowedProperties) { const propertyValue = value[propertyName]; if (defined(propertyValue)) { const message = `The ${name} may not define the ${propertyName}`; const issue = StructureValidationIssues.DISALLOWED_VALUE_FOUND( path, message ); context.addIssue(issue); result = false; } } return result; } } ================================================ FILE: src/validation/SubtreeConsistencyValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { Subtree } from "3d-tiles-tools"; import { Availability } from "3d-tiles-tools"; import { TileImplicitTiling } from "3d-tiles-tools"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; import { ImplicitTilings } from "3d-tiles-tools"; import { BinaryBufferStructureValidator } from "./BinaryBufferStructureValidator"; import { BinaryBufferStructure } from "3d-tiles-tools"; /** * A class for the validation of the consistency of subtrees. * * The functions in this class are supposed to be called after the * basic validity has been checked with the `SubtreeValidator`. * * They perform the validity checks for the buffer data layout * and availability data, referring to the information that is * given in the `TileImplicitTiling` structure. * * They will **NOT** analyze the actual buffer data. If the subtree * data is consistent, then the actual buffer data is validated based * on the high-level (model) objects, using a `SubtreeInfoValidator`. * * @internal */ export class SubtreeConsistencyValidator { /** * Perform basic consistency validation on the given subtree object. * * This assumes that the basic (JSON-level) structural validations * have already been performed. It will only validate the consistency * of the memory layout of buffer views, buffers, and the availability * information. * * @param path - The path for `ValidationIssue` instances * @param subtree - The `Subtree` object * @param implicitTiling - The `TileImplicitTiling` object. If this * is not given, then the validation of the availability information * (that requires information about the subtree structure) will be * skipped * @param context - The `ValidationContext` * @returns Whether the data was consistent */ static validateSubtreeConsistency( path: string, subtree: Subtree, implicitTiling: TileImplicitTiling | undefined, context: ValidationContext ): boolean { // The buffers and bufferViews are optional. If they are both defined, // then the SubtreeValidator already validated them on the JSON level. // Here, validate their consistency in terms of memory layout const buffers = subtree.buffers; const bufferViews = subtree.bufferViews; if (defined(buffers) && defined(bufferViews)) { const binaryBufferStructure: BinaryBufferStructure = { buffers: buffers, bufferViews: bufferViews, }; if ( !BinaryBufferStructureValidator.validateBinaryBufferStructureConsistency( path, binaryBufferStructure, context ) ) { return false; } } if (defined(implicitTiling)) { if ( !SubtreeConsistencyValidator.validateSubtreeAvailabilityConsistency( path, subtree, implicitTiling, context ) ) { return false; } } return true; } /** * Performs the consistency checks for the `tileAvailability`, * `contentAvailability` and `childSubtreeAvailability` objects * in the given subtree. * * @param path - The path for the `ValidationIssue` instances * @param subtree - The `Subtree` object * @param implicitTiling - The `TileImplicitTiling` that defines the * subtree structure * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateSubtreeAvailabilityConsistency( path: string, subtree: Subtree, implicitTiling: TileImplicitTiling, context: ValidationContext ): boolean { let result = true; // The implicitTiling has already been validated to have a valid // subdivisionScheme. Therefore, the methods from `ImplicitTilings` // should never throw an `ImplicitTilingError` here. // Validate the consistency of the tileAvailability const tileAvailability = subtree.tileAvailability; const tileAvailabilityPath = path + "/tileAvailability"; const tileAvailabilityRequiredLengthInBits = ImplicitTilings.computeNumberOfNodesPerSubtree(implicitTiling); if ( !SubtreeConsistencyValidator.validateAvailabilityConsistency( tileAvailabilityPath, tileAvailability, tileAvailabilityRequiredLengthInBits, subtree, implicitTiling, context ) ) { result = false; } // Validate the consistency of the contentAvailability const contentAvailability = subtree.contentAvailability; const contentAvailabilityPath = path + "/contentAvailability"; const contentAvailabilityRequiredLengthInBits = ImplicitTilings.computeNumberOfNodesPerSubtree(implicitTiling); if (defined(contentAvailability)) { // Validate the consistency of each contentAvailability for (let i = 0; i < contentAvailability.length; i++) { const elementPath = contentAvailabilityPath + "/" + i; const element = contentAvailability[i]; if ( !SubtreeConsistencyValidator.validateAvailabilityConsistency( elementPath, element, contentAvailabilityRequiredLengthInBits, subtree, implicitTiling, context ) ) { result = false; } } } // Validate the consistency of the childSubtreeAvailability const childSubtreeAvailability = subtree.childSubtreeAvailability; const childSubtreeAvailabilityPath = path + "/childSubtreeAvailability"; const childSubtreeAvailabilityRequiredLengthInBits = ImplicitTilings.computeNumberOfNodesInLevel( implicitTiling, implicitTiling.subtreeLevels ); if ( !SubtreeConsistencyValidator.validateAvailabilityConsistency( childSubtreeAvailabilityPath, childSubtreeAvailability, childSubtreeAvailabilityRequiredLengthInBits, subtree, implicitTiling, context ) ) { result = false; } return result; } /** * Perform the consistency checks for the given availability object. * * This will check whether the object refers to a valid buffer view, * and the buffer view has a length that is sufficient for the * respective availability information. * * @param path - The path for the `ValidationIssue` instances * @param availability - The `Availability` object * @param requiredLengthInBits - The length, in bits, that is required * for storing the given availability information * @param subtree - The `Subtree` object * @param implicitTiling - The `TileImplicitTiling` that defines the * subtree structure * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateAvailabilityConsistency( path: string, availability: Availability, requiredLengthInBits: number, subtree: Subtree, implicitTiling: TileImplicitTiling, context: ValidationContext ): boolean { let result = true; const bufferViews = defaultValue(subtree.bufferViews, []); // Validate the bitstream const bitstream = availability.bitstream; const bitstreamPath = path + "/bitstream"; if (defined(bitstream)) { // The bitstream (index) MUST be smaller than the number of bufferViews if ( !BasicValidator.validateIntegerRange( bitstreamPath, "bitstream", bitstream, 0, true, bufferViews.length, false, context ) ) { result = false; } else { // The required length in bits MUST fit into the bufferView const bufferView = bufferViews[bitstream]; const requiredLengthInBytes = Math.ceil(requiredLengthInBits / 8); if (requiredLengthInBytes !== bufferView.byteLength) { const subtreeLevels = implicitTiling.subtreeLevels; const subdivisionScheme = implicitTiling.subdivisionScheme; const message = `The availability for ${subtreeLevels} levels in a subtree ` + `with subdivision scheme ${subdivisionScheme} ` + `requires ${requiredLengthInBits} bits (${requiredLengthInBytes} ` + `bytes), but the bitstream ${bitstream} refers to a buffer view ` + `that has a byte length of ${bufferView.byteLength}`; const issue = SemanticValidationIssues.SUBTREE_AVAILABILITY_INCONSISTENT( path, message ); context.addIssue(issue); result = false; } } } return result; } } ================================================ FILE: src/validation/SubtreeInfoValidator.ts ================================================ import { BinarySubtreeData, defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { SubtreeInfos } from "3d-tiles-tools"; import { AvailabilityInfo } from "3d-tiles-tools"; import { ImplicitTilings } from "3d-tiles-tools"; import { TileImplicitTiling } from "3d-tiles-tools"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; import { ImplicitTilingError } from "3d-tiles-tools"; import { ValidationIssues } from "../issues/ValidationIssues"; /** * A class for validation of subtree information. * * The methods in this class assume that the basic structure * of the given objects has already been validated, using * the `SubtreeValidator` and `SubtreeConsistencyValidator`. * * They will attempt to create instances of the "high level" * convenience classes from the `implicitTiling` package, * and perform consistency checks with these instances. * * @internal */ export class SubtreeInfoValidator { static async validateSubtreeInfo( path: string, binarySubtreeData: BinarySubtreeData, implicitTiling: TileImplicitTiling, context: ValidationContext ): Promise { let optionalSubtreeInfo = undefined; try { optionalSubtreeInfo = SubtreeInfos.create( binarySubtreeData, implicitTiling ); } catch (error) { if (error instanceof ImplicitTilingError) { const message = `Could not read subtree data: ${error.message}`; const issue = SemanticValidationIssues.IMPLICIT_TILING_ERROR( path, message ); context.addIssue(issue); return false; } const message = `Internal error while reading subtree data: ${error}`; const issue = ValidationIssues.INTERNAL_ERROR(path, message); context.addIssue(issue); return false; } const subtreeInfo = optionalSubtreeInfo; const subtree = binarySubtreeData.subtree; let result = true; // Validate the tileAvailability const tileAvailabilityInfo = subtreeInfo.tileAvailabilityInfo; const tileAvailabilityInfoPath = path + "/tileAvailability"; // Validate the tileAvailability availableCount if ( !SubtreeInfoValidator.validateAvailableCount( tileAvailabilityInfoPath, "tile availability", subtree.tileAvailability.availableCount, tileAvailabilityInfo, context ) ) { result = false; } // Validate the tileAvailability consistency if ( !SubtreeInfoValidator.validateTileAvailabilityConsistency( tileAvailabilityInfoPath, tileAvailabilityInfo, implicitTiling, context ) ) { result = false; } // Validate the childSubtreeAvailability const childSubtreeAvailabilityInfo = subtreeInfo.childSubtreeAvailabilityInfo; const childSubtreeAvailabilityInfoPath = path + "/childSubtreeAvailability"; // Validate the childSubtreeAvailability availableCount if ( !SubtreeInfoValidator.validateAvailableCount( childSubtreeAvailabilityInfoPath, "child subtree availability", subtree.childSubtreeAvailability.availableCount, childSubtreeAvailabilityInfo, context ) ) { result = false; } // TODO The validation of whether the child subtrees that are // marked as available are actually available is not done yet // (Should this really try to resolve the resource?) // Validate the contentAvailability const contentAvailabilityInfos = subtreeInfo.contentAvailabilityInfos; const contentAvailabilityInfosPath = path + "/contentAvailability"; const contentAvailability = defaultValue(subtree.contentAvailability, []); for (let i = 0; i < contentAvailabilityInfos.length; i++) { // Validate each contentAvailability const contentAvailabilityInfo = contentAvailabilityInfos[i]; const contentAvailabilityInfoPath = contentAvailabilityInfosPath + "/" + i; // Validate the contentAvailability availableCount if ( !SubtreeInfoValidator.validateAvailableCount( contentAvailabilityInfoPath, `content availability ${i}`, contentAvailability[i].availableCount, contentAvailabilityInfo, context ) ) { result = false; } // Validate that for each available content, there is als // an available tile if ( !SubtreeInfoValidator.validateTileAvailabilityPresence( path, tileAvailabilityInfo, contentAvailabilityInfo, i, implicitTiling, context ) ) { result = false; } } return result; } /** * Validates that the `availableCount` - if it is defined - * properly reflects the actual number of available elements * in the given availability info. * * If this is the case, then `true` is returned. * * If this is not the case, a `SUBTREE_AVAILABILITY_INCONSISTENT` * issue will be added to the given context, and `false` is returned. * * @param path - The path for `ValidationIssue` instances * @param name - The name of the availability object * @param availableCount - * @param availabilityInfo - The `AvailabilityInfo` * @param context - The `ValidationContext` * @returns Whether the availability was consistent */ private static validateAvailableCount( path: string, name: string, availableCount: number | undefined, availabilityInfo: AvailabilityInfo, context: ValidationContext ): boolean { // The availableCount is not required if (!defined(availableCount)) { return true; } // Count the number of actually available elements let actualAvailableCount = 0; for (let index = 0; index < availabilityInfo.length; index++) { const available = availabilityInfo.isAvailable(index); if (available) { actualAvailableCount++; } } if (actualAvailableCount === availableCount) { return true; } const message = `The ${name} declares an 'availableCount' of ${availableCount} ` + `but the number of available elements is ${actualAvailableCount}`; const issue = SemanticValidationIssues.SUBTREE_AVAILABILITY_INCONSISTENT( path, message ); context.addIssue(issue); return false; } /** * Validate that the given tile availability is consistent, * meaning that for each tile that is available, the parent * tile is also available. * * If this is the case, then `true` is returned. * * If this is not the case, a `SUBTREE_AVAILABILITY_INCONSISTENT` * issue will be added to the given context, and `false` is returned. * * @param path - The path for `ValidationIssue` instances * @param tileAvailabilityInfo - The `AvailabilityInfo` * @param implicitTiling - The `TileImplicitTiling` object * @param context - The `ValidationContext` * @returns Whether the availability was consistent */ static validateTileAvailabilityConsistency( path: string, tileAvailabilityInfo: AvailabilityInfo, implicitTiling: TileImplicitTiling, context: ValidationContext ): boolean { let result = true; const coordinates = ImplicitTilings.createSubtreeCoordinatesIterator(implicitTiling); for (const c of coordinates) { const p = c.parent(); if (defined(p)) { const cIndex = c.toIndex(); const pIndex = p.toIndex(); const cAvailable = tileAvailabilityInfo.isAvailable(cIndex); const pAvailable = tileAvailabilityInfo.isAvailable(pIndex); if (cAvailable && !pAvailable) { const message = `Tile availability declares tile at ${c} ` + `with index ${cIndex} to be available, but its parent ` + `tile at ${p} with index ${pIndex} is not available`; const issue = SemanticValidationIssues.SUBTREE_AVAILABILITY_INCONSISTENT( path, message ); context.addIssue(issue); result = false; } } } return result; } /** * Validate that the given tile availability matches the given content * availability, meaning that for each content that is available, the * corresponding tile is also available. * * If this is the case, then `true` is returned. * * If this is not the case, a `SUBTREE_AVAILABILITY_INCONSISTENT` * issue will be added to the given context, and `false` is returned. * * @param path - The path for `ValidationIssue` instances * @param tileAvailabilityInfo - The `AvailabilityInfo` for tiles * @param contentAvailabilityInfo - The `AvailabilityInfo` for content * @param contentAvailabilityIndex - The index of the content * @param implicitTiling - The `TileImplicitTiling` object * @param context - The `ValidationContext` * @returns Whether the availability was consistent */ static validateTileAvailabilityPresence( path: string, tileAvailabilityInfo: AvailabilityInfo, contentAvailabilityInfo: AvailabilityInfo, contentAvailabilityIndex: number, implicitTiling: TileImplicitTiling, context: ValidationContext ): boolean { let result = true; const coordinates = ImplicitTilings.createSubtreeCoordinatesIterator(implicitTiling); for (const c of coordinates) { const index = c.toIndex(); const contentAvailable = contentAvailabilityInfo.isAvailable(index); const tileAvailable = tileAvailabilityInfo.isAvailable(index); if (contentAvailable && !tileAvailable) { const message = `Content availability ${contentAvailabilityIndex} declares ` + `content at ${c} with index ${index} to be available, but ` + `the corresponding tile is not available`; const issue = SemanticValidationIssues.SUBTREE_AVAILABILITY_INCONSISTENT( path, message ); context.addIssue(issue); result = false; } } return result; } } ================================================ FILE: src/validation/SubtreeValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { Buffers } from "3d-tiles-tools"; import { ResourceResolver } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { Subtree } from "3d-tiles-tools"; import { Availability } from "3d-tiles-tools"; import { TileImplicitTiling } from "3d-tiles-tools"; import { MetadataUtilities } from "3d-tiles-tools"; import { BinarySubtreeData } from "3d-tiles-tools"; import { BinarySubtreeDataResolver } from "3d-tiles-tools"; import { BinaryPropertyTable } from "3d-tiles-tools"; import { BinaryMetadata } from "3d-tiles-tools"; import { Validator } from "./Validator"; import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { BinaryValidator } from "./BinaryValidator"; import { SubtreeConsistencyValidator } from "./SubtreeConsistencyValidator"; import { SubtreeInfoValidator } from "./SubtreeInfoValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { ValidatedElement } from "./ValidatedElement"; import { BinaryBufferStructureValidator } from "./BinaryBufferStructureValidator"; import { BinaryPropertyTableValidator } from "./metadata/BinaryPropertyTableValidator"; import { MetadataEntityValidator } from "./metadata/MetadataEntityValidator"; import { PropertyTablesDefinitionValidator } from "./metadata/PropertyTablesDefinitionValidator"; import { JsonValidationIssues } from "../issues/JsonValidationIssues"; import { IoValidationIssues } from "../issues/IoValidationIssue"; import { StructureValidationIssues } from "../issues/StructureValidationIssues"; /** * A class for validations related to `subtree` objects that have * been read from subtree JSON files, or the JSON part of a * binary 'subtree' file. * * This class is only performing the high-level validation that * is related to the binary data and JSON structure. The * detailed consistency validations are done by a * `SubtreeConsistencyValidator`. * * @internal */ export class SubtreeValidator implements Validator { /** * Information about the validation state of the metadata schema */ private readonly schemaState: ValidatedElement; /** * The `TileImplicitTiling` object that carries information * about the expected structure of the subtree */ private readonly implicitTiling: TileImplicitTiling | undefined; /** * The `ResourceResolver` that will be used to resolve * buffer URIs */ private readonly resourceResolver: ResourceResolver; /** * Creates a new instance. * * @param schemaState - The state of the validation of the `Schema` * @param implicitTiling - The `TileImplicitTiling` that * defines the expected structure of the subtree * @param resourceResolver - The `ResourceResolver` that * will be used to resolve buffer URIs. */ constructor( schemaState: ValidatedElement, implicitTiling: TileImplicitTiling | undefined, resourceResolver: ResourceResolver ) { this.schemaState = schemaState; this.implicitTiling = implicitTiling; this.resourceResolver = resourceResolver; } /** * Implementation of the `Validator` interface that performs the * validation of the given buffer, which is supposed to * contain subtree data, either in binary form or as JSON. * * @param path - The path for `ValidationIssue` instances * @param input - The subtree data * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished * and indicates whether the object was valid or not. */ async validateObject( path: string, input: Buffer, context: ValidationContext ): Promise { const isSubt = Buffers.getMagicString(input) === "subt"; if (isSubt) { const result = await this.validateSubtreeBinaryData(path, input, context); return result; } const isJson = Buffers.isProbablyJson(input); if (isJson) { const result = await this.validateSubtreeJsonData(path, input, context); return result; } const message = `Subtree input data was neither a subtree binary nor JSON`; const issue = IoValidationIssues.IO_ERROR(path, message); context.addIssue(issue); return false; } /** * Performs the validation of the given buffer, which contains the * data from a binary subtree file * * @param path - The path for `ValidationIssue` instances * @param input - The contents of a binary subtree file * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished * and indicates whether the object was valid or not. */ private async validateSubtreeBinaryData( path: string, input: Buffer, context: ValidationContext ): Promise { // Validate the header length const headerByteLength = 24; if ( !BinaryValidator.validateMinLength( path, "input", headerByteLength, input.length, context ) ) { return false; } // Validate the magic (this was usually already done before entering // this method, but done to perform a complete validation here, // regardless of where this method is called) // The magic MUST be "subt" const magic = input.toString("utf8", 0, 4); if (!BinaryValidator.validateValue(path, "magic", "subt", magic, context)) { return false; } // Validate the version // The version MUST be 1 const version = input.readUInt32LE(4); if (!BinaryValidator.validateValue(path, "version", 1, version, context)) { return false; } // Validate the jsonByteLength // The jsonByteLength MUST be aligned to 8 const jsonByteLength = input.readBigUint64LE(8); if ( !BinaryValidator.validateAlignment( path, "JSON byte length", jsonByteLength, 8, context ) ) { return false; } // Validate the binaryByteLength // The binaryByteLength MUST be aligned to 8 const binaryByteLength = input.readBigUint64LE(16); if ( !BinaryValidator.validateAlignment( path, "binary byte length", binaryByteLength, 8, context ) ) { return false; } // Validate the that the total byte length from the // header matches the length of the input data const computedByteLength = BigInt(headerByteLength) + jsonByteLength + binaryByteLength; if ( !BinaryValidator.validateLength( path, "header, JSON byte length, and binary byte length", input.length, computedByteLength, context ) ) { return false; } // Extract the JSON buffer const jsonStartByteOffset = headerByteLength; const jsonEndByteOffset = jsonStartByteOffset + Number(jsonByteLength); const jsonBuffer = input.subarray(jsonStartByteOffset, jsonEndByteOffset); // Try to parse the JSON let subtree: Subtree; try { const jsonString = jsonBuffer.toString(); subtree = JSON.parse(jsonString); } catch (error) { const message = `Could not parse subtree JSON: ${error}`; const issue = IoValidationIssues.JSON_PARSE_ERROR(path, message); context.addIssue(issue); return false; } // First, validate the basic JSON structure of the buffers // and bufferViews. When they are invalid, then the binary // subtree data cannot be resolved, and the subtree is // considered to be invalid. const firstBufferUriIsRequired = binaryByteLength === 0n; const bufferStructureValid = BinaryBufferStructureValidator.validateBinaryBufferStructure( path, subtree.buffers, subtree.bufferViews, firstBufferUriIsRequired, context ); if (!bufferStructureValid) { return false; } const binarySubtreeData = await BinarySubtreeDataResolver.resolveFromBuffer( input, this.resourceResolver ); const result = this.validateSubtree(path, binarySubtreeData, context); return result; } /** * Performs the validation of the subtree JSON data in the given buffer * * @param path - The path for `ValidationIssue` instances * @param input - The buffer that contains the subtree JSON data * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished * and indicates whether the object was valid or not. */ private async validateSubtreeJsonData( path: string, input: Buffer, context: ValidationContext ): Promise { const bom = Buffers.getUnicodeBOMDescription(input); if (defined(bom)) { const message = `Unexpected BOM in subtree JSON buffer: ${bom}`; const issue = IoValidationIssues.JSON_PARSE_ERROR(path, message); context.addIssue(issue); return false; } try { const inputString = input.toString(); const subtree: Subtree = JSON.parse(inputString); // First, validate the basic JSON structure of the buffers // and bufferViews. When they are invalid, then the binary // subtree data cannot be resolved, and the subtree is // considered to be invalid. const firstBufferUriIsRequired = true; const bufferStructureValid = BinaryBufferStructureValidator.validateBinaryBufferStructure( path, subtree.buffers, subtree.bufferViews, firstBufferUriIsRequired, context ); if (!bufferStructureValid) { return false; } const binarySubtreeData = await BinarySubtreeDataResolver.resolveFromJson( subtree, this.resourceResolver ); const result = await this.validateSubtree( path, binarySubtreeData, context ); return result; } catch (error) { console.log(error); const issue = IoValidationIssues.JSON_PARSE_ERROR(path, `${error}`); context.addIssue(issue); return false; } } /** * Performs the validation of the binary subtree data * * @param path - The path for `ValidationIssue` instances * @param binarySubtreeData - The `BinarySubtreeData` object * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished * and indicates whether the object was valid or not. */ private async validateSubtree( path: string, binarySubtreeData: BinarySubtreeData, context: ValidationContext ): Promise { const subtree = binarySubtreeData.subtree; let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, "subtree", subtree, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject(path, subtree, context) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(subtree)) { return result; } // Validate the structure of the given subtree object, // on the level of JSON validity const structureIsValid = this.validateSubtreeObject(path, subtree, context); if (!structureIsValid) { result = false; return result; } // If the structure was valid, perform the deeper consistency validation // of the binary buffer structure and availability consistency if ( !SubtreeConsistencyValidator.validateSubtreeConsistency( path, subtree, this.implicitTiling, context ) ) { result = false; return result; } // If the structure was valid and consistent, perform the // validation that actually involves reading the binary data // Validate the binary representation of the property tables const binaryPropertyTablesValid = await this.validateBinaryPropertyTables( path, binarySubtreeData, context ); if (!binaryPropertyTablesValid) { result = false; } // Validate the consistency of the binary availability data if (defined(this.implicitTiling)) { const dataIsConsistent = await SubtreeInfoValidator.validateSubtreeInfo( path, binarySubtreeData, this.implicitTiling, context ); if (!dataIsConsistent) { result = false; return result; } } return result; } /** * Performs the validation of the given `Subtree` object, on * the level of JSON validity. * * @param path - The path for `ValidationIssue` instances * @param subtree - The `Subtree` object * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished */ private validateSubtreeObject( path: string, subtree: Subtree, context: ValidationContext ): boolean { if (!this.validateSubtreeBasic(path, subtree, context)) { return false; } if (!this.validateMetadata(path, subtree, context)) { return false; } return true; } /** * Performs the validation to ensure that the given object is a * valid `subtree` object. * * This method will perform the basic validation of the JSON part, * excluding the metadata. * The consistency and binary data will be validated separately. * * @param path - The path for the `ValidationIssue` instances * @param subtree - The `Subtree` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private validateSubtreeBasic( path: string, subtree: Subtree, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "subtree", subtree, context)) { return false; } let result = true; // Validate the tileAvailability const tileAvailability = subtree.tileAvailability; const tileAvailabilityPath = path + "/tileAvailability"; // The tileAvailability MUST be defined // The tileAvailability MUST be a valid availability object if ( !SubtreeValidator.validateAvailability( tileAvailabilityPath, "tileAvailability", tileAvailability, context ) ) { result = false; } // Validate the contentAvailability const contentAvailability = subtree.contentAvailability; const contentAvailabilityPath = path + "/contentAvailability"; if (defined(contentAvailability)) { // The contentAvailability MUST be an array of at least 1 objects if ( !BasicValidator.validateArray( contentAvailabilityPath, "contentAvailability", contentAvailability, 1, undefined, "object", context ) ) { result = false; } else { // Validate each contentAvailability for (let i = 0; i < contentAvailability.length; i++) { const elementPath = contentAvailabilityPath + "/" + i; const elementName = "contentAvailability/" + i; const element = contentAvailability[i]; if ( !SubtreeValidator.validateAvailability( elementPath, elementName, element, context ) ) { result = false; } } } } // Validate the childSubtreeAvailability const childSubtreeAvailability = subtree.childSubtreeAvailability; const childSubtreeAvailabilityPath = path + "/childSubtreeAvailability"; // The childSubtreeAvailability MUST be defined // The childSubtreeAvailability MUST be a valid availability object if ( !SubtreeValidator.validateAvailability( childSubtreeAvailabilityPath, "childSubtreeAvailability", childSubtreeAvailability, context ) ) { result = false; } return result; } /** * Performs the validation to ensure that the given object is a * valid `availability` object. * * @param path - The path for the `ValidationIssue` instances * @param name - The name of the object * @param availability - The `Availability` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateAvailability( path: string, name: string, availability: Availability | undefined, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, availability, context)) { return false; } let result = true; const bitstream = availability.bitstream; const bitstreamPath = path + "/bitstream"; const constant = availability.constant; const constantPath = path + "/constant"; // Any of the bitstream or the constant must be defined if (!defined(bitstream) && !defined(constant)) { const issue = JsonValidationIssues.ANY_OF_ERROR( path, name, "bitstream", "constant" ); context.addIssue(issue); result = false; } // One of the bitstream or the constant must be defined, if (defined(bitstream) && defined(constant)) { const issue = JsonValidationIssues.ONE_OF_ERROR( path, name, "bitstream", "constant" ); context.addIssue(issue); result = false; } if (defined(bitstream)) { // The bitstream MUST be an integer of at least 0 if ( !BasicValidator.validateIntegerRange( bitstreamPath, "bitstream", bitstream, 0, true, undefined, false, context ) ) { result = false; } } if (defined(constant)) { // The constant MUST be 0 or 1 const constantValues = [0, 1]; if ( !BasicValidator.validateEnum( constantPath, "constant", constant, constantValues, context ) ) { result = false; } } // Validate the availableCount const availableCount = availability.availableCount; const availableCountPath = path + "/availableCount"; if (defined(availableCount)) { // The availableCount MUST be an integer of at least 0 if ( !BasicValidator.validateIntegerRange( availableCountPath, "availableCount", availableCount, 0, true, undefined, false, context ) ) { result = false; } } return result; } /** * Validates the metadata that may be associated with the given subtree. * * This checks whether there are `propertyTables`, and whether they * are valid according to the `schemaState.validatedElement`. * * It also checks the `tileMetadata`, `contentMetadata`, and * `subtreeMetadata`, to see whether it complies to the schema * definition and the property tables. * * @param path - The path for `ValidationIssue` instances * @param subtree - The `Subtree` object * @param context - The `ValidationContext` * @returns Whether the metadata was valid */ private validateMetadata( path: string, subtree: Subtree, context: ValidationContext ): boolean { let result = true; const numBufferViews = defaultValue(subtree.bufferViews?.length, 0); const propertyTablesState = PropertyTablesDefinitionValidator.validatePropertyTablesDefinition( path, "subtree", subtree.propertyTables, numBufferViews, this.schemaState, context ); // When there have been property tables, but they have // not been valid, then the overall result is invalid. if ( propertyTablesState.wasPresent && !defined(propertyTablesState.validatedElement) ) { result = false; } // Validate the tileMetadata const tileMetadata = subtree.tileMetadata; const tileMetadataPath = path + "/tileMetadata"; if (defined(tileMetadata)) { // The tileMetadata MUST be an integer of at least 0 if ( !BasicValidator.validateIntegerRange( tileMetadataPath, "tileMetadata", tileMetadata, 0, true, undefined, false, context ) ) { result = false; } else { if (!this.schemaState.wasPresent) { // If there is tileMetadata, then there MUST be a schema definition const message = `The subtree defines 'tileMetadata' but ` + `there was no schema definition`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else if (!propertyTablesState.wasPresent) { // If there is tileMetadata, then there MUST be propertyTables const message = `The subtree defines 'tileMetadata' but ` + `defines no property tables`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else if ( defined(this.schemaState.validatedElement) && defined(propertyTablesState.validatedElement) ) { // The tileMetadata MUST be smaller than the numberOfPropertyTables if ( !BasicValidator.validateIntegerRange( tileMetadataPath, "tileMetadata", tileMetadata, 0, true, propertyTablesState.validatedElement.length, false, context ) ) { result = false; } } } } // Validate the contentMetadata const contentMetadata = subtree.contentMetadata; const contentMetadataPath = path + "/contentMetadata"; if (defined(contentMetadata)) { // The contentMetadata MUST be an array of at least 1 numbers if ( !BasicValidator.validateArray( contentMetadataPath, "contentMetadata", contentMetadata, 1, undefined, "number", context ) ) { result = false; } else { if (!this.schemaState.wasPresent) { // If there is contentMetadata, then there MUST be a schema definition const message = `The subtree defines 'contentMetadata' but ` + `there was no schema definition`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else if (!propertyTablesState.wasPresent) { // If there is contentMetadata, then there MUST be propertyTables const message = `The subtree defines 'contentMetadata' but ` + `defines no property tables`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else if ( defined(this.schemaState.validatedElement) && defined(propertyTablesState.validatedElement) ) { for (let i = 0; i < contentMetadata.length; i++) { const elementPath = contentMetadataPath + "/" + i; const elementName = "contentMetadata/" + i; const element = contentMetadata[i]; // Each contentMetadata MUST be an integer of at least 0 // Each contentMetadata MUST be smaller than the numberOfPropertyTables if ( !BasicValidator.validateIntegerRange( elementPath, elementName, element, 0, true, propertyTablesState.validatedElement.length, false, context ) ) { result = false; } } } } } // Validate the subtreeMetadata const subtreeMetadata = subtree.subtreeMetadata; const subtreeMetadataPath = path + "/subtreeMetadata"; if (defined(subtreeMetadata)) { if (!this.schemaState.wasPresent) { // If there is subtreeMetadata, then there MUST be a schema definition const message = `The subtree defines 'subtreeMetadata' but ` + `there was no schema definition`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else if (defined(this.schemaState.validatedElement)) { if ( !MetadataEntityValidator.validateMetadataEntity( subtreeMetadataPath, "subtreeMetadata", subtreeMetadata, this.schemaState.validatedElement, context ) ) { result = false; } } } return result; } private async validateBinaryPropertyTables( path: string, binarySubtreeData: BinarySubtreeData, context: ValidationContext ): Promise { const subtree = binarySubtreeData.subtree; if (!defined(subtree.propertyTables)) { return true; } if (!defined(this.schemaState.validatedElement)) { return false; } const binaryBufferStructure = binarySubtreeData.binaryBufferStructure; const binaryBufferData = binarySubtreeData.binaryBufferData; let result = true; // Obtain the structural information about the schema // that is required for validating each property table const schema = this.schemaState.validatedElement; const classes = defaultValue(schema.classes, {}); const binaryEnumInfo = MetadataUtilities.computeBinaryEnumInfo(schema); const propertyTables = defaultValue(subtree.propertyTables, []); for (const propertyTable of propertyTables) { const classId = propertyTable.class; const metadataClass = classes[classId]; // Create the `BinaryPropertyTable` for each property table, // which contains everything that is required for the // validation of the binary representation of the // property table const binaryMetadata: BinaryMetadata = { metadataClass: metadataClass, binaryEnumInfo: binaryEnumInfo, binaryBufferStructure: binaryBufferStructure, binaryBufferData: binaryBufferData, }; const binaryPropertyTable: BinaryPropertyTable = { propertyTable: propertyTable, binaryMetadata: binaryMetadata, }; if ( !BinaryPropertyTableValidator.validateBinaryPropertyTable( path, binaryPropertyTable, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/TemplateUriValidator.ts ================================================ import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; /** * A class for validations related to tempalte URIs for implicit tiling * * @internal */ export class TemplateUriValidator { /** * Validate that the given URI is a valid template URI. * * If the URI is valid, then `true` is returned. * * If the URI contains a `{variable}` expression with a variable * name that is not `level`, `x`, `y` (or `z` for "OCTREE"), then * a `TEMPLATE_URI_INVALID_VARIABLE_NAME` validation issue will * be added to the given context, and `false` is returned. * * If the URI does not contain one of these (expected) variable names, * then a `TEMPLATE_URI_MISSING_VARIABLE_NAME` (warning) issue will * be added to the given context, but `true` will still be returned. * * @param path - The path for `ValidationIssue` instances * @param name - A name for the uri * @param uri - The uri * @param subdivisionScheme - The subdivisionScheme, "QUADTREE" or "OCTREE" * @param context - The `ValidationContext` * @returns Whether the given URI is a valid template URI */ static validateTemplateUri( path: string, name: string, uri: string, subdivisionScheme: string, context: ValidationContext ): boolean { // The uri MUST be a string if (!BasicValidator.validateString(path, name, uri, context)) { return false; } let result = true; // Obtain all {expressions} from the URI const expressionRegex = /{([^}]*)}/g; const expressions = [...uri.matchAll(expressionRegex)]; // Define the set of valid and expected variable names const validVariableNames = ["level", "x", "y"]; if (subdivisionScheme === "OCTREE") { validVariableNames.push("z"); } let expectedVariableNames = [...validVariableNames]; for (let i = 0; i < expressions.length; i++) { const variableName = expressions[i][1]; // Each variable name MUST be one of the valid ones if (!validVariableNames.includes(variableName)) { const issue = SemanticValidationIssues.TEMPLATE_URI_INVALID_VARIABLE_NAME( path, variableName, validVariableNames ); context.addIssue(issue); result = false; } else { // If the variable name was used, remove it from // the set of expected ones expectedVariableNames = expectedVariableNames.filter( (e) => e !== variableName ); } } // If one of the valid variable names was not used, // create a warning if (expectedVariableNames.length > 0) { const issue = SemanticValidationIssues.TEMPLATE_URI_MISSING_VARIABLE_NAME( path, expectedVariableNames ); context.addIssue(issue); } return result; } } ================================================ FILE: src/validation/TileContentValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { ContentDataValidator } from "./ContentDataValidator"; import { BoundingVolumeChecks } from "./legacy/BoundingVolumeChecks"; import { Tile } from "3d-tiles-tools"; import { Content } from "3d-tiles-tools"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; /** * A class for validating a `Tile` and its associated `Content`. * * @internal */ export class TileContentValidator { /** * Validates the given tile content. * * This assumes that the given content was already determined to * be _structurally_ valid on the JSON level, using the * `ContentValidator`. * * @param contentPath - The path for `ValidationIssue` instances * @param content - The `Content` * @param tile - The tile that the content belongs to * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished */ static async validateTileContent( contentPath: string, content: Content, tile: Tile, context: ValidationContext ): Promise { // If the tile is the root of an implicit tileset, then // there is no content to validate here. This method // will be called for each implicit tile during traversal, // and then receive the content where the appropriate // substitution of the template URI has been done. const implicitTiling = tile.implicitTiling; if (defined(implicitTiling)) { return true; } let result = true; // Validate the content data const options = context.getOptions(); if (options.validateContentData) { const contentResult = await ContentDataValidator.validateContentData( contentPath, content, context ); if (!contentResult) { result = false; } } // Validate the content bounding volume consistency if ( !TileContentValidator.validateContentBoundingVolumeConsistency( tile, contentPath, content, context ) ) { result = false; } return result; } /** * Validate that the content bounding volume (if present) is completely * contained in the tile bounding volume. * * @param tile - The containing tile * @param contentPath - The path for the `ValidationIssue` instances * @param content - The content * @param context - The `ValidationContext` * @returns Whether the bounding volumes are consistent */ private static validateContentBoundingVolumeConsistency( tile: Tile, contentPath: string, content: Content, context: ValidationContext ): boolean { const contentBoundingVolume = content.boundingVolume; const contentBoundingVolumePath = contentPath + "/boundingVolume"; if (!defined(contentBoundingVolume)) { return true; } const tileBoundingVolume = tile.boundingVolume; const outerTransform = tile.transform; const innerTransform = tile.transform; const errorMessage = BoundingVolumeChecks.checkBoundingVolume( contentBoundingVolume, tileBoundingVolume, innerTransform, outerTransform ); if (defined(errorMessage)) { const message = `The content bounding volume is not contained ` + `in the tile bounding volume: ${errorMessage}`; const issue = SemanticValidationIssues.BOUNDING_VOLUMES_INCONSISTENT( contentBoundingVolumePath, message ); context.addIssue(issue); return false; } return true; } } ================================================ FILE: src/validation/TileValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { ContentValidator } from "./ContentValidator"; import { BoundingVolumeValidator } from "./BoundingVolumeValidator"; import { BasicValidator } from "./BasicValidator"; import { ImplicitTilingValidator } from "./ImplicitTilingValidator"; import { TransformValidator } from "./TransformValidator"; import { ValidationState } from "./ValidationState"; import { TemplateUriValidator } from "./TemplateUriValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { MetadataEntityValidator } from "./metadata/MetadataEntityValidator"; import { Tile } from "3d-tiles-tools"; import { TileImplicitTiling } from "3d-tiles-tools"; import { JsonValidationIssues } from "../issues/JsonValidationIssues"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; import { StructureValidationIssues } from "../issues/StructureValidationIssues"; /** * The valid values for the `refine` property */ const refineValues: string[] = ["ADD", "REPLACE"]; /** * A class for validations related to `tile` objects. * * The main function of this class, `validateTile`, will perform the * basic structural validation of the tile object. * * The function will **NOT** traverse through the children! * The traversal is done separately, and supposed to call * the `validateTile` function for each encountered tile. * * The function will **NOT** validate the tile content data. * This is done with the `TileContentValidator`, after it * has been determined that the tile is structurally valid. * * @internal */ export class TileValidator { /** * Validates the given tile. * * @param tilePath - The path for the `ValidationIssue` * @param tile - The tile * @param validationState - The `ValidationState` * @param context - The `ValidationContext` * @returns Whether the object was valid */ static async validateTile( tilePath: string, tile: Tile, validationState: ValidationState, context: ValidationContext ): Promise { // Make sure that the given value is an object if (!BasicValidator.validateObject(tilePath, "tile", tile, context)) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( tilePath, "tile", tile, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject(tilePath, tile, context) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(tile)) { return result; } // Validate the boundingVolume const boundingVolume = tile.boundingVolume; const boundingVolumePath = tilePath + "/boundingVolume"; // The boundingVolume MUST be defined const boundingVolumeValid = await BoundingVolumeValidator.validateBoundingVolume( boundingVolumePath, boundingVolume, context ); if (!boundingVolumeValid) { result = false; } // Validate the viewerRequestVolume const viewerRequestVolume = tile.viewerRequestVolume; const viewerRequestVolumePath = tilePath + "/viewerRequestVolume"; if (defined(viewerRequestVolume)) { if ( !BoundingVolumeValidator.validateBoundingVolume( viewerRequestVolumePath, viewerRequestVolume, context ) ) { result = false; } } // Validate the geometricError const geometricError = tile.geometricError; const geometricErrorPath = tilePath + "/geometricError"; // The geometricError MUST be defined // The geometricError MUST be a number // The geometricError MUST be >= 0 if ( !BasicValidator.validateNumberRange( geometricErrorPath, "geometricError", geometricError, 0.0, true, undefined, false, context ) ) { result = false; } // Validate the refine const refine = tile.refine; const refinePath = tilePath + "/refine"; if (defined(refine)) { // The refine MUST be a string if ( !BasicValidator.validateString(refinePath, "refine", refine, context) ) { result = false; } else { // Special handling for refine values that are not // in uppercase: If it is a valid value, but not // in uppercase, then issue a warning const upperCaseRefine = refine.toUpperCase(); if ( !refineValues.includes(refine) && refineValues.includes(upperCaseRefine) ) { const message = `The 'refine' property must be ` + `'ADD' or 'REPLACE', but is '${refine}'`; const issue = SemanticValidationIssues.TILE_REFINE_WRONG_CASE( refinePath, message ); context.addIssue(issue); } else { // The refine MUST be one of the refineValues if ( !BasicValidator.validateEnum( refinePath, "refine", refine, refineValues, context ) ) { result = false; } } } } // Validate the transform const transform = tile.transform; const transformPath = tilePath + "/transform"; if (defined(transform)) { if ( !TransformValidator.validateTransform(transformPath, transform, context) ) { result = false; } } // Validate the metadata const metadata = tile.metadata; const metadataPath = tilePath + "/metadata"; if (defined(metadata)) { const schemaState = validationState.schemaState; if (!schemaState.wasPresent) { // If there is metadata, then there must be a schema definition const message = "The tile defines 'metadata' but the tileset does not have a schema"; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( tilePath, message ); context.addIssue(issue); result = false; } else if (defined(schemaState.validatedElement)) { if ( !MetadataEntityValidator.validateMetadataEntity( metadataPath, "tile.metadata", metadata, schemaState.validatedElement, context ) ) { result = false; } } } // The content and contents MUST NOT be present at the same time const content = tile.content; const contents = tile.contents; if (defined(content) && defined(contents)) { const path = tilePath; const issue = JsonValidationIssues.ONE_OF_ERROR( path, "tile", "content", "contents" ); context.addIssue(issue); result = false; } // Check if the tile defines an implicitTiling. There are several // checks that are very specific for implicit tileset roots, so // these validation steps are implemented as dedicated functions. const implicitTiling = tile.implicitTiling; if (defined(implicitTiling)) { if ( !TileValidator.validateImplicitTilesetRoot( tilePath, tile, implicitTiling, context ) ) { result = false; } } else { const simpleTileValid = await TileValidator.validateSimpleTile( tilePath, tile, validationState, context ); if (!simpleTileValid) { result = false; } } return result; } /** * Validate the given tile, which is already determined to be * a tile that is **NOT** the root of an implicit tileset * (i.e. it does **NOT** define `implicitTiling`). * * @param tilePath - The path for the `ValidationIssue` * @param tile - The tile * @param validationState - The `ValidationState` object * @param context - The `ValidationContext` * @returns Whether the object was valid */ private static async validateSimpleTile( tilePath: string, tile: Tile, validationState: ValidationState, context: ValidationContext ): Promise { let result = true; // Note: The check that content and contents may not be present // at the same time is done in `validateTile`! // Validate the content const content = tile.content; const contentPath = tilePath + "/content"; if (defined(content)) { const contentValid = await ContentValidator.validateContent( contentPath, content, validationState, context ); if (!contentValid) { result = false; } } // Validate the contents const contents = tile.contents; const contentsPath = tilePath + "/contents"; if (defined(contents)) { // The contents MUST be an array // Each element of the contents array MUST be an object if ( !BasicValidator.validateArray( contentsPath, "contents", contents, undefined, undefined, "object", context ) ) { result = false; } else { // Validate each element of the contents array for (let index = 0; index < contents.length; index++) { const contentsElementPath = contentsPath + "/" + index; const contentsElement = contents[index]; const contentValid = await ContentValidator.validateContent( contentsElementPath, contentsElement, validationState, context ); if (!contentValid) { result = false; } } } } // Validate the children // Note that this will NOT recurse through the children! const children = tile.children; const childrenPath = tilePath + "/children"; if (defined(children)) { // The children MUST be an array of objects if ( !BasicValidator.validateArray( childrenPath, "children", children, 0, undefined, "object", context ) ) { result = false; } else { // The children are an array of objects. // The case that the array has a length of 0 will cause a warning, // due to https://github.com/CesiumGS/3d-tiles/issues/752 if (children.length === 0) { const message = `The 'children' array should contain at least 1 element, ` + `but had a length of 0`; const issue = JsonValidationIssues.ARRAY_LENGTH_UNEXPECTED( childrenPath, message ); context.addIssue(issue); } } } return result; } /** * Certain properties may not be defined in an implicit tileset root: * * - tile.children * - tile.metadata * - tile.content.boundingVolume * * This method checks whether the property is indeed undefined, * and adds a `TILE_IMPLICIT_ROOT_INVALID` issue to the given * context if it was defined. * * @param tilePath - The path for the `ValidationIssue` * @param name - The name of the property * @param value - The value of the property * @param context - The `ValidationContext` * @returns Whether the values was not defined */ private static validateDisallowedInImplicitTilesetRoot( tilePath: string, name: string, value: any, context: ValidationContext ): boolean { if (!defined(value)) { return true; } const message = `The tile defines 'implicitTiling' and ` + `may therefore not define '${name}'`; const issue = SemanticValidationIssues.TILE_IMPLICIT_ROOT_INVALID( tilePath, message ); context.addIssue(issue); return false; } /** * Validate the given tile, given that it is the root of * an implicit tileset, as indicated by the presence of * the `implicitTiling` property. * * @param tilePath - The path for the `ValidationIssue` * @param tile - The tile * @param implicitTiling - The `TileImplicitTiling` object * @param context - The `ValidationContext` * @returns Whether the object was valid */ private static validateImplicitTilesetRoot( tilePath: string, tile: Tile, implicitTiling: TileImplicitTiling, context: ValidationContext ): boolean { let result = true; let implicitTilingIsValid = true; // Validate the implicitTiling const implicitTilingPath = tilePath + "/implicitTiling"; if ( !ImplicitTilingValidator.validateImplicitTiling( implicitTilingPath, implicitTiling, context ) ) { result = false; implicitTilingIsValid = false; } // From the specification text: // The tile shall omit the children property if ( !TileValidator.validateDisallowedInImplicitTilesetRoot( tilePath, "children", tile.children, context ) ) { result = false; } // From the specification text: // The tile shall omit the metadata property if ( !TileValidator.validateDisallowedInImplicitTilesetRoot( tilePath, "metadata", tile.metadata, context ) ) { result = false; } // From the specification text: // The content shall omit the boundingVolume property if ( !TileValidator.validateDisallowedInImplicitTilesetRoot( tilePath, "content.boundingVolume", tile.content?.boundingVolume, context ) ) { result = false; } // From the specification text: // - The content.uri shall not point to an external tileset // TODO This can hardly be validated here... // From the specification text of Implicit Tiling: Sphere bounding volumes // are disallowed, as these cannot be divided into a quadtree or octree. if ( !TileValidator.validateDisallowedInImplicitTilesetRoot( tilePath, "boundingVolume.sphere", tile.boundingVolume?.sphere, context ) ) { result = false; } // Note: The check that content and contents may not be present // at the same time is done in `validateTile`! // Validate the content const content = tile.content; const contentPath = tilePath + "/content"; if (defined(content)) { // The content of an implicit root requires special checks: // The content MUST be an object if ( !BasicValidator.validateObject(contentPath, "content", content, context) ) { result = false; } else { // The content uri MUST be a valid template URI. // This is only checked if the implicit tiling was // valid (i.e. contained a valid subdivisionScheme) if (implicitTilingIsValid) { const contentUri = content.uri; const contentUriPath = contentPath + "/uri"; const subdivisionScheme = implicitTiling.subdivisionScheme; if ( !TemplateUriValidator.validateTemplateUri( contentUriPath, "uri", contentUri, subdivisionScheme, context ) ) { result = false; } } } } // Validate the contents const contents = tile.contents; const contentsPath = tilePath + "/contents"; if (defined(contents)) { // The content of an implicit root requires special checks: // The contents MUST be an array // Each element of the contents array MUST be an object if ( !BasicValidator.validateArray( contentsPath, "contents", contents, undefined, undefined, "object", context ) ) { result = false; } else { // Validate each element of the contents array for (let index = 0; index < contents.length; index++) { const contentsElementPath = contentsPath + "/" + index; const contentsElement = contents[index]; // The content uri MUST be a valid template URI. // This is only checked if the implicit tiling was // valid (i.e. contained a valid subdivisionScheme) if (implicitTilingIsValid) { const contentsElementUri = contentsElement.uri; const contentsElementUriPath = contentsElementPath + "/uri"; const subdivisionScheme = implicitTiling.subdivisionScheme; if ( !TemplateUriValidator.validateTemplateUri( contentsElementUriPath, "uri", contentsElementUri, subdivisionScheme, context ) ) { result = false; } } } } } return result; } } ================================================ FILE: src/validation/TilesetPackageValidator.ts ================================================ import path from "path"; import { defined } from "3d-tiles-tools"; import { Buffers } from "3d-tiles-tools"; import { UnzippingResourceResolver } from "3d-tiles-tools"; import { Validators } from "./Validators"; import { Validator } from "./Validator"; import { ValidationContext } from "./ValidationContext"; import { TilesetSourceResourceResolver } from "3d-tiles-tools"; import { ContentValidationIssues } from "../issues/ContentValidationIssues"; import { IoValidationIssues } from "../issues/IoValidationIssue"; import { TilesetSource3tz } from "3d-tiles-tools"; import { TilesetSource3dtiles } from "3d-tiles-tools"; import { TilesetSourceFs } from "3d-tiles-tools"; import { TilesetSource } from "3d-tiles-tools"; import { ArchiveValidation3tz } from "../archives/ArchiveValidation3tz"; /** * An implementation of a validator that validates a `TilesetSource`. * * The actual validation function is `validatePackageFile`. * * This class also implements the `Validator` interface, so that * instances of it can be used when the tile content is a * tileset package. In this case, the validated type is `string`, where * this string is the 'resolvedUri' that points to a file in the * local file system. * * @internal */ export class TilesetPackageValidator implements Validator { /** * Implementation of the `Validator` interface. This validates * the given 'resolvedUri' string, assuming that it is a full * path to a tileset package in the local file system. * * @param uri - The (usually relative) URI of the package * @param resolvedUri - The resolved URI, which is the full URI * of the package in the local file system. * @param context - The `ValidationContext` * @returns A promise that is fulfilled when the validation is finished * and indicates whether the object was valid or not. */ async validateObject( uri: string, resolvedUri: string, context: ValidationContext ): Promise { const isContent = true; const result = TilesetPackageValidator.validatePackageFileInternal( resolvedUri, isContent, context ); return result; } /** * Validates the tileset that is contained in the package that is * pointed to by the given URI (assuming that it is a file in * the local file system). * * @param uri - The full URI of the package file * @param context - The `ValidationContext` * @returns A promise that indicates whether the package contained * a valid tileset. */ static async validatePackageFile(uri: string, context: ValidationContext) { const isContent = false; const result = TilesetPackageValidator.validatePackageFileInternal( uri, isContent, context ); return result; } /** * Validates the tileset that is contained in the package that is * pointed to by the given URI (assuming that it is a file in * the local file system). * * @param uri - The full URI of the package file * @param isContent - Whether the given package was found as a tile * content. If this is the case, then the issues that are found * in the package will be summarized in a `CONTENT_VALIDATION_` * issue. Otherwise, they will be added directly to the given context. * @param context - The `ValidationContext` * @returns A promise that indicates whether the package contained * a valid tileset. */ private static async validatePackageFileInternal( uri: string, isContent: boolean, context: ValidationContext ): Promise { try { const result = await TilesetPackageValidator.validatePackageFileUnchecked( uri, isContent, context ); return result; } catch (error) { const message = `Failed to open ${uri}. Input file is invalid.`; const issue = IoValidationIssues.IO_ERROR(uri, message); context.addIssue(issue); return false; } } /** * Validates the tileset that is contained in the package that is * pointed to by the given URI (assuming that it is a file in * the local file system). * * @param uri - The full URI of the package file * @param isContent - Whether the given package was found as a tile * content. If this is the case, then the issues that are found * in the package will be summarized in a `CONTENT_VALIDATION_` * issue. Otherwise, they will be added directly to the given context. * @param context - The `ValidationContext` * @returns A promise that indicates whether the package contained * a valid tileset. * @throws Error if opening the tileset source causes an unhandled * error. */ private static async validatePackageFileUnchecked( uri: string, isContent: boolean, context: ValidationContext ): Promise { // Create the tileset source for the package from the given URI // (i.e. the full package file name). If the source cannot // be opened, bail out with an IO_WARNING. let tilesetSource = undefined; const extension = path.extname(uri).toLowerCase(); if (extension === ".3tz") { tilesetSource = new TilesetSource3tz(); } else if (extension === ".3dtiles") { tilesetSource = new TilesetSource3dtiles(); } else if (extension === "") { tilesetSource = new TilesetSourceFs(); } else { const message = `Could not create tileset source from ${uri}: No known file extension. `; const issue = IoValidationIssues.IO_WARNING(uri, message); context.addIssue(issue); return true; } await tilesetSource.open(uri); const result = await TilesetPackageValidator.validatePackageInternal( uri, tilesetSource, isContent, context ); await tilesetSource.close(); return result; } /** * Validates the tileset that is contained in the given `TilesetSource`. * * The caller is responsible for calling 'open' on the source before * passing it to this method, and 'close' after this method returns. * * @param uri - The full URI of the package file * @param tilesetSource - The `TilesetSource` that was created from * the package file * @param isContent - Whether the given package was found as a tile * content. If this is the case, then the issues that are found * in the package will be summarized in a `CONTENT_VALIDATION_` * issue. Otherwise, they will be added directly to the given context. * @param context - The `ValidationContext` * @returns A promise that indicates whether the package contained * a valid tileset. */ private static async validatePackageInternal( uri: string, tilesetSource: TilesetSource, isContent: boolean, context: ValidationContext ): Promise { // If the package is a 3TZ package, then perform the extended // validation of the 3TZ index part, using the ("legacy") 3TZ // package validation if (tilesetSource instanceof TilesetSource3tz) { const tilesetSource3tz = tilesetSource as TilesetSource3tz; const zipIndex = tilesetSource3tz.getZipIndex(); if (defined(zipIndex)) { try { const indexValid = await ArchiveValidation3tz.validateIndex( zipIndex, uri, false ); if (!indexValid) { const message = `The 3TZ index is not valid`; const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( uri, message ); context.addIssue(issue); return false; } } catch (error) { const message = `Error while validating 3TZ index: ${error}.`; const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( uri, message ); context.addIssue(issue); return false; } } } // Create the `TilesetSourceResourceResolver` from the package, // and obtain the data for the `tileset.json` file. // This has to be present according to the 3TZ specification. const plainPackageResourceResolver = new TilesetSourceResourceResolver( "./", tilesetSource ); const packageResourceResolver = new UnzippingResourceResolver( plainPackageResourceResolver ); const tilesetJsonBuffer = await packageResourceResolver.resolveData( "tileset.json" ); if (!defined(tilesetJsonBuffer)) { const message = `Could not read 'tileset.json' from package ${uri}.`; const issue = IoValidationIssues.IO_ERROR(uri, message); context.addIssue(issue); return false; } const bom = Buffers.getUnicodeBOMDescription(tilesetJsonBuffer); if (defined(bom)) { const message = `Unexpected BOM in JSON buffer: ${bom}`; const issue = IoValidationIssues.IO_ERROR(uri, message); context.addIssue(issue); return false; } // Parse the tileset object from the JSON data let tileset = undefined; try { tileset = JSON.parse(tilesetJsonBuffer.toString()); } catch (error) { const message = `Could not parse tileset JSON from 'tileset.json' ` + `data in package ${uri}.`; const issue = IoValidationIssues.IO_ERROR(uri, message); context.addIssue(issue); return false; } // Open a new context for collecting the issues that // are caused by the tileset, and validate the // tileset using a default tileset validator. const derivedContext = context.deriveFromResourceResolver( uri, packageResourceResolver ); const tilesetValidator = Validators.createDefaultTilesetValidator(); const result = await tilesetValidator.validateObject( uri + "/tileset.json", tileset, derivedContext ); const derivedResult = derivedContext.getResult(); // Add all extensions that have been found in the tileset // to the current context. They also have to appear in // the 'extensionsUsed' of the containing tileset. const derivedExtensionsFound = derivedContext.getExtensionsFound(); for (const derivedExtensionFound of derivedExtensionsFound) { context.addExtensionFound(derivedExtensionFound); } if (isContent) { const issue = ContentValidationIssues.createForContent( uri, derivedResult ); if (issue) { context.addIssue(issue); } } else { for (const innerIssue of derivedResult.issues) { context.addIssue(innerIssue); } } return result; } } ================================================ FILE: src/validation/TilesetTraversingValidator.ts ================================================ import path from "path"; import { defined } from "3d-tiles-tools"; import { ImplicitTilings } from "3d-tiles-tools"; import { ExplicitTraversedTile } from "3d-tiles-tools"; import { ValidationContext } from "./ValidationContext"; import { ValidationState } from "./ValidationState"; import { TileValidator } from "./TileValidator"; import { TileContentValidator } from "./TileContentValidator"; import { SubtreeValidator } from "./SubtreeValidator"; import { ImplicitTilingValidator } from "./ImplicitTilingValidator"; import { TilesetTraverser } from "3d-tiles-tools"; import { TraversedTile } from "3d-tiles-tools"; import { MetadataEntityValidator } from "./metadata/MetadataEntityValidator"; import { ImplicitTilingError } from "3d-tiles-tools"; import { Tileset } from "3d-tiles-tools"; import { TileImplicitTiling } from "3d-tiles-tools"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; import { ValidationIssues } from "../issues/ValidationIssues"; import { StructureValidationIssues } from "../issues/StructureValidationIssues"; /** * A validator for a `Tileset` that traverses the tile hierarchy * and performs the validation of the tile instances, their contents, * and the consistency of the tile hierarchy. * * @internal */ export class TilesetTraversingValidator { /** * Validates the given tileset, by traversing the tile hierarchy * and validating each traversed tile. * * @param tileset - The `Tileset` * @param validationState - The `ValidationState` * @param context - The `TraversalContext` * @returns A promise that resolves when the validation is finished * and indicates whether every traversed tile was valid. */ static async validateTileset( tileset: Tileset, validationState: ValidationState, context: ValidationContext ): Promise { const resourceResolver = context.getResourceResolver(); let result = true; const tilesetTraverser = new TilesetTraverser(".", resourceResolver, { depthFirst: true, }); try { const schema = validationState.schemaState.validatedElement; await tilesetTraverser.traverseWithSchema( tileset, schema, async (traversedTile: TraversedTile) => { // Validate the tile, and only continue the traversal // if it was found to be valid const isValid = await TilesetTraversingValidator.validateTraversedTile( traversedTile, validationState, context ); if (!isValid) { result = false; } if (isValid) { // If the traversed tile is generally valid, then // validate its content const contentValid = await TilesetTraversingValidator.validateTraversedTileContent( traversedTile, context ); if (!contentValid) { result = false; } // If the traversed tile is not the root tile, validate // the consistency of the hierarchy const parent = traversedTile.getParent(); if (defined(parent)) { const hierarchyValid = TilesetTraversingValidator.validateTraversedTiles( parent, traversedTile, context ); if (!hierarchyValid) { result = false; } } } return isValid; } ); } catch (error) { // There may be different kinds of errors that are thrown // during the traversal of the tileset and its validation. // An `ImplicitTilingError` indicates that an implicit // tileset was invalid (e.g. a missing subtree file or // one of its buffers). The `ImplicitTilingError` is // supposed to contain more detailed information. if (error instanceof ImplicitTilingError) { const message = `Could not traverse tileset: ${error}`; const issue = SemanticValidationIssues.IMPLICIT_TILING_ERROR( "", message ); context.addIssue(issue); result = false; } else { // Other kinds of errors should not bubble up to the caller, // and are therefore collected here as `INTERNAL_ERROR`. // Whether or not this should cause the object to be // reported as "invalid" is up to debate. But to reduce // the number of follow-up errors, the object will be // reported as invalid here. const message = `Internal error while traversing tileset: ${error}`; const issue = ValidationIssues.INTERNAL_ERROR("", message); context.addIssue(issue); result = false; } } return result; } /** * Validates the given traversed tile. * * This will validate the tile that is represented with the given * traversed tile, so far that it ensures that it is a valid * tile object and can be traversed further. * * It will not validate the tile content. This is done with * `validateTraversedTileContent` * * @param traversedTile - The `TraversedTile` * @param validationState - The `ValidationState` * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished */ private static async validateTraversedTile( traversedTile: TraversedTile, validationState: ValidationState, context: ValidationContext ): Promise { const path = traversedTile.path; // TODO The validation of the implicit tiling and the // metadata that are done here are redundant. They // are also done in `TileValidator#validateTile`. // It is not entirely clear which types of inconsistencies // should cause the validation to fail with which message. // Maybe some of these validation steps should be pulled // out of "validateTile", or enabled/disabled via flags. if (traversedTile instanceof ExplicitTraversedTile) { const explicitPartIsValid = await TilesetTraversingValidator.validateExplicitTraversedTile( traversedTile, validationState, context ); if (!explicitPartIsValid) { return false; } } const tile = traversedTile.asRawTile(); // Validate the tile itself const tileValid = await TileValidator.validateTile( path, tile, validationState, context ); if (!tileValid) { return false; } // The specification says that the "refine" property is required // for the root tile of a tileset. if (tileValid) { const isRoot = traversedTile.level === 0; const refine = tile.refine; if (isRoot && !defined(refine)) { const message = `The 'refine' property must be set in root tiles`; const issue = SemanticValidationIssues.TILE_REFINE_MISSING_IN_ROOT( path, message ); context.addIssue(issue); return false; } } return true; } /** * Validates the given explicit traversed tile. * * This will ONLY validate the elements that are specific for * an `ExplicitTraversedTile` (compared to a `TraversedTile`) , * namely the `implicitTiling` and `metadata` of the tile. * * @param traversedTile - The `ExplicitTraversedTile` * @param validationState - The `ValidationState` * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished */ private static async validateExplicitTraversedTile( traversedTile: ExplicitTraversedTile, validationState: ValidationState, context: ValidationContext ): Promise { const path = traversedTile.path; // If the tile defines implicit tiling, validate this // first. All subsequent checks depend on the validity // of the implicit tiling information. const implicitTiling = traversedTile.getImplicitTiling(); const implicitTilingPath = path + "/implicitTiling"; if (defined(implicitTiling)) { if ( !ImplicitTilingValidator.validateImplicitTiling( implicitTilingPath, implicitTiling, context ) ) { return false; } // Validate the subtree data that will be expected // for the root of the implicit tileset const rootCoordinates = ImplicitTilings.createRootCoordinates(implicitTiling); const subtreeUri = ImplicitTilings.substituteTemplateUri( implicitTiling.subdivisionScheme, implicitTiling.subtrees.uri, rootCoordinates ); const subtreeRootValid = await TilesetTraversingValidator.validateSubtreeRoot( path, implicitTiling, subtreeUri, validationState, context ); if (!subtreeRootValid) { return false; } } // Validate the metadata. // This is also done in `TileValidator#validateTile`, but // the following steps require the metadata to already be // valid. const metadata = traversedTile.getMetadata(); const metadataPath = path + "/metadata"; if (defined(metadata)) { const schemaState = validationState.schemaState; if (!schemaState.wasPresent) { // If there is metadata, then there must be a schema definition const message = "The tile defines 'metadata' but the tileset does not have a schema"; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); return false; } if (defined(schemaState.validatedElement)) { if ( !MetadataEntityValidator.validateMetadataEntity( metadataPath, "tile.metadata", metadata, schemaState.validatedElement, context ) ) { return false; } } } return true; } /** * Validates the content in given traversed tile. * * This assumes that the given tile already has been determined to * be basically valid, as of `validateTraversedTile`. * * @param traversedTile - The `TraversedTile` * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished */ private static async validateTraversedTileContent( traversedTile: TraversedTile, context: ValidationContext ): Promise { const tile = traversedTile.asRawTile(); let result = true; // Validate the content const content = tile.content; const contentPath = traversedTile.path + "/content"; if (defined(content)) { const contentResult = await TileContentValidator.validateTileContent( contentPath, content, tile, context ); if (!contentResult) { result = false; } } // Validate the contents const contents = tile.contents; const contentsPath = traversedTile.path + "/contents"; if (defined(contents)) { for (let i = 0; i < contents.length; i++) { const contentsElement = contents[i]; const contentsElementPath = contentsPath + "/" + i; const contentResult = await TileContentValidator.validateTileContent( contentsElementPath, contentsElement, tile, context ); if (!contentResult) { result = false; } } } return result; } /** * Performs the validation to make sure that the specified subtree * root is valid. * * This will attempt to resolve the `.subtree` (or subtree JSON) * data from the URI that is created by substituting the given * coordinates into the subtree template URI of the implicit tiling, * resolve the resulting data, and pass it to a `SubtreeValidator`. * * @param tilePath - The path for `ValidationIssue` instances * @param implicitTiling - The `TileImplicitTiling` * @param subtreeUri - The subtree URI * @param validationState - The `ValidationState` * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished */ private static async validateSubtreeRoot( tilePath: string, implicitTiling: TileImplicitTiling, subtreeUri: string, validationState: ValidationState, context: ValidationContext ): Promise { // Resolve resources (like buffers) relative to the // directory of the subtree file const resourceResolver = context.getResourceResolver(); const subtreeDirectory = path.dirname(subtreeUri); const subtreeResourceResolver = resourceResolver.derive(subtreeDirectory); // Obtain the raw subtree data (binary subtree file or JSON) const subtreeData = await resourceResolver.resolveData(subtreeUri); if (subtreeData == null) { const message = `Could not resolve subtree URI ${subtreeUri} that was ` + `created from template URI ${implicitTiling.subtrees.uri} `; const issue = SemanticValidationIssues.TILE_IMPLICIT_ROOT_INVALID( tilePath, message ); context.addIssue(issue); return false; } // Validate the subtree data with a `SubtreeValidator` const subtreeValidator = new SubtreeValidator( validationState.schemaState, implicitTiling, subtreeResourceResolver ); const result = await subtreeValidator.validateObject( subtreeUri, subtreeData, context ); return result; } /** * Validate the consistency of the given traversed tile instances. * * This will check whether the geometric error of the tile * is larger than the geometric error of its parent, and * create a warning if this is not the case. * * @param traversedParent - The parent `TraversedTile` * @param traversedTile - The current `TraversedTile` * @param context - The `ValidationContext` */ private static validateTraversedTiles( traversedParent: TraversedTile, traversedTile: TraversedTile, context: ValidationContext ): boolean { const path = traversedTile.path; const tile = traversedTile.asRawTile(); const parent = traversedParent.asRawTile(); // Create a warning when the geometric error of the tile // is larger than the geometric error of its parent const parentGeometricError = parent.geometricError; const tileGeometricError = tile.geometricError; if ( defined(tileGeometricError) && defined(parentGeometricError) && tileGeometricError > parentGeometricError ) { const message = `Tile ${path} has a geometricError of ${tileGeometricError}, ` + `which is larger than the parent geometricError ` + `of ${parentGeometricError}`; const issue = SemanticValidationIssues.TILE_GEOMETRIC_ERRORS_INCONSISTENT( path, message ); context.addIssue(issue); } // The geometric error inconsistency is only a WARNING, // so the tile is still considered to be valid return true; } } ================================================ FILE: src/validation/TilesetValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Validator } from "./Validator"; import { ValidationState } from "./ValidationState"; import { BasicValidator } from "./BasicValidator"; import { ValidationContext } from "./ValidationContext"; import { PropertiesValidator } from "./PropertiesValidator"; import { StatisticsValidator } from "./StatisticsValidator"; import { AssetValidator } from "./AssetValidator"; import { TilesetTraversingValidator } from "./TilesetTraversingValidator"; import { RootPropertyValidator } from "./RootPropertyValidator"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { ValidatedElement } from "./ValidatedElement"; import { ExtensionsDeclarationsValidator } from "./ExtensionsDeclarationsValidator"; import { SchemaDefinitionValidator } from "./metadata/SchemaDefinitionValidator"; import { MetadataEntityValidator } from "./metadata/MetadataEntityValidator"; import { Tileset } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { Group } from "3d-tiles-tools"; import { IoValidationIssues } from "../issues/IoValidationIssue"; import { StructureValidationIssues } from "../issues/StructureValidationIssues"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; /** * A class that can validate a 3D Tiles tileset. * * @internal */ export class TilesetValidator implements Validator { /** * Performs the validation of the tileset that is parsed from the * given input string. * * @param input - The string that was read from a `tileset.json` file * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished */ async validateJsonString( input: string, context: ValidationContext ): Promise { try { const object: Tileset = JSON.parse(input); await this.validateObject("", object, context); } catch (error) { //console.log(error); const issue = IoValidationIssues.JSON_PARSE_ERROR("", "" + error); context.addIssue(issue); } } /** * Implementation of the `Validator` interface that just passes the * input to `validateTileset`. * * @param path - The path for `ValidationIssue` instances * @param input - The `Tileset` object * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished * and indicates whether the object was valid or not. */ async validateObject( path: string, input: Tileset, context: ValidationContext ): Promise { const result = await TilesetValidator.validateTileset(path, input, context); return result; } /** * Performs the validation of the given `Tileset` object that was parsed * from a `tileset.json` input. * * Issues that are encountered during the validation will be added * as `ValidationIssue` instances to the given `ValidationContext`. * * @param path - The path for `ValidationIssue` instances * @param tileset - The `Tileset` object * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished * and indicates whether the object was valid or not. */ static async validateTileset( path: string, tileset: Tileset, context: ValidationContext ): Promise { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "tileset", tileset, context)) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, "tileset", tileset, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject(path, tileset, context) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(tileset)) { return result; } // The asset MUST be defined const asset = tileset.asset; if (!AssetValidator.validateAsset(asset, context)) { result = false; } // Validate the properties (I mean, the `properties`...) const properties = tileset.properties; if (defined(properties)) { if (!PropertiesValidator.validateProperties(properties, context)) { result = false; } } // Validate the schema definition that is given either via // the `schema` or the `schemaUri`. const schemaState = await SchemaDefinitionValidator.validateSchemaDefinition( path, "tileset", tileset.schema, tileset.schemaUri, context ); // When there was a schema definition, but the schema itself // was not valid, then the overall result is invalid if (schemaState.wasPresent && !defined(schemaState.validatedElement)) { result = false; } // Validate the groups. const groupsState: ValidatedElement = { wasPresent: false, validatedElement: undefined, }; const groups = tileset.groups; const groupsPath = path + "/groups"; if (defined(groups)) { groupsState.wasPresent = true; // If there are groups, then there must be a schema definition if (!schemaState.wasPresent) { const message = "The tileset defines 'groups' but does not have a schema"; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( groupsPath, message ); context.addIssue(issue); result = false; } else if (defined(schemaState.validatedElement)) { if ( TilesetValidator.validateTilesetGroups( groups, schemaState.validatedElement, context ) ) { groupsState.validatedElement = groups; } else { result = false; } } } // Create the ValidationState that describes the state of // the validation for tileset elements (i.e. the schema // and the metadata groups) const validationState: ValidationState = { schemaState: schemaState, groupsState: groupsState, }; // Validate the statistics const statistics = tileset.statistics; const statisticsPath = path + "/statistics"; if (defined(statistics)) { if ( !StatisticsValidator.validateStatistics( statisticsPath, statistics, schemaState, context ) ) { result = false; } } // Validate the geometricError const geometricError = tileset.geometricError; const geometricErrorPath = "/geometricError"; // The geometricError MUST be defined // The geometricError MUST be a number // The geometricError MUST be >= 0 if ( !BasicValidator.validateNumberRange( geometricErrorPath, "geometricError", geometricError, 0.0, true, undefined, false, context ) ) { result = false; } // Validate the metadata const metadata = tileset.metadata; const metadataPath = path + "/metadata"; if (defined(metadata)) { if (!schemaState.wasPresent) { // If there is metadata, then there MUST be a schema definition const message = `The tileset defines metadata, but ` + `there was no schema definition`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else if (defined(schemaState.validatedElement)) { if ( !MetadataEntityValidator.validateMetadataEntity( metadataPath, "metadata", metadata, schemaState.validatedElement, context ) ) { result = false; } } } const traversalValid = await TilesetTraversingValidator.validateTileset( tileset, validationState, context ); if (!traversalValid) { result = false; } if ( !TilesetValidator.validateExtensionDeclarations(path, tileset, context) ) { result = false; } return result; } /** * Validate the extension declarations of the given tileset. * * This is supposed to be called at the end of the validation process * of the tileset. It uses the extension names that have been added * to the `ValidationContext` via `addExtensionFound`, to make sure * that all extensions that are found have also been declared in * the 'extensionsUsed' array. * * It also performs the JSON-schema level validation of the basic * structure and consistency of the 'extensionsUsed' and * 'extensionsRequired' arrays of the given tileset. * * @param path - The path for `ValidationIssue` instances * @param tileset - The `Tileset` * @param context - The `ValidationContext` * @returns Whether the declarations have been valid */ private static validateExtensionDeclarations( path: string, tileset: Tileset, context: ValidationContext ): boolean { let result = true; const extensionsUsed = tileset.extensionsUsed; const extensionsUsedPath = path + "/extensionsUsed"; const extensionsRequired = tileset.extensionsRequired; const extensionsRequiredPath = path + "/extensionsRequired"; if ( !ExtensionsDeclarationsValidator.validateExtensionDeclarationConsistency( path, extensionsUsed, extensionsRequired, context ) ) { return false; } const actualExtensionsUsed = new Set(); if (defined(extensionsUsed)) { extensionsUsed.forEach((e) => actualExtensionsUsed.add(e)); } const actualExtensionsRequired = new Set(); if (defined(extensionsRequired)) { extensionsRequired.forEach((e) => actualExtensionsRequired.add(e)); } // Each extension that is found during the validation // in the `RootPropertyValidator` or the // `ContentDataValidator` also has to appear // in the 'extensionsUsed' const actualExtensionsFound = context.getExtensionsFound(); // Special handling for the "3DTILES_content_gltf" extension: // (also see https://github.com/CesiumGS/3d-tiles-validator/issues/231) // When the tileset version is 1.0, and the extension was // declared in 'extensionsUsed', then it must also be // declared in 'extensionsRequired' if (tileset.asset?.version === "1.0") { if ( actualExtensionsUsed.has("3DTILES_content_gltf") && !actualExtensionsRequired.has("3DTILES_content_gltf") ) { const issue = SemanticValidationIssues.EXTENSION_REQUIRED_BUT_NOT_DECLARED( extensionsRequiredPath, "3DTILES_content_gltf" ); context.addIssue(issue); result = false; } } // The 3DTILES_content_gltf extension can end up in the // "actualExtensionsFound" in two ways: // - because an actual glTF content was found. // - because a tileset.extensions["3DTILES_content_gltf"] was found // Only the latter is relevant for the further checks here. // So remove this from the actualExtensionsFound when it was // only found as a tile content. if (tileset.asset?.version === "1.1") { const tilesetExtensions = tileset.extensions; if (!defined(tilesetExtensions)) { actualExtensionsFound.delete("3DTILES_content_gltf"); } else { const tilesetContentGltfExtensionObject = tilesetExtensions["3DTILES_content_gltf"]; if (!defined(tilesetContentGltfExtensionObject)) { actualExtensionsFound.delete("3DTILES_content_gltf"); } } } // Every extension that is found must be declared in extensionsUsed for (const extensionName of actualExtensionsFound) { if (!actualExtensionsUsed.has(extensionName)) { const issue = SemanticValidationIssues.EXTENSION_FOUND_BUT_NOT_USED( extensionsUsedPath, extensionName ); context.addIssue(issue); result = false; } } // Each extension that is declared in the 'extensionsUsed' // should also appear in the extensions that are found // (but it does not have to - so this is just a warning) for (const extensionName of actualExtensionsUsed) { if (!actualExtensionsFound.has(extensionName)) { const issue = SemanticValidationIssues.EXTENSION_USED_BUT_NOT_FOUND( extensionsUsedPath, extensionName ); context.addIssue(issue); } } // Certain extensions that are 'found' must also be listed // in the 'extensionsRequired' if ( !TilesetValidator.validateExtensionsRequired( extensionsRequiredPath, actualExtensionsFound, actualExtensionsRequired, context ) ) { result = false; } return result; } /** * Validates that the extensions that are known to be 'required' actually * appear in the 'extensionsRequired' declarations when they have been * found in the tileset. * * @param path - The path for validation issues * @param actualExtensionsFound - The extensions that have been found * @param actualExtensionsRequired - The extensions from 'extensionsRequired' * @param context - The context for validation issues * @returns Whether the 'extensionsRequired' declaration was valid */ private static validateExtensionsRequired( path: string, actualExtensionsFound: Set, actualExtensionsRequired: Set, context: ValidationContext ): boolean { // There currently is no streamlined mechanism in the validator to // declare which extensions are 'required'. A good place for this // could be in ContentDataValidators.registerDefaults. Information // about the extensions that are found AND required could then be // tracked at the place where ContentDataValidator.trackExtensionsFound // is called. Special cases (like 3DTILES_content_gltf, which is // only required in 3D Tiles 1.0 but not in 1.1) make this difficult. // For now, just list the extensions that are known to be required: const requiredExtensions = ["MAXAR_content_3tz", "MAXAR_content_geojson"]; let result = true; for (const extensionName of actualExtensionsFound) { if (requiredExtensions.includes(extensionName)) { if (!actualExtensionsRequired.has(extensionName)) { const issue = SemanticValidationIssues.EXTENSION_REQUIRED_BUT_NOT_DECLARED( path, extensionName ); context.addIssue(issue); result = false; } } } return result; } /** * Validates the given `tileset.groups` * * @param groups - The groups * @param schema - The schema that was either contained in the * `tileset.schema`, or resolved from the `tileset.schemaUri` * @param context - The `ValidationContext` * @returns Whether the groups are valid */ private static validateTilesetGroups( groups: Group[], schema: Schema, context: ValidationContext ): boolean { const groupsPath = "/groups"; // The groups MUST be an array of objects if ( !BasicValidator.validateArray( groupsPath, "groups", groups, undefined, undefined, "object", context ) ) { return false; } // Validate each group against the schema let allValid = true; for (let index = 0; index < groups.length; index++) { const group = groups[index]; const groupPath = groupsPath + "/" + index; allValid = allValid && MetadataEntityValidator.validateMetadataEntity( groupPath, "group[" + index + "]", group, schema, context ); } return allValid; } } ================================================ FILE: src/validation/TransformValidator.ts ================================================ import { ValidationContext } from "./ValidationContext"; import { BasicValidator } from "./BasicValidator"; import { SemanticValidationIssues } from "../issues/SemanticValidationIssues"; import { Cartesian4 } from "cesium"; import { Math } from "cesium"; import { Matrix4 } from "cesium"; /** * A class for validations related to `tile.transform` objects. * * @internal */ export class TransformValidator { private static readonly scratchMatrix4 = new Matrix4(); /** * Performs the validation to ensure that the given object is a * valid `transform` object. * * @param path - The path for `ValidationIssue` instances * @param transform - The object to validate * @param context - The `ValidationContext` that any issues will be added to */ static validateTransform( path: string, transform: number[], context: ValidationContext ): boolean { // The transform MUST be an array of 16 numbers if ( !BasicValidator.validateArray( path, "transform", transform, 16, 16, "number", context ) ) { return false; } const matrix = Matrix4.fromArray(transform); // Check whether the matrix is affine, which means that the // last row must be epsilon-equal to (0,0,0,1) const row3 = new Cartesian4(); Matrix4.getRow(matrix, 3, row3); const isAffine = row3.equalsEpsilon(Cartesian4.UNIT_W, Math.EPSILON8); if (!isAffine) { const message = `The transform is not affine: [${transform}]`; const issue = SemanticValidationIssues.TRANSFORM_INVALID(path, message); context.addIssue(issue); return false; } return true; } } ================================================ FILE: src/validation/ValidatedElement.ts ================================================ /** * Summarizes state information about the validation of a certain * element. It contains information about * - whether the element was present in the input * - whether the element was valid * * This is used, for example, for the metadata schema definition * of a tileset: When the tileset defines a `schema` or `schemaUri`, * then the element was present (indicated by `wasPresent=true`). * The schema itself may still have been invalid. If it was * valid, then it will be stored as the `validatedElement`. * If it was not valid, then the `validatedElement` will remain * undefined. * * @internal */ export interface ValidatedElement { /** * Whether a definition for the element was found */ wasPresent: boolean; /** * The validated element. * * This can be `undefined` when... * - the input did not contain a definition (as indicated by * `wasPresent=false`) * - the input was present (as indicated by `wasPresent= true`), * but it was NOT valid */ validatedElement: T | undefined; } ================================================ FILE: src/validation/ValidationContext.ts ================================================ import path from "path"; import { defaultValue } from "3d-tiles-tools"; import { ResourceResolver } from "3d-tiles-tools"; import { ValidationIssue } from "./ValidationIssue"; import { ValidationOptions } from "./ValidationOptions"; import { ValidationResult } from "./ValidationResult"; /** * A class describing the context in which a validation takes place. * * This class is used to gather the `ValidationIssue` objects * that are created during the validation, and add them to a * `ValidationResult`. * * It also provides a `ResourceResolver` to read resources from URIs, * in the respective context. For example: When an external tileset * is encountered, a new context is derived from the given one, * which resolved resources against the base directory of the * external tileset. * * The different configuration settings that affect the behavior * of the validator (for example, whether external resources should * be validated) are stored in a `ValidationOptions` object. * * @internal */ export class ValidationContext { /** * The `ValidationOptions` for the validation process */ private _options: ValidationOptions; /** * The `ValidationResult` that receives the `ValidationIssue` instances */ private readonly _result: ValidationResult; /** * The set of extensions that have been found during the validation */ private _extensionsFound: Set; /** * The `ResourceResolver` that resolves resources that are given * as URI strings into Buffer objects, relative to the directory * in which the validation started. */ private readonly _resourceResolver: ResourceResolver; /** * The base URI that URIs should be resolved against in * this context */ private readonly _baseUri; /** * The set of absolute URIs of tilesets that are currently being * validated. When an external tileset is encountered, then its * absolute URI is added to this set. */ private _activeTilesetUris: Set; /** * The set of schema objects that will be used for validating * metadata class property semantics, in the * `ClassPropertySemanticsValidator`. */ private _semanticMatchingSchemas: Set; constructor( baseUri: string, resourceResolver: ResourceResolver, options?: ValidationOptions ) { this._options = defaultValue(options, new ValidationOptions()); this._baseUri = baseUri; this._result = ValidationResult.create(); this._resourceResolver = resourceResolver; this._extensionsFound = new Set(); this._activeTilesetUris = new Set(); this._semanticMatchingSchemas = new Set(); } /** * Derives a new context from this one. * * It uses the same `ValidationOptions` as this one. The internal * `ResourceResolver` is derived by resolving the given path * against the original `ResourceResolver`, yielding one that * resolves resources against the resulting path. * * The returned context will initially not have any records of * extensions that are 'found' (i.e. `getExtensionsFound` will * be empty). Depending on the purpose of the derived context, * and details about the validation of 'used' extensions * (see https://github.com/CesiumGS/3d-tiles-validator/issues/231 ), * the caller may decide to add the `getExtensionsUsed` of the * derived context to the context that it was derived from. * * @param uri - The (usually relative) URI * @returns The new instance */ deriveFromUri(uri: string): ValidationContext { const derivedResourceResolver = this._resourceResolver.derive(uri); const derivedBaseUri = path.join(this._baseUri, decodeURIComponent(uri)); const derived = new ValidationContext( derivedBaseUri, derivedResourceResolver, this._options ); derived._extensionsFound = new Set(); derived._activeTilesetUris = this._activeTilesetUris; derived._semanticMatchingSchemas = this._semanticMatchingSchemas; return derived; } /** * Derives a new context from this one. * * It uses the same `ValidationOptions` as this one, with * a base URI that is derived by resolving the given URI * against the current base URI, and uses the given * `ResourceResolver`. * * The returned context will initially not have any records of * extensions that are 'found' (i.e. `getExtensionsFound` will * be empty). Depending on the purpose of the derived context, * and details about the validation of 'used' extensions * (see https://github.com/CesiumGS/3d-tiles-validator/issues/231 ), * the caller may decide to add the `getExtensionsUsed` of the * derived context to the context that it was derived from. * * @param uri - The (usually relative) URI * @param resourceResolver - The resource resolver * @returns The new instance */ deriveFromResourceResolver( uri: string, resourceResolver: ResourceResolver ): ValidationContext { const derivedBaseUri = path.join(this._baseUri, decodeURIComponent(uri)); const derived = new ValidationContext( derivedBaseUri, resourceResolver, this._options ); derived._extensionsFound = new Set(); derived._activeTilesetUris = this._activeTilesetUris; derived._semanticMatchingSchemas = this._semanticMatchingSchemas; return derived; } addIssue(issue: ValidationIssue): void { this._result.add(issue); } addExtensionFound(extension: string) { this._extensionsFound.add(extension); } getExtensionsFound(): Set { return new Set(this._extensionsFound); } getResult(): ValidationResult { return this._result; } getResourceResolver(): ResourceResolver { return this._resourceResolver; } resolveUri(uri: string): string { let resolved = path.resolve(this._baseUri, decodeURIComponent(uri)); resolved = resolved.replace(/\\/g, "/"); return resolved; } addActiveTilesetUri(uri: string) { this._activeTilesetUris.add(uri); } removeActiveTilesetUri(uri: string) { this._activeTilesetUris.delete(uri); } isActiveTilesetUri(uri: string): boolean { return this._activeTilesetUris.has(uri); } addSemanticMatchingSchema(schema: any) { this._semanticMatchingSchemas.add(schema); } getSemanticMatchingSchemas(): any[] { return [...this._semanticMatchingSchemas]; } getOptions(): ValidationOptions { return this._options; } } ================================================ FILE: src/validation/ValidationContexts.ts ================================================ import fs from "fs"; import { ValidationContext } from "./ValidationContext"; /** * Methods related to `ValidationContext` instances */ export class ValidationContexts { /** * The metadata schema that contains the definitions of the * Cesium Metadata semantics. * * Note that this is not a valid `Schema` object, for the reasons * described in `addSemanticMatchingSchema` */ private static cesiumMetadataSemanticsSchema = { id: "CesiumMetadataSemantics-0.0.1", classes: { GeneralSemantics: { properties: { ID: { description: "The unique identifier for the entity.", type: "STRING", }, NAME: { description: "The name of the entity. Names should be human-readable, and do not have to be unique.", type: "STRING", }, DESCRIPTION: { description: "Description of the entity. Typically at least a phrase, and possibly several sentences or paragraphs.", type: "STRING", }, ATTRIBUTION_IDS: { description: "List of attribution IDs that index into a global list of attribution strings. This semantic may be assigned to metadata at any level of granularity including tileset, group, subtree, tile, content, feature, vertex, and texel granularity. The global list of attribution strings is located in a tileset or subtree with the property semantic ATTRIBUTION_STRINGS. The following precedence order is used to locate the attribution strings: first the containing subtree (if applicable), then the containing external tileset (if applicable), and finally the root tileset.", type: "SCALAR", array: true, componentType: "UINT(8|16|32|64)", }, ATTRIBUTION_STRINGS: { description: "List of attribution strings. Each string contains information about a data provider or copyright text. Text may include embedded markup languages such as HTML. This semantic may be assigned to metadata at any granularity (wherever STRING property values can be encoded). When used in combination with ATTRIBUTION_IDS it is assigned to subtrees and tilesets.", type: "STRING", array: true, }, }, }, TilesetMetadataSemantics: { properties: { TILESET_FEATURE_ID_LABELS: { description: "The union of all the feature ID labels in glTF content using the EXT_mesh_features and EXT_instance_features extensions.", type: "STRING", array: true, }, TILESET_CRS_GEOCENTRIC: { description: "The geocentric coordinate reference system (CRS) of the tileset.", type: "STRING", }, TILESET_CRS_COORDINATE_EPOCH: { description: "The coordinate epoch for coordinates that are referenced to a dynamic CRS such as WGS 84.", type: "STRING", }, }, }, TileMetadataSemantics: { properties: { TILE_BOUNDING_BOX: { description: "The bounding volume of the tile, expressed as a box. Equivalent to tile.boundingVolume.box.", type: "SCALAR", componentType: "FLOAT(32|64)", array: true, count: 12, }, TILE_BOUNDING_REGION: { description: "The bounding volume of the tile, expressed as a region. Equivalent to tile.boundingVolume.region.", type: "SCALAR", componentType: "FLOAT(32|64)", array: true, count: 6, }, TILE_BOUNDING_SPHERE: { description: "The bounding volume of the tile, expressed as a sphere. Equivalent to tile.boundingVolume.sphere.", type: "SCALAR", componentType: "FLOAT(32|64)", array: true, count: 4, }, TILE_BOUNDING_S2_CELL: { description: "The bounding volume of the tile, expressed as an S2 Cell ID using the 64-bit representation instead of the hexadecimal representation. Only applicable to 3DTILES_bounding_volume_S2.", type: "SCALAR", componentType: "UINT64", }, TILE_MINIMUM_HEIGHT: { description: "The minimum height of the tile above (or below) the WGS84 ellipsoid.", type: "SCALAR", componentType: "FLOAT(32|64)", }, TILE_MAXIMUM_HEIGHT: { description: "The maximum height of the tile above (or below) the WGS84 ellipsoid.", type: "SCALAR", componentType: "FLOAT(32|64)", }, TILE_HORIZON_OCCLUSION_POINT: { description: "The horizon occlusion point of the tile expressed in an ellipsoid-scaled fixed frame. If this point is below the horizon, the entire tile is below the horizon.", type: "VEC3", componentType: "FLOAT(32|64)", }, TILE_GEOMETRIC_ERROR: { description: "The geometric error of the tile. Equivalent to tile.geometricError.", type: "SCALAR", componentType: "FLOAT(32|64)", }, TILE_REFINE: { description: "The tile refinement type. Valid values are 0 (ADD) and 1 (REPLACE). Equivalent to tile.refine.", type: "SCALAR", componentType: "UINT8", }, TILE_TRANSFORM: { description: "The tile transform. Equivalent to tile.transform.", type: "MAT4", componentType: "FLOAT(32|64)", }, }, }, ContentMetadataSemantics: { properties: { CONTENT_BOUNDING_BOX: { description: "The bounding volume of the content of a tile, expressed as a box. Equivalent to tile.content.boundingVolume.box.", type: "SCALAR", componentType: "FLOAT(32|64)", array: true, count: 12, }, CONTENT_BOUNDING_REGION: { description: "The bounding volume of the content of a tile, expressed as a region. Equivalent to tile.content.boundingVolume.region.", type: "SCALAR", componentType: "FLOAT(32|64)", array: true, count: 6, }, CONTENT_BOUNDING_SPHERE: { description: "The bounding volume of the content of a tile, expressed as a sphere. Equivalent to tile.content.boundingVolume.sphere.", type: "SCALAR", componentType: "FLOAT(32|64)", array: true, count: 4, }, CONTENT_BOUNDING_S2_CELL: { description: "The bounding volume of the content of a tile, expressed as an S2 Cell ID using the 64-bit representation instead of the hexadecimal representation. Only applicable to 3DTILES_bounding_volume_S2.", type: "SCALAR", componentType: "UINT64", }, CONTENT_MINIMUM_HEIGHT: { description: "The minimum height of the content of a tile above (or below) the WGS84 ellipsoid.", type: "SCALAR", componentType: "FLOAT(32|64)", }, CONTENT_MAXIMUM_HEIGHT: { description: "The maximum height of the content of a tile above (or below) the WGS84 ellipsoid.", type: "SCALAR", componentType: "FLOAT(32|64)", }, CONTENT_HORIZON_OCCLUSION_POINT: { description: "The horizon occlusion point of the content of a tile expressed in an ellipsoid-scaled fixed frame. If this point is below the horizon, the entire content is below the horizon.", type: "VEC3", componentType: "FLOAT(32|64)", }, CONTENT_URI: { description: "The content uri. Overrides the implicit tile's generated content uri. Equivalent to tile.content.uri", type: "STRING", componentType: "FLOAT(32|64)", }, CONTENT_GROUP_ID: { description: "The content group ID. Equivalent to tile.content.group.", type: "SCALAR", componentType: "UINT(8|16|32|64)", }, }, }, }, }; /** * Initialize the schemas that are used for matching metadata property * semantics. * * This will register the default Cesium Metadata Semantic definitions, * as well as the semantic definitions from the specified schema files. * * @param context - The validation context * @param schemaFileNames - The schema file names */ static initializeSemanticMatchingSchemas( context: ValidationContext, schemaFileNames: string[] | undefined ) { context.addSemanticMatchingSchema( ValidationContexts.cesiumMetadataSemanticsSchema ); if (schemaFileNames) { for (const schemaFileName of schemaFileNames) { ValidationContexts.addSemanticMatchingSchema(context, schemaFileName); } } } /** * Add the specified schema to the given context, as a schema to be used * for matching metadata property semantics. * * The specified file is supposed to contain a full, valid metadata schema, * where the property names are just semantic names. * * To support legacy semantic definitions, it is allowed for the * `matchingSchema.classes[className].properties[semanticName].componentType` * to be a string that is used for creating a regular expression that the * actual `componentType` has to match. E.g. this may be `"FLOAT(32|64)"` * when the component type can either be `FLOAT32` or `FLOAT64`. * * Eventually, it might make sense to make the component types * unambiguous, so that the semantics definition is actually * a proper `Schema`. This could be achieved by specific semantics * like `GEOMETRIC_ERROR_FLOAT32`. * * See https://github.com/CesiumGS/3d-tiles/issues/643 * * @param context - The validation context * @param schemaFileName - The schema file name */ private static addSemanticMatchingSchema( context: ValidationContext, schemaFileName: string ) { try { const fileContents = fs.readFileSync(schemaFileName); const schema = JSON.parse(fileContents.toString()); context.addSemanticMatchingSchema(schema); } catch (e) { console.error(e); } } } ================================================ FILE: src/validation/ValidationIssue.ts ================================================ import { ValidationIssueSeverity } from "./ValidationIssueSeverity"; /** * A class summarizing the information about an issue that was * encountered during the validation process. * * @beta */ export class ValidationIssue { /** * The type of the issue. This should be an identifier for the * type of the issue, in `UPPER_SNAKE_CASE`, describing what * caused the issue. */ private readonly _type: string; /** * The path leading to the element that caused the issue. * * This resembles a "JSON path", but may contain elements * that go outside of the actual containing JSON (for example, * it may contain the name of a tile content file) */ private readonly _path: string; /** * The human-readable message that describes the issue, preferably * with information that indicates how to resolve the issue. */ private readonly _message: string; /** * A severity level for the issue (e.g. WARNING or ERROR) */ private readonly _severity: ValidationIssueSeverity; /** * Validation issues that are individual issues, which, as a whole, * caused this validation issue. * * This is used to summarize issues that may occur during the * validation of tile content or external tilesets, and which * are combined into a single validation issue. */ private readonly _causes: ValidationIssue[]; /** * Creates a new instance. See the properties documentation for * details about the given parameters. * * @param type - The type * @param path - The path * @param message - The message * @param severity - The severity * @internal */ constructor( type: string, path: string, message: string, severity: ValidationIssueSeverity ) { this._type = type; this._path = path; this._message = message; this._severity = severity; this._causes = []; } /** * Returns the type of this issue. * * This is a an identifier for the type of the issue, * in `UPPER_SNAKE_CASE`, describing what caused the * issue. * * @returns The type */ get type(): string { return this._type; } /** * Returns the path leading to the element that caused the issue. * * This resembles a "JSON path", but may contain elements * that go outside of the actual containing JSON (for example, * it may contain the name of a tile content file) * * @returns The path */ get path(): string { return this._path; } /** * Returns the human-readable message that describes the issue. * * This contains further details about the issue, often with * information that indicates how to resolve the issue. * * @returns The message */ get message(): string { return this._message; } /** * Returns the severity of this issue * * @returns The `ValidationIssueSeverity` */ get severity(): ValidationIssueSeverity { return this._severity; } /** * Adds the given validation issue as one of the 'causes' of * this issue. * * Clients should not call this function. It is only used * to construct validation issues internally. * * @param cause - The issue to add as a cause * @internal */ addCause(cause: ValidationIssue) { this._causes.push(cause); } /** * Returns a read-only view of all issues that eventually * caused this issue (this may be an empty array). * * @returns The causes of this issue */ get causes(): readonly ValidationIssue[] { return this._causes; } /** * Creates a JSON representation of this issue and all the * causes that it contains. * * @returns The JSON representation of this issue * @internal */ toJson(): any { const causesJson = this.causes.length > 0 ? this.causes.map((i) => i.toJson()) : undefined; return { type: this.type, path: this.path, message: this.message, severity: this.severity, causes: causesJson, }; } /** * Converts the given JSON object into a `ValidationIssue` instance. * * This does not perform any sanity checks on the given object. * The object is assumed to be one that was created with `toJson`. * * @param object - The object * @returns The `ValidationIssue` */ static fromJson(object: any): ValidationIssue { const type = object.type; const path = object.path; const message = object.message; const severity = object.severity; const issue = new ValidationIssue(type, path, message, severity); const causes = object.causes; if (causes != undefined) { for (const cause of causes) { const causeObject = ValidationIssue.fromJson(cause); issue.addCause(causeObject); } } return issue; } /** * Creates a JSON string representation of this issue * * @returns The string representation * @internal */ serialize(): string { return JSON.stringify(this.toJson(), undefined, 2); } /** * Parse a `ValidationIssue` from the given JSON string. * * This does not perform any sanity checks. The given string is assumed * to be in the shape that is created with `serialize`. * * @param jsonString - The JSON string * @returns The `ValidationIssue` */ static deserialize(jsonString: string): ValidationIssue { const object = JSON.parse(jsonString); return ValidationIssue.fromJson(object); } } ================================================ FILE: src/validation/ValidationIssueFilter.ts ================================================ import { ValidationIssue } from "./ValidationIssue"; /** * A predicate that is used for filtering issues that * are contained in a `ValidationResult`. * * It receives the "stack" of issues, i.e. the path * leading from the top-level issue through its * 'causes', and returns whether the leaf issue * (i.e. the last element of the issues stack) * should be included in the filtered result. * * @beta */ export type ValidationIssueFilter = (issuesStack: ValidationIssue[]) => boolean; ================================================ FILE: src/validation/ValidationIssueFilters.ts ================================================ import { ValidationIssue } from "./ValidationIssue"; import { ValidationIssueSeverity } from "./ValidationIssueSeverity"; import { ValidationIssueFilter } from "./ValidationIssueFilter"; /** * Methods related to `ValidationIssueFilter` instances. * * @beta */ export class ValidationIssueFilters { /** * Creates a `ValidationIssueFilter` that excludes all * `ValidationIssue` instances where the `ValidationIssue#type` * is one of the given strings. * * @param excludedTypes - The excluded type strings * @returns The `ValidationIssueFilter` */ static byExcludedTypes(...excludedTypes: string[]): ValidationIssueFilter { const predicate = (issues: ValidationIssue[]) => !excludedTypes.includes(issues[issues.length - 1].type); return predicate; } /** * Creates a `ValidationIssueFilter` that includes all * `ValidationIssue` instances where the `ValidationIssue#severity` * is one of the given severities. * * @param includedSeverities - The included severities * @returns The `ValidationIssueFilter` */ static byIncludedSeverities( ...includedSeverities: ValidationIssueSeverity[] ): ValidationIssueFilter { const predicate = (issues: ValidationIssue[]) => includedSeverities.includes(issues[issues.length - 1].severity); return predicate; } } ================================================ FILE: src/validation/ValidationIssueSeverity.ts ================================================ /** * An enumeration of different severity levels for a * `ValidationIssue` * * @beta */ export enum ValidationIssueSeverity { /** * An error, indicating that the validation failed */ ERROR = "ERROR", /** * A warning, indicating that validation passed, but * the input might cause unexpected or undesired * behavior in clients. */ WARNING = "WARNING", /** * An information that does not affect the validity. * This may affect the runtime behavior of specific * client applications. */ INFO = "INFO", } ================================================ FILE: src/validation/ValidationOptionChecks.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationOptions } from "./ValidationOptions"; import { ContentData } from "3d-tiles-tools"; import { ContentDataTypeRegistry } from "3d-tiles-tools"; /** * A class for checking the settings that are stored * in a `ValidationOptions` object, and determine * whether (and how) certain validation steps should * be performed. * * @internal */ export class ValidationOptionChecks { /** * Examines the given validation options, to see whether the given * content data should be validated. * * @param options - The validation options * @param contentData - The content data * @returns Whether the content data should be validated */ static async shouldValidate( options: ValidationOptions, contentData: ContentData ): Promise { if (!options.validateContentData) { return false; } const name = await ContentDataTypeRegistry.findContentDataType(contentData); if (!defined(name)) { return false; } let isIncluded = true; let isExcluded = false; const included = options.includeContentTypes; if (defined(included)) { isIncluded = included.includes(name); } const excluded = options.excludeContentTypes; if (defined(excluded)) { isExcluded = excluded.includes(name); } return isIncluded && !isExcluded; } } ================================================ FILE: src/validation/ValidationOptions.ts ================================================ import { ValidationIssueSeverity } from "./ValidationIssueSeverity"; /** * A class describing the options for a validator within * a `ValidationContext` * * Note: Some aspects of this class are preliminary. The exact * options and their representation in this class may still * change. * * @beta */ export class ValidationOptions { /** * Whether content data should be validated at all. */ private _validateContentData: boolean; /** * The severity of content validation issues that should be * included in the results. */ private _contentValidationIssueSeverity: ValidationIssueSeverity; /** * The content types that are included in the validation. */ private _includeContentTypes: string[] | undefined; /** * The content types that are included in the validation. */ private _excludeContentTypes: string[] | undefined; /** * The names of files that contain metadata schemas with * semantic definitions */ private _semanticSchemaFileNames: string[] | undefined; /** * Default constructor. * * The default options will be: * * - `validateContentData = true`, causing content data to be validated * - `includeContentTypes = undefined`, causing ALL known content * types to be included in the validation. * - `excludeContentTypes = undefined`, causing NO known content * types to be excluded the validation. */ constructor() { this._validateContentData = true; this._contentValidationIssueSeverity = ValidationIssueSeverity.INFO; this._includeContentTypes = undefined; this._excludeContentTypes = undefined; this._semanticSchemaFileNames = undefined; } /** * The flag that indicates whether content data should * be validated at all. When this is `false`, then * all content data validations will be skipped. */ get validateContentData(): boolean { return this._validateContentData; } set validateContentData(value: boolean) { this._validateContentData = value; } /** * The severity of content validation issues that should * be included in the result. * * By default, this will be `INFO`, meaning that all content * validation issues will be included. It can be set to * `WARNING`, to include all `ERROR` and `WARNING` issues, * or to `ERROR` to only include `ERROR` issues. */ get contentValidationIssueSeverity(): ValidationIssueSeverity { return this._contentValidationIssueSeverity; } set contentValidationIssueSeverity(value: ValidationIssueSeverity) { this._contentValidationIssueSeverity = value; } /** * The content types that should be included. * * This is an array containing any of the following content * type descriptors: * * - `CONTENT_TYPE_TILESET` (for external tilesets) * * - `CONTENT_TYPE_GLB` (for binary glTF only) * * - `CONTENT_TYPE_GLTF` (for JSON-based glTF) * * - `CONTENT_TYPE_B3DM` * * - `CONTENT_TYPE_I3DM` * * - `CONTENT_TYPE_CMPT` * * - `CONTENT_TYPE_PNTS` * * - `CONTENT_TYPE_3TZ` (Experimental support) * * - `CONTENT_TYPE_GEOM` (Not validated yet) * * - `CONTENT_TYPE_VCTR` (Not validated yet) * * - `CONTENT_TYPE_GEOJSON` (Not validated yet) * * If this is `undefined`, then ALL known content types * will be included. Note that this may mean that * encountering certain content types will cause a * validation warning when the content type validation * is not implemented. */ get includeContentTypes(): string[] | undefined { return this._includeContentTypes; } set includeContentTypes(value: string[] | undefined) { this._includeContentTypes = value; } /** * The content types that should be excluded. * * See `includeContentTypes` for details. * * If this is `undefined`, then NO known content type * will be excluded. */ get excludeContentTypes(): string[] | undefined { return this._excludeContentTypes; } set excludeContentTypes(value: string[] | undefined) { this._excludeContentTypes = value; } /** * The names of files that contain metadata schema definitions * for the valid metadata semantics */ get semanticSchemaFileNames(): string[] | undefined { return this._semanticSchemaFileNames; } set semanticSchemaFileNames(value: string[] | undefined) { this._semanticSchemaFileNames = value; } /** * Creates a new `ValidationOptions` object where each property is * initialized from the given JSON object. * * @param json - The input JSON object * @returns The validation options */ static fromJson(json: any): ValidationOptions { const options: ValidationOptions = Object.assign( new ValidationOptions(), json ); return options; } } ================================================ FILE: src/validation/ValidationResult.ts ================================================ import { ValidationIssue } from "./ValidationIssue"; import { ValidationIssueFilter } from "./ValidationIssueFilter"; import { ValidationIssueSeverity } from "./ValidationIssueSeverity"; import { ValidationResults } from "./ValidationResults"; /** * A class summarizing the result of a validation pass. * * It mainly summarizes a set of `ValidationIssue` instances. * * @beta */ export class ValidationResult { /** * The date when this instance was created (this * indicates the start of the validation process) */ private readonly _date: Date; /** * The list of `ValidationIssue` instances */ private readonly _issues: ValidationIssue[]; /** * Creates a new, empty validation result. * * Clients should not call this method. They only receive * validation results from the validation methods. * * @returns The new `ValidationResult` * @internal */ static create(): ValidationResult { return new ValidationResult(new Date(Date.now())); } /** * Private constructor for `filter` * * @param date - The date that is stored in the result */ private constructor(date: Date) { this._date = date; this._issues = []; } /** * Creates a new `ValidationResult` by filtering this one, * using the given `ValidationIssueFilter` as the inclusion * predicate. * * @param includePredicate - The predicate that determines whether * a certain issue should be included in the result * @returns The filtered result */ filter(includePredicate: ValidationIssueFilter): ValidationResult { const result = new ValidationResult(this._date); ValidationResults.filter(this, includePredicate, result); return result; } /** * Returns a read-only view on the issues of this result */ get issues(): readonly ValidationIssue[] { return this._issues; } /** * Adds a new `ValidationIssue` to this result. * * This method should not be called by clients. It is mainly * intended for the `ValidationContext#addIssue` method, * to collect the issues during validation. * * @param issue - The `ValidationIssue` to add. * @internal */ add(issue: ValidationIssue): void { this._issues.push(issue); } /** * Returns the number of issues that are contained in this result * * @returns The number of issues */ get length(): number { return this._issues.length; } /** * Returns the validation issue at the specified index in this * result * * @param index - The index * @returns The validation issue */ get(index: number): ValidationIssue { return this._issues[index]; } /** * Computes the number of issues in this result that have * the `ERROR` severity level * * @internal */ get numErrors(): number { return this.count(ValidationIssueSeverity.ERROR); } /** * Computes the number of issues in this result that have * the `WARNING` severity level * * @internal */ get numWarnings(): number { return this.count(ValidationIssueSeverity.WARNING); } /** * Computes the number of issues in this result that have * the `INFO` severity level * * @internal */ get numInfos(): number { return this.count(ValidationIssueSeverity.INFO); } /** * Counts the number of issues in this result that have the * given severity level * * @param severity - The severity level * @returns The number of issues */ private count(severity: ValidationIssueSeverity): number { return this._issues.reduce((accumulator, element) => { if (element.severity === severity) { return accumulator + 1; } return accumulator; }, 0); } /** * Creates a JSON representation of this result and all the * issues that it contains. * * @returns The JSON representation of this result * @internal */ toJson(): any { const issuesJson = this._issues.length > 0 ? this._issues.map((i) => i.toJson()) : undefined; const numErrors = this.numErrors; const numWarnings = this.numWarnings; const numInfos = this.numInfos; return { date: this._date, numErrors: numErrors, numWarnings: numWarnings, numInfos: numInfos, issues: issuesJson, }; } /** * Converts the given JSON object into a `ValidationResult` instance. * * This does not perform any sanity checks on the given object. * The object is assumed to be one that was created with `toJson`. * * @param object - The object * @returns The `ValidationResult` */ static fromJson(object: any) { const result = ValidationResult.create(); const issues = object.issues; for (const issue of issues) { result.add(ValidationIssue.fromJson(issue)); } return result; } /** * Creates a JSON string representation of this result. * * Some details about the format of this result are not yet * specified, and might change in future releases. * * @returns The string representation */ serialize(): string { return JSON.stringify(this.toJson(), undefined, 2); } /** * Parse a `ValidationResult` from the given JSON string. * * This does not perform any sanity checks. The given string is assumed * to be in the shape that is created with `serialize`. * * @param jsonString - The JSON string * @returns The `ValidationResult` */ static deserialize(jsonString: string): ValidationResult { const object = JSON.parse(jsonString); return ValidationResult.fromJson(object); } } ================================================ FILE: src/validation/ValidationResults.ts ================================================ import { ValidationIssue } from "./ValidationIssue"; import { ValidationResult } from "./ValidationResult"; import { ValidationIssueFilter } from "./ValidationIssueFilter"; /** * Methods related to `ValidationResult` instances. * * These are used internally, for the implementation of the * `ValidationResult#filter` operation. * * @internal */ export class ValidationResults { /** * Filters the issues of the given input `ValidationResults`, * and passes the includes ones to the given output. * * @param input - The input `ValidationResult` * @param inclusionPredicate - The predicate that says whether * a certain issue should be included in the result. * @param output - The `ValidationResult` to which * the included issues will be added. */ static filter( input: ValidationResult, inclusionPredicate: ValidationIssueFilter, output: ValidationResult ): void { const inputIssues = input.issues; const outputIssues = ValidationResults.filterIssues( inputIssues, [], inclusionPredicate ); for (const outputIssue of outputIssues) { output.add(outputIssue); } } /** * Filters the given array of issues, and returns a new * array with the filtered issues. * * Note that this does a "deep" filtering: It applies the * given predicate to each element of the given array, and * to all 'causes' of each element, recursively. * * The 'issuesStack' keeps track of the path from the * root issue to the current issue during that recursion. * * @param inputIssues - The input issues * @param issuesStack - The stack of issues * @param inclusionPredicate - The inclusion predicate * @returns The filtered issues */ private static filterIssues( inputIssues: readonly ValidationIssue[], issuesStack: ValidationIssue[], inclusionPredicate: ValidationIssueFilter ): ValidationIssue[] { const outputIssues = []; for (let i = 0; i < inputIssues.length; i++) { const inputIssue = inputIssues[i]; issuesStack.push(inputIssue); const included = inclusionPredicate(issuesStack); if (included) { const outputIssue = ValidationResults.filterCauses( inputIssue, issuesStack, inclusionPredicate ); outputIssues.push(outputIssue); } issuesStack.pop(); } return outputIssues; } /** * Applies the given filter to all 'causes' of the given * issue, and returns a new issue that is equal to the * given input, but with the 'causes' filtered accordingly. * * @param inputIssue - The input issue * @param issuesStack - The issues stack * @param inclusionPredicate - The inclusion predicate * @returns The filtered issue */ private static filterCauses( inputIssue: ValidationIssue, issuesStack: ValidationIssue[], inclusionPredicate: ValidationIssueFilter ): ValidationIssue { const outputIssue = new ValidationIssue( inputIssue.type, inputIssue.path, inputIssue.message, inputIssue.severity ); const inputCauses = inputIssue.causes; const outputCauses = ValidationResults.filterIssues( inputCauses, issuesStack, inclusionPredicate ); for (const outputCause of outputCauses) { outputIssue.addCause(outputCause); } return outputIssue; } /** * Only used for tests and debugging: * * Creates a string representation of the given validation result * that only consists of the 'type' of each validation issue, * indented to reflect the structure of the issues and their causes. * * @param inputResult - The validation result * @returns The string representation */ static createSimpleResultString(inputResult: ValidationResult): string { let result = ""; const inputIssues = inputResult.issues; for (const inputIssue of inputIssues) { const issueString = ValidationResults.createSimpleIssueString( inputIssue, "" ); result += issueString; } return result; } /** * Only used for tests and debugging: * * Creates a string representation of the given validation issue that * only consists of the 'type' of this issue and all its causes. * * @param inputIssue - The issue * @param indentation - The indentation to use * @returns The string representation */ private static createSimpleIssueString( inputIssue: ValidationIssue, indentation: string ): string { let result = ""; result += indentation + inputIssue.type + "\n"; for (const cause of inputIssue.causes) { const causeString = ValidationResults.createSimpleIssueString( cause, indentation + " " ); result += causeString; } return result; } } ================================================ FILE: src/validation/ValidationState.ts ================================================ import { Schema } from "3d-tiles-tools"; import { Group } from "3d-tiles-tools"; import { ValidatedElement } from "./ValidatedElement"; /** * A class that summarizes state information about the validation * of a tileset. It contains information about the state of the * validation of various components that is required to selectively * perform or skip other validation steps. * * @internal */ export type ValidationState = { /** * The state describing the validation of the metadata schema */ schemaState: ValidatedElement; /** * The state describing the validation of the groups */ groupsState: ValidatedElement; }; ================================================ FILE: src/validation/Validator.ts ================================================ import { ValidationContext } from "./ValidationContext"; /** * Interface for classes that can perform generic validation of an object, * detect issues, and add them to a `ValidationContext` * * @internal */ export interface Validator { /** * Performs the validation of the given object, and adds all issues * that are detected to the given `ValidationContext`. * * @param input - The input object * @param context - The `ValidationContext` * @returns A promise that is fulfilled when the validation is finished * and indicates whether the object was valid or not. */ validateObject( path: string, input: T, context: ValidationContext ): Promise; } ================================================ FILE: src/validation/Validators.ts ================================================ import path from "path"; import fs from "fs"; import { defined, Schema } from "3d-tiles-tools"; import { LazyContentData } from "3d-tiles-tools"; import { Buffers } from "3d-tiles-tools"; import { ResourceResolvers } from "3d-tiles-tools"; import { TileImplicitTiling } from "3d-tiles-tools"; import { Validator } from "./Validator"; import { TilesetValidator } from "./TilesetValidator"; import { ValidationContext } from "./ValidationContext"; import { ValidationResult } from "./ValidationResult"; import { SubtreeValidator } from "./SubtreeValidator"; import { ValidationOptions } from "./ValidationOptions"; import { ExtendedObjectsValidators } from "./ExtendedObjectsValidators"; import { TilesetPackageValidator } from "./TilesetPackageValidator"; import { ContentDataValidators } from "./ContentDataValidators"; import { ValidatedElement } from "./ValidatedElement"; import { ValidationContexts } from "./ValidationContexts"; import { SchemaValidator } from "./metadata/SchemaValidator"; import { IoValidationIssues } from "../issues/IoValidationIssue"; import { ContentValidationIssues } from "../issues/ContentValidationIssues"; import { BoundingVolumeS2Validator } from "./extensions/BoundingVolumeS2Validator"; import { NgaGpmValidator } from "./extensions/NgaGpmValidator"; import { ContentGltfValidator } from "./extensions/ContentGltfValidator"; import { MaxarExtentValidator } from "./extensions/MaxarExtentValidator"; import { MaxarGridValidator } from "./extensions/MaxarGridValidator"; import { MaxarContentGeojsonValidator } from "./extensions/MaxarContentGeojsonValidator"; /** * Utility methods related to `Validator` instances. * * @beta */ export class Validators { /** * Whether the knows extension validators have already been registered * by calling `registerExtensionValidators`. * * Note: This could be solved with a static initializer block, but the * unclear initialization order of the classes would make this brittle */ private static _registeredExtensionValidators = false; /** * Creates a `TilesetValidator` with an unspecified default configuration. * * @returns The `TilesetValidator` * @internal */ static createDefaultTilesetValidator(): TilesetValidator { const validator = new TilesetValidator(); return validator; } /** * Performs a default validation of the given tileset file, and * returns a promise to the `ValidationResult`. * * The given file may be a `tileset.json` file, or a tileset * package file, as indicated by a `.3tz` or `.3dtiles` file * extensions. * * @param filePath - The file path * @param validationOptions - The `ValidationOptions`. When this * is not given (or `undefined`), then default validation options * will be used. See {@link ValidationOptions}. * @returns A promise to a `ValidationResult` that is fulfilled when * the validation finished. * @beta */ static async validateTilesetFile( filePath: string, validationOptions?: ValidationOptions ): Promise { const extension = path.extname(filePath).toLowerCase(); const isDirectory = fs.statSync(filePath).isDirectory(); const packageExtensions = [".3tz", ".3dtiles"]; const isPackage = packageExtensions.includes(extension); if (isPackage || isDirectory) { const validationResult = await Validators.validateTilesetPackageInternal( filePath, validationOptions ); return validationResult; } const validationResult = await Validators.validateTilesetFileInternal( filePath, validationOptions ); return validationResult; } /** * Performs a default validation of the given `tileset.json` file, and * returns a promise to the `ValidationResult`. * * @param filePath - The file path * @param validationOptions - The `ValidationOptions`. When this * is not given (or `undefined`), then default validation options * will be used. See {@link ValidationOptions}. * @returns A promise to a `ValidationResult` that is fulfilled when * the validation finished. * @beta */ private static async validateTilesetFileInternal( filePath: string, validationOptions?: ValidationOptions ): Promise { Validators.registerExtensionValidators(); const directory = path.dirname(filePath); const fileName = path.basename(filePath); const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); const validator = Validators.createDefaultTilesetValidator(); const context = new ValidationContext( directory, resourceResolver, validationOptions ); ValidationContexts.initializeSemanticMatchingSchemas( context, validationOptions?.semanticSchemaFileNames ); const tilesetUri = context.resolveUri(fileName); context.addActiveTilesetUri(tilesetUri); const resourceData = await resourceResolver.resolveData(fileName); if (!defined(resourceData)) { const message = `Could not read input file: ${filePath}`; const issue = IoValidationIssues.IO_ERROR(filePath, message); context.addIssue(issue); } else { const bom = Buffers.getUnicodeBOMDescription(resourceData); if (defined(bom)) { const message = `Unexpected BOM in JSON buffer: ${bom}`; const issue = IoValidationIssues.IO_ERROR(filePath, message); context.addIssue(issue); } else { const jsonString = resourceData.toString(); await validator.validateJsonString(jsonString, context); } } context.removeActiveTilesetUri(tilesetUri); return context.getResult(); } /** * Performs a default validation of the given tileset package file, and * returns a promise to the `ValidationResult`. * * The given path may be a path of a `.3tz` or a `.3dtiles` file (or * a directory that contains a 'tileset.json' file) * * @param filePath - The file path * @param validationOptions - The `ValidationOptions`. When this * is not given (or `undefined`), then default validation options * will be used. See {@link ValidationOptions}. * @returns A promise to a `ValidationResult` that is fulfilled when * the validation finished. * @beta */ private static async validateTilesetPackageInternal( filePath: string, validationOptions?: ValidationOptions ): Promise { Validators.registerExtensionValidators(); const directory = path.dirname(filePath); const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); const context = new ValidationContext( directory, resourceResolver, validationOptions ); ValidationContexts.initializeSemanticMatchingSchemas( context, validationOptions?.semanticSchemaFileNames ); const tilesetUri = context.resolveUri(filePath); context.addActiveTilesetUri(tilesetUri); await TilesetPackageValidator.validatePackageFile(filePath, context); context.removeActiveTilesetUri(tilesetUri); return context.getResult(); } /** * Performs a default validation of the given tile content file, and * returns a promise to the `ValidationResult`. * * The given file may be of any format. The method will detect * the format, and decide whether it can perform a sensible * validation, based on the existing validation functionality. * * @param filePath - The file path * @param validationOptions - The `ValidationOptions`. When this * is not given (or `undefined`), then default validation options * will be used. See {@link ValidationOptions}. * @returns A promise to a `ValidationResult` that is fulfilled when * the validation finished. * @beta */ static async validateTileContentFile( filePath: string, validationOptions?: ValidationOptions ): Promise { const directory = path.dirname(filePath); const fileName = path.basename(filePath); const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); const context = new ValidationContext( directory, resourceResolver, validationOptions ); ValidationContexts.initializeSemanticMatchingSchemas( context, validationOptions?.semanticSchemaFileNames ); const contentData = new LazyContentData(fileName, resourceResolver); // Check if the file exists, and bail out early if it doesn't const dataExists = await contentData.exists(); if (!dataExists) { const message = `Content file ${filePath} could not be resolved`; const issue = ContentValidationIssues.CONTENT_VALIDATION_ERROR( filePath, message ); context.addIssue(issue); return context.getResult(); } // Find the validator for the content data, and bail // out early if none could be found const dataValidator = await ContentDataValidators.findContentDataValidator( contentData ); if (!defined(dataValidator)) { const message = `No valid content type could be determined for ${filePath}`; const issue = ContentValidationIssues.CONTENT_VALIDATION_WARNING( filePath, message ); context.addIssue(issue); return context.getResult(); } // Perform the actual validation await dataValidator.validateObject(fileName, contentData, context); return context.getResult(); } /** * Creates a `SchemaValidator` with an unspecified default configuration. * * @returns The `SchemaValidator` * @internal */ static createDefaultSchemaValidator(): SchemaValidator { const validator = new SchemaValidator(); return validator; } /** * Performs a default validation of the given schema JSON file, and * returns a promise to the `ValidationResult`. * * @param filePath - The file path * @returns A promise to a `ValidationResult` that is fulfilled when * the validation finished. * @internal */ static async validateSchemaFile(filePath: string): Promise { const directory = path.dirname(filePath); const fileName = path.basename(filePath); const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); const resourceData = await resourceResolver.resolveData(fileName); const validator = Validators.createDefaultSchemaValidator(); const context = new ValidationContext(directory, resourceResolver); ValidationContexts.initializeSemanticMatchingSchemas(context, undefined); const jsonString = resourceData ? resourceData.toString() : ""; await validator.validateJsonString(jsonString, context); return context.getResult(); } /** * Creates a `SubtreeValidator` with an unspecified default configuration. * * @returns The `SubtreeValidator` * @internal */ static createDefaultSubtreeValidator( uri: string, schemaState: ValidatedElement, implicitTiling: TileImplicitTiling | undefined ): SubtreeValidator { const directory = path.dirname(uri); const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); const validator = new SubtreeValidator( schemaState, implicitTiling, resourceResolver ); return validator; } /** * Performs a default validation of the given subtree JSON file, and * returns a promise to the `ValidationResult`. * * @param filePath - The file path * @returns A promise to a `ValidationResult` that is fulfilled when * the validation finished. * @internal */ static async validateSubtreeFile( filePath: string, schemaState: ValidatedElement, implicitTiling: TileImplicitTiling | undefined ): Promise { const directory = path.dirname(filePath); const fileName = path.basename(filePath); const resourceResolver = ResourceResolvers.createFileResourceResolver(directory); const resourceData = await resourceResolver.resolveData(fileName); const validator = Validators.createDefaultSubtreeValidator( filePath, schemaState, implicitTiling ); const context = new ValidationContext(directory, resourceResolver); ValidationContexts.initializeSemanticMatchingSchemas(context, undefined); if (!defined(resourceData)) { const message = `Could not read subtree file ${filePath}`; const issue = IoValidationIssues.IO_ERROR(filePath, message); context.addIssue(issue); } else { await validator.validateObject(filePath, resourceData, context); } return context.getResult(); } /** * Creates a validator for `Buffer` objects that parses an * object of type `T` from the (JSON) string representation * of the buffer contents, and applies the given delegate * to the result. * * If the object cannot be parsed, a `JSON_PARSE_ERROR` * will be added to the given context. * * @param delegate - The delegate * @returns The new validator * @internal */ static parseFromBuffer(delegate: Validator): Validator { return { async validateObject( inputPath: string, input: Buffer, context: ValidationContext ): Promise { try { const bom = Buffers.getUnicodeBOMDescription(input); if (defined(bom)) { const message = `Unexpected BOM in JSON buffer: ${bom}`; const issue = IoValidationIssues.IO_ERROR(inputPath, message); context.addIssue(issue); return false; } const object: T = JSON.parse(input.toString()); const delegateResult = await delegate.validateObject( inputPath, object, context ); return delegateResult; } catch (error) { const message = `${error}`; const issue = IoValidationIssues.JSON_PARSE_ERROR(inputPath, message); context.addIssue(issue); return false; } }, }; } /** * Creates a `Validator` that only adds a `CONTENT_VALIDATION_INFO` * with the given message to the given context when it is called. * * This is used for "dummy" validators that handle content data types * that are already anticipated (like VCTR or GEOM), but not validated * explicitly. * * @param message - The message for the info * @returns The new validator * @internal */ static createContentValidationInfo(message: string): Validator { return { async validateObject( inputPath: string, //eslint-disable-next-line @typescript-eslint/no-unused-vars input: Buffer, context: ValidationContext ): Promise { const issue = ContentValidationIssues.CONTENT_VALIDATION_INFO( inputPath, message ); context.addIssue(issue); return true; }, }; } /** * Creates an empty validator that does nothing. * * This is used for "dummy" validators for content types that * are ignored. * * @returns The new validator * @internal */ static createEmptyValidator(): Validator { return { async validateObject( //eslint-disable-next-line @typescript-eslint/no-unused-vars inputPath: string, //eslint-disable-next-line @typescript-eslint/no-unused-vars input: T, //eslint-disable-next-line @typescript-eslint/no-unused-vars context: ValidationContext ): Promise { return true; }, }; } /** * Register the validators for known extensions */ private static registerExtensionValidators() { if (Validators._registeredExtensionValidators) { return; } // Register the validator for 3DTILES_bounding_volume_S2 { const s2Validator = new BoundingVolumeS2Validator(); const override = true; ExtendedObjectsValidators.register( "3DTILES_bounding_volume_S2", s2Validator, override ); } // Register the validator for 3DTILES_content_gltf { const contentGltfValidator = new ContentGltfValidator(); const override = false; ExtendedObjectsValidators.register( "3DTILES_content_gltf", contentGltfValidator, override ); } // Register the validator for MAXAR_content_geojson { const maxarContentGeojsonValidator = new MaxarContentGeojsonValidator(); const override = false; ExtendedObjectsValidators.register( "MAXAR_content_geojson", maxarContentGeojsonValidator, override ); } // Register the validator for MAXAR_extent { const maxarExtentValidator = new MaxarExtentValidator(); const override = false; ExtendedObjectsValidators.register( "MAXAR_extent", maxarExtentValidator, override ); } // Register the validator for MAXAR_grid { const maxarGridValidator = new MaxarGridValidator(); const override = false; ExtendedObjectsValidators.register( "MAXAR_grid", maxarGridValidator, override ); } // Register an empty validator for VRICON_class { const emptyValidator = Validators.createEmptyValidator(); const override = false; ExtendedObjectsValidators.register( "VRICON_class", emptyValidator, override ); } // Register an empty validator for VRICON_grid { const emptyValidator = Validators.createEmptyValidator(); const override = false; ExtendedObjectsValidators.register( "VRICON_grid", emptyValidator, override ); } // Register the validator for NGA_gpm { const ngaGpmValidator = new NgaGpmValidator(); const override = false; ExtendedObjectsValidators.register("NGA_gpm", ngaGpmValidator, override); } Validators._registeredExtensionValidators = true; } } ================================================ FILE: src/validation/extensions/BoundingVolumeS2ValidationIssues.ts ================================================ import { ValidationIssue } from "../../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../../validation/ValidationIssueSeverity"; export class BoundingVolumeS2ValidationIssues { static S2_TOKEN_INVALID(path: string, message: string) { const type = "S2_TOKEN_INVALID"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/validation/extensions/BoundingVolumeS2Validator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Validator } from "../Validator"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { BoundingVolumeValidator } from "../BoundingVolumeValidator"; import { RootPropertyValidator } from "../RootPropertyValidator"; import { ExtendedObjectsValidators } from "../ExtendedObjectsValidators"; import { SemanticValidationIssues } from "../../issues/SemanticValidationIssues"; import { BoundingVolumeS2ValidationIssues } from "./BoundingVolumeS2ValidationIssues"; /** * A class for the validation of bounding volumes that contain * `3DTILES_bounding_volume_S2` extension objects * * @internal */ export class BoundingVolumeS2Validator implements Validator { /** * Performs the validation of a `BoundingVolume` object that * contains a `3DTILES_bounding_volume_S2` extension object. * * @param path - The path for `ValidationIssue` instances * @param boundingVolume - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ async validateObject( path: string, boundingVolume: any, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "boundingVolume", boundingVolume, context ) ) { return false; } let result = true; // Validate the box const box = boundingVolume.box; const boxPath = path + "/box"; if (defined(box)) { if (!BoundingVolumeValidator.validateBoundingBox(boxPath, box, context)) { result = false; } } // Validate the region const region = boundingVolume.region; const regionPath = path + "/region"; if (defined(region)) { if ( !BoundingVolumeValidator.validateBoundingRegion( regionPath, region, context ) ) { result = false; } } // Validate the sphere const sphere = boundingVolume.sphere; const spherePath = path + "/sphere"; if (defined(sphere)) { if ( !BoundingVolumeValidator.validateBoundingSphere( spherePath, sphere, context ) ) { result = false; } } // If there is a 3DTILES_bounding_volume_S2 extension, // perform the validation of the corresponding object const extensions = boundingVolume.extensions; if (defined(extensions)) { const key = "3DTILES_bounding_volume_S2"; const s2 = extensions[key]; const s2Path = path + "/" + key; if ( !BoundingVolumeS2Validator.validateBoundingVolumeS2(s2Path, s2, context) ) { result = false; } } return result; } /** * Performs the validation to ensure that the given object is a * valid `3DTILES_bounding_volume_S2` object. * * @param path - The path for `ValidationIssue` instances * @param object - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateBoundingVolumeS2( path: string, object: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "object", object, context)) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, "3DTILES_bounding_volume_S2", object, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject(path, object, context) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(object)) { return result; } // Validate the token const token = object.token; const tokenPath = path + "/token"; // The token MUST be defined // The token MUST be a string if (!BasicValidator.validateString(tokenPath, "token", token, context)) { result = false; } else { // The token MUST be a valid S2 token if (!BoundingVolumeS2Validator.isValidToken(token)) { const message = `The S2 token '${token}' is not valid`; const issue = BoundingVolumeS2ValidationIssues.S2_TOKEN_INVALID( tokenPath, message ); context.addIssue(issue); result = false; } } // Validate the minimumHeight const minimumHeight = object.minimumHeight; const minimumHeightPath = path + "/minimumHeight"; // The minimumHeight MUST be a number if ( !BasicValidator.validateNumber( minimumHeightPath, "minimumHeight", minimumHeight, context ) ) { result = false; } // Validate the maximumHeight const maximumHeight = object.maximumHeight; const maximumHeightPath = path + "/maximumHeight"; // The maximumHeight MUST be a number if ( !BasicValidator.validateNumber( maximumHeightPath, "maximumHeight", maximumHeight, context ) ) { result = false; } // The minimumHeight MUST NOT be larger // than the maximumHeight if (defined(minimumHeight) && defined(maximumHeight)) { if (minimumHeight > maximumHeight) { const message = `The minimumHeight may not be larger than the ` + `maximumHeight, but the minimumHeight is ${minimumHeight} ` + `and the maximum height is ${maximumHeight}`; const issue = SemanticValidationIssues.BOUNDING_VOLUME_INVALID( path, message ); context.addIssue(issue); result = false; } } return result; } /** * Performs a basic validation that the given string is a valid S2 cell token * * @param token - The token * @returns Whether the token is valid */ private static isValidToken(token: string): boolean { // According to cesium/Source/Core/S2Cell.js if (!/^[0-9a-fA-F]{1,16}$/.test(token)) { return false; } // Further constraints could be added here (e.g. that // the first digit is only a value in [0,5] ...) return true; } } ================================================ FILE: src/validation/extensions/ContentGltfValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Validator } from "../Validator"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { ExtensionsDeclarationsValidator } from "../ExtensionsDeclarationsValidator"; /** * A class for the validation of `3DTILES_content_gltf` extension objects * * @internal */ export class ContentGltfValidator implements Validator { /** * Performs the validation of a `Tileset` object that * contains a `3DTILES_content_gltf` extension object. * * @param path - The path for `ValidationIssue` instances * @param boundingVolume - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ async validateObject( path: string, tileset: any, context: ValidationContext ): Promise { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "tileset", tileset, context)) { return false; } let result = true; // If there is a 3DTILES_content_gltf extension, // perform the validation of the corresponding object const extensions = tileset.extensions; if (defined(extensions)) { const key = "3DTILES_content_gltf"; const extension = extensions[key]; const extensionPath = path + "/" + key; if ( !ContentGltfValidator.validateContentGltf( extensionPath, extension, context ) ) { result = false; } } return result; } /** * Performs the validation to ensure that the given object is a * valid `3DTILES_content_gltf` object. * * @param path - The path for `ValidationIssue` instances * @param object - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateContentGltf( path: string, object: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "object", object, context)) { return false; } const extensionsUsed = object.extensionsUsed; const extensionsRequired = object.extensionsRequired; return ExtensionsDeclarationsValidator.validateExtensionDeclarationConsistency( path, extensionsUsed, extensionsRequired, context ); } } ================================================ FILE: src/validation/extensions/MaxarContentGeojsonValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Validator } from "../Validator"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { JsonValidationIssues } from "../../issues/JsonValidationIssues"; import { IoValidationIssues } from "../../issues/IoValidationIssue"; /** * A class for the validation of `MAXAR_content_geojson` extension objects * * @internal */ export class MaxarContentGeojsonValidator implements Validator { /** * Performs the validation of a metadata entity object that may contain * a `MAXAR_content_geojson` extension. * * @param path - The path for ValidationIssue instances * @param metadataEntity - The metadata entity object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ async validateObject( path: string, metadataEntity: any, context: ValidationContext ): Promise { let result = true; // If there is a MAXAR_content_geojson extension, // perform the validation of the corresponding object const extensions = metadataEntity.extensions; if (defined(extensions)) { const key = "MAXAR_content_geojson"; const extension = extensions[key]; const extensionPath = path + "/extensions/" + key; const extensionValid = await MaxarContentGeojsonValidator.validateMaxarContentGeojson( extensionPath, extension, context ); if (!extensionValid) { result = false; } } return result; } /** * Validates a MAXAR_content_geojson extension object * * @param path - The path for ValidationIssue instances * @param maxar_content_geojson - The MAXAR_content_geojson object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ static async validateMaxarContentGeojson( path: string, maxar_content_geojson: any, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "MAXAR_content_geojson", maxar_content_geojson, context ) ) { return false; } let result = true; // Validate propertiesSchemaUri property (optional) const propertiesSchemaUri = maxar_content_geojson.propertiesSchemaUri; if (defined(propertiesSchemaUri)) { const propertiesSchemaUriPath = path + "/propertiesSchemaUri"; if ( !BasicValidator.validateString( propertiesSchemaUriPath, "propertiesSchemaUri", propertiesSchemaUri, context ) ) { result = false; } else { // Validate URI format if ( !MaxarContentGeojsonValidator.validateUriFormat( propertiesSchemaUriPath, "propertiesSchemaUri", propertiesSchemaUri, context ) ) { result = false; } else { // Validate the referenced schema content const schemaValid = await MaxarContentGeojsonValidator.validatePropertiesSchema( propertiesSchemaUriPath, propertiesSchemaUri, context ); if (!schemaValid) { result = false; } } } } return result; } /** * Validates the properties schema referenced by propertiesSchemaUri * * @param path - The path for ValidationIssue instances * @param propertiesSchemaUri - The URI of the properties schema to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the schema was valid */ static async validatePropertiesSchema( path: string, propertiesSchemaUri: string, context: ValidationContext ): Promise { try { // Resolve and load the schema content const resourceResolver = context.getResourceResolver(); const schemaData = await resourceResolver.resolveData( propertiesSchemaUri ); if (!defined(schemaData)) { const message = `The properties schema URI '${propertiesSchemaUri}' could not be resolved`; const issue = IoValidationIssues.IO_ERROR(path, message); context.addIssue(issue); return false; } // Parse the schema JSON let schemaObject; try { const schemaString = schemaData.toString(); schemaObject = JSON.parse(schemaString); } catch (error) { const message = `Invalid JSON in properties schema: ${error}`; const issue = IoValidationIssues.JSON_PARSE_ERROR(path, message); context.addIssue(issue); return false; } // Validate the schema against geojsonproperties.schema.json structure return MaxarContentGeojsonValidator.validateGeojsonPropertiesSchema( path, schemaObject, context ); } catch (error) { const message = `Error validating properties schema: ${error}`; const issue = IoValidationIssues.IO_ERROR(path, message); context.addIssue(issue); return false; } } /** * Validates a GeoJSON properties schema object against the expected structure * * @param path - The path for ValidationIssue instances * @param schema - The schema object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the schema was valid */ static validateGeojsonPropertiesSchema( path: string, schema: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "schema", schema, context)) { return false; } let result = true; // Validate semantic property [required] const semanticPath = path + "/semantic"; if ( !BasicValidator.validateStringLength( semanticPath, "semantic", schema.semantic, 1, undefined, context ) ) { result = false; } // Validate geometry property [required] if ( !MaxarContentGeojsonValidator.validateGeometrySchema( path + "/geometry", schema.geometry, context ) ) { result = false; } // Validate properties array [required] if ( !MaxarContentGeojsonValidator.validatePropertiesArray( path + "/properties", schema.properties, context ) ) { result = false; } // Validate name property [optional] if (defined(schema.name)) { const namePath = path + "/name"; if ( !BasicValidator.validateStringLength( namePath, "name", schema.name, 1, undefined, context ) ) { result = false; } } return result; } /** * Validates a URI format * * @param path - The path for ValidationIssue instances * @param name - The name of the property * @param uri - The URI string to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the URI format was valid */ static validateUriFormat( path: string, name: string, uri: string, context: ValidationContext ): boolean { try { // Basic URI validation - check if it can be parsed as a URL // This handles both absolute URLs and relative URIs if (uri.includes("://")) { // Absolute URI - validate as URL new URL(uri); } else { // Relative URI - basic validation for invalid characters if (uri.includes(" ") || uri.includes("\n") || uri.includes("\t")) { throw new Error("Invalid characters in URI"); } } return true; } catch (error) { const message = `The property '${name}' must be a valid URI, but is '${uri}'`; const issue = JsonValidationIssues.STRING_VALUE_INVALID(path, message); context.addIssue(issue); return false; } } /** * Validates the geometry schema object * * @param path - The path for ValidationIssue instances * @param geometry - The geometry object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the geometry was valid */ static validateGeometrySchema( path: string, geometry: any, context: ValidationContext ): boolean { if (!BasicValidator.validateObject(path, "geometry", geometry, context)) { return false; } let result = true; // Validate required type property const type = geometry.type; const typePath = path + "/type"; const validTypes = [ "Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", "MultiPolygon", ]; if ( !BasicValidator.validateEnum(typePath, "type", type, validTypes, context) ) { result = false; } // Validate required dimensions property const dimensions = geometry.dimensions; const dimensionsPath = path + "/dimensions"; if ( !BasicValidator.validateIntegerRange( dimensionsPath, "dimensions", dimensions, 2, true, 3, true, context ) ) { result = false; } return result; } /** * Validates the properties array * * @param path - The path for ValidationIssue instances * @param properties - The properties array to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the properties array was valid */ static validatePropertiesArray( path: string, properties: any, context: ValidationContext ): boolean { if ( !BasicValidator.validateArray( path, "properties", properties, 1, undefined, "object", context ) ) { return false; } let result = true; // Validate each property object for (let i = 0; i < properties.length; i++) { const property = properties[i]; const propertyPath = path + "/" + i; if ( !MaxarContentGeojsonValidator.validatePropertySchema( propertyPath, property, context ) ) { result = false; } } // Validate that property IDs are unique if ( !MaxarContentGeojsonValidator.validateUniquePropertyIds( path, properties, context ) ) { result = false; } return result; } /** * Validates that property IDs are unique within the properties array * * @param path - The path for ValidationIssue instances * @param properties - The properties array to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether all property IDs are unique */ static validateUniquePropertyIds( path: string, properties: any, context: ValidationContext ): boolean { let result = true; const seenIds = new Set(); const duplicateIds = new Set(); // Check for duplicate IDs for (let i = 0; i < properties.length; i++) { const property = properties[i]; if (defined(property) && defined(property.id)) { const id = property.id; if (seenIds.has(id)) { duplicateIds.add(id); } else { seenIds.add(id); } } } // Report errors for each duplicate ID for (const duplicateId of duplicateIds) { const message = `Property ID '${duplicateId}' is not unique. All property IDs must be unique within the schema.`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); result = false; } return result; } /** * Validates a single property schema object * * @param path - The path for ValidationIssue instances * @param property - The property object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the property was valid */ static validatePropertySchema( path: string, property: any, context: ValidationContext ): boolean { if (!BasicValidator.validateObject(path, "property", property, context)) { return false; } let result = true; // Validate id property [required] const id = property.id; const idPath = path + "/id"; if ( !BasicValidator.validateStringLength( idPath, "id", id, 1, undefined, context ) ) { result = false; } // Validate type property [required] const type = property.type; const typePath = path + "/type"; const validTypes = ["Integer", "Float", "String", "Boolean", "Variant"]; if ( !BasicValidator.validateEnum(typePath, "type", type, validTypes, context) ) { result = false; } // Validate description properties [optional] if (defined(property.description)) { const descriptionPath = path + "/description"; if ( !BasicValidator.validateStringLength( descriptionPath, "description", property.description, 1, undefined, context ) ) { result = false; } } // Validate unit property [optional] if (defined(property.unit)) { const unitPath = path + "/unit"; if ( !BasicValidator.validateStringLength( unitPath, "unit", property.unit, 1, undefined, context ) ) { result = false; } } // Validate semantic property [optional] if (defined(property.semantic)) { const semanticPath = path + "/semantic"; if ( !BasicValidator.validateStringLength( semanticPath, "semantic", property.semantic, 1, undefined, context ) ) { result = false; } } // Validate required property [optional] if (defined(property.required)) { const requiredPath = path + "/required"; if ( !BasicValidator.validateBoolean( requiredPath, "required", property.required, context ) ) { result = false; } } // Validate that required properties do not have a default value if ( defined(property.required) && property.required === true && defined(property.default) ) { const message = "A required property cannot have a default value"; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); result = false; } // Note: Non-required properties are allowed to omit default values and will default to null // This is valid according to the MAXAR_content_geojson schema specification // Validate that default values match their property types if (defined(property.default)) { const defaultPath = path + "/default"; const defaultValue = property.default; if (type === "Variant") { const message = "Variant type properties cannot have default values"; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); result = false; } else if (type === "String") { if ( !BasicValidator.validateString( defaultPath, "default", defaultValue, context ) ) { result = false; } } else if (type === "Integer") { if ( !BasicValidator.validateInteger( defaultPath, "default", defaultValue, context ) ) { result = false; } } else if (type === "Float") { if ( !BasicValidator.validateNumber( defaultPath, "default", defaultValue, context ) ) { result = false; } } else if (type === "Boolean") { if ( !BasicValidator.validateBoolean( defaultPath, "default", defaultValue, context ) ) { result = false; } } } // Validate that min/max properties are only used with Integer and Float types if (defined(property.min) || defined(property.max)) { if (type !== "Integer" && type !== "Float") { const message = `Properties 'min' and 'max' can only be used with Integer and Float types, but property type is '${type}'`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); result = false; } } // Validate min/max properties (only for Integer and Float types) if (type === "Integer" || type === "Float") { if (defined(property.min)) { const minPath = path + "/min"; if ( !BasicValidator.validateNumber(minPath, "min", property.min, context) ) { result = false; } } if (defined(property.max)) { const maxPath = path + "/max"; if ( !BasicValidator.validateNumber(maxPath, "max", property.max, context) ) { result = false; } } // Validate that min <= max if both are defined if (defined(property.min) && defined(property.max)) { if (property.min > property.max) { const message = `The property min (${property.min}) must be <= max (${property.max})`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); result = false; } } } return result; } } ================================================ FILE: src/validation/extensions/MaxarExtentValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Cartographic } from "cesium"; import { Validator } from "../Validator"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { JsonValidationIssues } from "../../issues/JsonValidationIssues"; import { IoValidationIssues } from "../../issues/IoValidationIssue"; import { SemanticValidationIssues } from "../../issues/SemanticValidationIssues"; import { GeojsonValidator } from "../../tileFormats/GeojsonValidator"; /** * A class for validating MAXAR_extent extension objects. * * @internal */ export class MaxarExtentValidator implements Validator { /** * Epsilon value used for floating-point comparisons throughout the validator */ private static readonly EPSILON = 1e-10; /** * Performs the validation to determine whether the given tileset contains * a valid MAXAR_extent extension. * * @param path - The path for ValidationIssue instances * @param tileset - The tileset object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ async validateObject( path: string, tileset: any, context: ValidationContext ): Promise { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "tileset", tileset, context)) { return false; } let result = true; // If there is a MAXAR_extent extension, // perform the validation of the corresponding object const extensions = tileset.extensions; if (defined(extensions)) { const key = "MAXAR_extent"; const extension = extensions[key]; if (defined(extension)) { const extensionPath = path + "/extensions/" + key; const extensionValid = await MaxarExtentValidator.validateMaxarExtent( extensionPath, extension, tileset, context ); if (!extensionValid) { result = false; } } } return result; } /** * Validates the MAXAR_extent extension object * * @param path - The path for ValidationIssue instances * @param maxar_extent - The MAXAR_extent object to validate * @param tileset - The tileset object containing the root tile bounding volume * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ private static async validateMaxarExtent( path: string, maxar_extent: any, tileset: any, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "MAXAR_extent", maxar_extent, context ) ) { return false; } let result = true; // Validate the uri property (required) const uri = maxar_extent.uri; const uriPath = path + "/uri"; if (!BasicValidator.validateString(uriPath, "uri", uri, context)) { result = false; } else { // Validate that the URI is not empty if (uri.trim().length === 0) { const message = "The 'uri' property must not be empty"; const issue = JsonValidationIssues.STRING_VALUE_INVALID( uriPath, message ); context.addIssue(issue); result = false; } else { // Validate that the URI is resolvable and contains valid GeoJSON const uriValid = await MaxarExtentValidator.validateUriContent( uriPath, uri, tileset, context ); if (!uriValid) { result = false; } } } return result; } /** * Validates that the URI is resolvable and contains valid GeoJSON content * that is spatially contained within the root tile's bounding volume * * @param path - The path for ValidationIssue instances * @param uri - The URI to validate * @param tileset - The tileset object containing the root tile bounding volume * @param context - The ValidationContext that any issues will be added to * @returns Whether the URI content was valid */ private static async validateUriContent( path: string, uri: string, tileset: any, context: ValidationContext ): Promise { // Attempt to resolve the URI const resourceResolver = context.getResourceResolver(); const uriData = await resourceResolver.resolveData(uri); if (!defined(uriData)) { const message = `The URI '${uri}' could not be resolved`; const issue = IoValidationIssues.IO_ERROR(path, message); context.addIssue(issue); return false; } // Parse the JSON once for both GeoJSON validation and geometric validation let geojsonObject: any; try { const jsonString = uriData.toString("utf-8"); geojsonObject = JSON.parse(jsonString); } catch (error) { const message = `Invalid JSON in GeoJSON file: ${error}`; const issue = IoValidationIssues.JSON_PARSE_ERROR(path, message); context.addIssue(issue); return false; } // Validate the parsed GeoJSON object using the static method const geojsonValid = await GeojsonValidator.validateGeojsonObject( uri, geojsonObject, context ); if (!geojsonValid) { return false; } // Validate that GeoJSON contains only Polygon or MultiPolygon shapes const geometryValid = MaxarExtentValidator.validateGeometryTypes( path, geojsonObject, context ); if (!geometryValid) { return false; } // Perform all geometric validations and accumulate results // This allows us to report multiple issues instead of failing on the first one let allValidationsValid = true; // Validate minimum coordinate count and self-intersection const extentValid = MaxarExtentValidator.validateExtentRequirements( path, geojsonObject, context ); if (!extentValid) { allValidationsValid = false; } // Validate spatial containment within root tile bounding volume const spatialValid = await MaxarExtentValidator.validateSpatialContainment( path, geojsonObject, tileset, context ); if (!spatialValid) { allValidationsValid = false; } return allValidationsValid; } /** * Validates that all coordinates in the GeoJSON are spatially contained * within the root tile's bounding volume * * @param path - The path for ValidationIssue instances * @param geojsonObject - The parsed GeoJSON object * @param tileset - The tileset object containing the root tile bounding volume * @param context - The ValidationContext that any issues will be added to * @returns Whether all coordinates are contained within the bounding volume */ private static async validateSpatialContainment( path: string, geojsonObject: any, tileset: any, context: ValidationContext ): Promise { // Get the root tile's bounding volume const rootTile = tileset.root; if (!defined(rootTile) || !defined(rootTile.boundingVolume)) { // If no root tile or bounding volume, skip spatial validation return true; } const boundingVolume = rootTile.boundingVolume; // Extract all coordinates from the GeoJSON const coordinates = MaxarExtentValidator.extractAllCoordinates(geojsonObject); // Check each coordinate for containment for (let i = 0; i < coordinates.length; i++) { const coord = coordinates[i]; if (!MaxarExtentValidator.isCoordinateContained(coord, boundingVolume)) { const message = `GeoJSON coordinate [${coord.join( ", " )}] is not contained within the root tile's bounding volume`; const issue = SemanticValidationIssues.BOUNDING_VOLUMES_INCONSISTENT( path, message ); context.addIssue(issue); return false; } } return true; } /** * Validates that the GeoJSON contains only Polygon or MultiPolygon geometries * * @param path - The path for ValidationIssue instances * @param geojsonObject - The parsed GeoJSON object * @param context - The ValidationContext that any issues will be added to * @returns Whether all geometries are Polygon or MultiPolygon */ private static validateGeometryTypes( path: string, geojsonObject: any, context: ValidationContext ): boolean { const invalidGeometries: string[] = []; function checkGeometry(geometry: any): void { if (!geometry || !geometry.type) { return; } const type = geometry.type; if (type !== "Polygon" && type !== "MultiPolygon") { if (type === "GeometryCollection") { // Recursively check geometries in collection if (geometry.geometries) { for (const subGeometry of geometry.geometries) { checkGeometry(subGeometry); } } } else { // Invalid geometry type invalidGeometries.push(type); } } } // Handle different GeoJSON types if (geojsonObject.type === "Feature") { checkGeometry(geojsonObject.geometry); } else if (geojsonObject.type === "FeatureCollection") { for (const feature of geojsonObject.features || []) { checkGeometry(feature.geometry); } } else { // Direct geometry object checkGeometry(geojsonObject); } // Report any invalid geometry types found if (invalidGeometries.length > 0) { const uniqueTypes = [...new Set(invalidGeometries)]; const message = `MAXAR_extent GeoJSON must contain only Polygon or MultiPolygon geometries, but found: ${uniqueTypes.join( ", " )}`; const issue = SemanticValidationIssues.INVALID_GEOMETRY_TYPE( path, message ); context.addIssue(issue); return false; } return true; } /** * Validates extent-specific requirements: minimum coordinate count and self-intersection * * @param path - The path for ValidationIssue instances * @param geojsonObject - The parsed GeoJSON object * @param context - The ValidationContext that any issues will be added to * @returns Whether the extent requirements are met */ private static validateExtentRequirements( path: string, geojsonObject: any, context: ValidationContext ): boolean { let result = true; function validateGeometry(geometry: any): boolean { if (!geometry || !geometry.type || !geometry.coordinates) { return true; // Skip invalid geometries (already handled by GeoJSON validator) } const type = geometry.type; if (type === "Polygon") { return MaxarExtentValidator.validatePolygonExtent( geometry.coordinates, path, context ); } else if (type === "MultiPolygon") { for (let i = 0; i < geometry.coordinates.length; i++) { if ( !MaxarExtentValidator.validatePolygonExtent( geometry.coordinates[i], path, context ) ) { return false; } } return true; } else if (type === "GeometryCollection") { if (geometry.geometries) { for (const subGeometry of geometry.geometries) { if (!validateGeometry(subGeometry)) { return false; } } } return true; } return true; } // Handle different GeoJSON types if (geojsonObject.type === "Feature") { result = validateGeometry(geojsonObject.geometry); } else if (geojsonObject.type === "FeatureCollection") { for (const feature of geojsonObject.features || []) { if (!validateGeometry(feature.geometry)) { result = false; break; } } } else { // Direct geometry object result = validateGeometry(geojsonObject); } return result; } /** * Validates a polygon's coordinates for extent requirements * * @param polygonCoords - The polygon coordinates array * @param path - The path for ValidationIssue instances * @param context - The ValidationContext that any issues will be added to * @returns Whether the polygon meets extent requirements */ private static validatePolygonExtent( polygonCoords: number[][][], path: string, context: ValidationContext ): boolean { let result = true; // Validate each ring (exterior and holes) for (let ringIndex = 0; ringIndex < polygonCoords.length; ringIndex++) { const ring = polygonCoords[ringIndex]; // Check minimum coordinate count (at least 3 unique coordinates) const uniqueCoords = MaxarExtentValidator.getUniqueCoordinates(ring); if (uniqueCoords.length < 3) { const message = `Extent polygon ring must have at least 3 unique coordinates, but has ${uniqueCoords.length}`; const issue = SemanticValidationIssues.INVALID_GEOMETRY_SIZE( path, message ); context.addIssue(issue); result = false; } // Check for self-intersection with debug details const intersection = MaxarExtentValidator.findRingSelfIntersection(ring); if (intersection) { const { e1s, e1e, e2s, e2e, point } = intersection; // Try to identify if the intersection lies exactly on an existing vertex const vertexIndex = point ? MaxarExtentValidator.findMatchingVertexIndex(ring, point) : -1; const atVertex = vertexIndex !== -1; const coordStr = point ? `[${point[0]}, ${point[1]}${ point.length > 2 ? ", " + point[2] : "" }]` : "unknown"; const message = atVertex ? `Extent polygon ring ${ringIndex} is self-intersecting, which is forbidden. Intersection at vertex ${vertexIndex} ${coordStr}` : `Extent polygon ring ${ringIndex} is self-intersecting, which is forbidden. Intersects between edges (${e1s}-${e1e}) and (${e2s}-${e2e}) near ${coordStr}`; const issue = SemanticValidationIssues.INVALID_GEOMETRY_STRUCTURE( path, message ); context.addIssue(issue); result = false; } } return result; } /** * Gets unique coordinates from a ring, excluding the closing coordinate * Uses epsilon-based comparison to handle floating point precision issues * * @param ring - Array of coordinate pairs [longitude, latitude] * @returns Array of unique coordinates with duplicates removed */ private static getUniqueCoordinates(ring: number[][]): number[][] { if (ring.length === 0) return []; const unique: number[][] = []; // Process all coordinates except the last one (which should close the ring) const coordsToCheck = ring.length > 0 && MaxarExtentValidator.coordinatesEqual( ring[0], ring[ring.length - 1], MaxarExtentValidator.EPSILON ) ? ring.slice(0, -1) : ring; for (const coord of coordsToCheck) { // Check if this coordinate is already in the unique list const isDuplicate = unique.some((existingCoord) => MaxarExtentValidator.coordinatesEqual( coord, existingCoord, MaxarExtentValidator.EPSILON ) ); if (!isDuplicate) { unique.push(coord); } } return unique; } /** * Compares two coordinates for equality within epsilon tolerance * * @param coord1 - First coordinate [longitude, latitude] * @param coord2 - Second coordinate [longitude, latitude] * @param epsilon - Tolerance for floating point comparison * @returns Whether the coordinates are equal within tolerance */ private static coordinatesEqual( coord1: number[], coord2: number[], epsilon: number ): boolean { if (coord1.length !== coord2.length) return false; for (let i = 0; i < coord1.length; i++) { if (Math.abs(coord1[i] - coord2[i]) > epsilon) { return false; } } return true; } /** * Finds the first pair of intersecting non-adjacent edges in a ring and the intersection point * Returns indices of the edge start/end vertices and the intersection point (if computable) */ private static findRingSelfIntersection(ring: number[][]): { e1s: number; e1e: number; e2s: number; e2e: number; point: number[] | null; } | null { if (ring.length < 4) return null; for (let i = 0; i < ring.length - 1; i++) { const a1 = ring[i]; const a2 = ring[i + 1]; for (let j = i + 2; j < ring.length - 1; j++) { if (j === ring.length - 2 && i === 0) continue; // Skip adjacent/closing edges const b1 = ring[j]; const b2 = ring[j + 1]; const point = MaxarExtentValidator.segmentsIntersectionFinite( a1, a2, b1, b2 ); if (point) { return { e1s: i, e1e: i + 1, e2s: j, e2e: j + 1, point }; } } } return null; } /** * Find index of a vertex in ring that matches the given point within epsilon, or -1 */ private static findMatchingVertexIndex( ring: number[][], point: number[] ): number { for (let i = 0; i < ring.length; i++) { if ( MaxarExtentValidator.coordinatesEqual( ring[i], point, MaxarExtentValidator.EPSILON ) ) { return i; } } return -1; } /** * Robust finite-segment intersection check. * Returns an intersection point on the finite segments (with epsilon tolerance), * or a representative point for collinear overlaps, or null if segments don't intersect. */ private static segmentsIntersectionFinite( p1: number[], p2: number[], p3: number[], p4: number[] ): number[] | null { const eps = MaxarExtentValidator.EPSILON; const r = [p2[0] - p1[0], p2[1] - p1[1]]; const s = [p4[0] - p3[0], p4[1] - p3[1]]; const cross = (a: number[], b: number[]) => a[0] * b[1] - a[1] * b[0]; const denom = cross(r, s); const qmp = [p3[0] - p1[0], p3[1] - p1[1]]; const crossQmpR = cross(qmp, r); if (Math.abs(denom) < eps) { // Parallel: either collinear or disjoint if (Math.abs(crossQmpR) >= eps) { return null; // Parallel, non-collinear } // Collinear: check overlap in 1D along r const rr = r[0] * r[0] + r[1] * r[1]; if (rr < eps) { return null; // Degenerate segment: |p2 - p1| ≈ 0 (within EPSILON). Intersection parameters are ill-defined; ignore as non-intersecting. } const dot = (a: number[], b: number[]) => a[0] * b[0] + a[1] * b[1]; const t0 = dot([p3[0] - p1[0], p3[1] - p1[1]], r) / rr; const t1 = dot([p4[0] - p1[0], p4[1] - p1[1]], r) / rr; const tmin = Math.min(t0, t1); const tmax = Math.max(t0, t1); const overlapStart = Math.max(0 - eps, tmin); const overlapEnd = Math.min(1 + eps, tmax); if (overlapStart <= overlapEnd) { // Pick a representative point within the overlap interval, clamped to [0,1] const t = Math.min(1, Math.max(0, (overlapStart + overlapEnd) / 2)); return [p1[0] + t * r[0], p1[1] + t * r[1]]; } return null; } // Proper intersection: compute parameters along each segment const t = cross(qmp, s) / denom; // along p1->p2 const u = cross(qmp, r) / denom; // along p3->p4 const inside01 = (x: number) => x >= 0 && x <= 1; const nearEndpoint = (x: number) => Math.abs(x) <= eps || Math.abs(1 - x) <= eps; if ((inside01(t) || nearEndpoint(t)) && (inside01(u) || nearEndpoint(u))) { return [p1[0] + t * r[0], p1[1] + t * r[1]]; } return null; } /** * Extracts all coordinate arrays from a GeoJSON object * * @param geojsonObject - The GeoJSON object to extract coordinates from * @returns Array of coordinate arrays [longitude, latitude, optional height] */ private static extractAllCoordinates(geojsonObject: any): number[][] { const coordinates: number[][] = []; function extractFromGeometry(geometry: any): void { if (!geometry || !geometry.type || !geometry.coordinates) { return; } // Only extract coordinates from Polygon and MultiPolygon geometries // since those are the only valid types for MAXAR_extent switch (geometry.type) { case "Polygon": for (const ring of geometry.coordinates) { for (const coord of ring) { coordinates.push(coord); } } break; case "MultiPolygon": for (const polygon of geometry.coordinates) { for (const ring of polygon) { for (const coord of ring) { coordinates.push(coord); } } } break; case "GeometryCollection": if (geometry.geometries) { for (const subGeometry of geometry.geometries) { extractFromGeometry(subGeometry); } } break; // Skip other geometry types (Point, LineString, etc.) as they are invalid for MAXAR_extent // and should have been caught by validateGeometryTypes } } // Handle different GeoJSON types if (geojsonObject.type === "Feature") { extractFromGeometry(geojsonObject.geometry); } else if (geojsonObject.type === "FeatureCollection") { for (const feature of geojsonObject.features || []) { extractFromGeometry(feature.geometry); } } else { // Direct geometry object extractFromGeometry(geojsonObject); } return coordinates; } /** * Checks if a coordinate is contained within a bounding volume * * @param coordinate - The coordinate array [longitude, latitude, optional height] * @param boundingVolume - The bounding volume to check against * @returns Whether the coordinate is contained within the bounding volume */ private static isCoordinateContained( coordinate: number[], boundingVolume: any ): boolean { const longitude = coordinate[0]; const latitude = coordinate[1]; const height = coordinate.length > 2 ? coordinate[2] : 0.0; if (defined(boundingVolume.region)) { // For region, work directly with degrees/radians const cartographic = Cartographic.fromDegrees( longitude, latitude, height ); return MaxarExtentValidator.isPointInRegion( cartographic, boundingVolume.region ); } else if (defined(boundingVolume.box)) { // TODO: Box bounding volume spatial validation requires complex coordinate system conversion // For now, skip spatial validation for box bounding volumes console.warn( "MAXAR_extent: Spatial validation not yet implemented for box bounding volumes - skipping containment check" ); return true; } else if (defined(boundingVolume.sphere)) { // TODO: Sphere bounding volume spatial validation requires complex coordinate system conversion // For now, skip spatial validation for sphere bounding volumes console.warn( "MAXAR_extent: Spatial validation not yet implemented for sphere bounding volumes - skipping containment check" ); return true; } // Unknown bounding volume type, assume contained console.warn( "MAXAR_extent: Unknown bounding volume type - skipping containment check" ); return true; } /** * Checks if a point is within a region bounding volume * * @param cartographic - The cartographic position to check (longitude/latitude in radians, height in meters) * @param region - The region array [west, south, east, north, minHeight, maxHeight] in radians and meters * @returns Whether the point is contained within the region bounds */ private static isPointInRegion( cartographic: Cartographic, region: number[] ): boolean { // Validate region array has exactly 6 elements if (!region || region.length !== 6) { return false; } const [west, south, east, north, minHeight, maxHeight] = region; return ( cartographic.longitude >= west && cartographic.longitude <= east && cartographic.latitude >= south && cartographic.latitude <= north && cartographic.height >= minHeight && cartographic.height <= maxHeight ); } } ================================================ FILE: src/validation/extensions/MaxarGridValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Validator } from "../Validator"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { StructureValidator } from "../StructureValidator"; import { JsonValidationIssues } from "../../issues/JsonValidationIssues"; import { MaxarValidatorCommon } from "./maxar/MaxarValidatorCommon"; /** * A class for the validation of `MAXAR_grid` extension objects * * @internal */ export class MaxarGridValidator implements Validator { /** * Performs the validation of a `Tileset` object that * contains a `MAXAR_grid` extension object. * * @param path - The path for `ValidationIssue` instances * @param tileset - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ async validateObject( path: string, tileset: any, context: ValidationContext ): Promise { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "tileset", tileset, context)) { return false; } let result = true; // If there is a MAXAR_grid extension, // perform the validation of the corresponding object const extensions = tileset.extensions; if (defined(extensions)) { const key = "MAXAR_grid"; const extension = extensions[key]; const extensionPath = path + "/" + key; if ( !MaxarGridValidator.validateMaxarGrid(extensionPath, extension, context) ) { result = false; } } return result; } /** * Validates the MAXAR_grid extension object at either tileset or tile level * * @param path - The path for ValidationIssue instances * @param maxar_grid - The MAXAR_grid object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ static validateMaxarGrid( path: string, maxar_grid: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, "MAXAR_grid", maxar_grid, context) ) { return false; } let result = true; // Determine if this is a tileset-level or tile-level extension // Tileset-level extensions have a 'type' property // Tile-level extensions have 'boundingBox', 'level', and 'index' properties const hasType = defined(maxar_grid.type); const hasTileProperties = defined(maxar_grid.boundingBox) || defined(maxar_grid.level) || defined(maxar_grid.index); if (hasType) { // This is a tileset-level MAXAR_grid extension if ( !MaxarGridValidator.validateTilesetMaxarGrid(path, maxar_grid, context) ) { result = false; } } else if (hasTileProperties) { // This is a tile-level MAXAR_grid extension if ( !MaxarGridValidator.validateTileMaxarGrid(path, maxar_grid, context) ) { result = false; } } else { // Neither tileset nor tile properties found - this is an error const message = "MAXAR_grid extension must have either tileset-level properties (type, center, size, srs) or tile-level properties (boundingBox, level, index)"; const issue = JsonValidationIssues.PROPERTY_MISSING(path, message); context.addIssue(issue); result = false; } return result; } /** * Validates the MAXAR_grid extension object at the tileset level * * @param path - The path for ValidationIssue instances * @param maxar_grid - The MAXAR_grid object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ static validateTilesetMaxarGrid( path: string, maxar_grid: any, context: ValidationContext ): boolean { let result = true; // Validate the type property (required) const type = maxar_grid.type; const typePath = path + "/type"; if (!BasicValidator.validateString(typePath, "type", type, context)) { return false; } // Validate type enum values based on schema const validTypes = ["quad", "s2", "geod"]; if ( !BasicValidator.validateEnum(typePath, "type", type, validTypes, context) ) { result = false; return result; // Can't continue with invalid type } // Validate properties based on grid type if (type === "quad") { if (!MaxarGridValidator.validateQuadGrid(path, maxar_grid, context)) { result = false; } } else if (type === "s2" || type === "geod") { if (!MaxarGridValidator.validateS2OrGeodGrid(path, maxar_grid, context)) { result = false; } } return result; } /** * Validates a quad grid type MAXAR_grid extension * Required properties: type, center, size, srs * * @param path - The path for ValidationIssue instances * @param maxar_grid - The MAXAR_grid object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ static validateQuadGrid( path: string, maxar_grid: any, context: ValidationContext ): boolean { let result = true; // Validate center property (required for quad type) const center = maxar_grid.center; const centerPath = path + "/center"; if ( !BasicValidator.validateArray( centerPath, "center", center, 2, 2, "number", context ) ) { result = false; } // Validate size property (required for quad type) const size = maxar_grid.size; const sizePath = path + "/size"; if ( !BasicValidator.validateArray( sizePath, "size", size, 2, 2, "number", context ) ) { result = false; } // Validate srs property (required for quad type) const srs = maxar_grid.srs; const srsPath = path + "/srs"; if (!BasicValidator.validateObject(srsPath, "srs", srs, context)) { result = false; } else { if (!MaxarValidatorCommon.validateSrs(srsPath, srs, context)) { result = false; } } return result; } /** * Validates an S2 or geodetic grid type MAXAR_grid extension * For s2/geod types, center, size, and srs properties must NOT be present * * @param path - The path for ValidationIssue instances * @param maxar_grid - The MAXAR_grid object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ static validateS2OrGeodGrid( path: string, maxar_grid: any, context: ValidationContext ): boolean { // For s2/geod types, center, size, and srs properties must NOT be present const disallowedProperties = ["center", "size", "srs"]; return StructureValidator.validateDisallowedProperties( path, "MAXAR_grid with type=s2 or type=geod", maxar_grid, disallowedProperties, context ); } /** * Validates the MAXAR_grid extension object at the tile level * Required properties: boundingBox, level, index * Optional properties: metersPerPixel, face * * @param path - The path for ValidationIssue instances * @param maxar_grid - The MAXAR_grid object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ static validateTileMaxarGrid( path: string, maxar_grid: any, context: ValidationContext ): boolean { let result = true; // Validate boundingBox property (required) const boundingBox = maxar_grid.boundingBox; const boundingBoxPath = path + "/boundingBox"; if ( !BasicValidator.validateArray( boundingBoxPath, "boundingBox", boundingBox, 6, 6, "number", context ) ) { result = false; } else { // Semantic validation: xmin <= xmax, ymin <= ymax, zmin <= zmax // boundingBox format: [xmin, ymin, xmax, ymax, zmin, zmax] const [xmin, ymin, xmax, ymax, zmin, zmax] = boundingBox; if (xmin > xmax) { const message = `The boundingBox xmin (${xmin}) must be <= xmax (${xmax})`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE( boundingBoxPath, message ); context.addIssue(issue); result = false; } if (ymin > ymax) { const message = `The boundingBox ymin (${ymin}) must be <= ymax (${ymax})`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE( boundingBoxPath, message ); context.addIssue(issue); result = false; } if (zmin > zmax) { const message = `The boundingBox zmin (${zmin}) must be <= zmax (${zmax})`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE( boundingBoxPath, message ); context.addIssue(issue); result = false; } } // Validate level property (required) const level = maxar_grid.level; const levelPath = path + "/level"; if ( !BasicValidator.validateIntegerRange( levelPath, "level", level, 0, true, undefined, false, context ) ) { result = false; } // Validate index property (required) const index = maxar_grid.index; const indexPath = path + "/index"; if ( !BasicValidator.validateArray( indexPath, "index", index, 2, 2, "number", context ) ) { result = false; } else { // Validate that index values are integers >= 0 for (let i = 0; i < index.length; i++) { const indexValue = index[i]; const indexValuePath = indexPath + "/" + i; if ( !BasicValidator.validateIntegerRange( indexValuePath, `index[${i}]`, indexValue, 0, true, undefined, false, context ) ) { result = false; } } } // Validate optional properties if (defined(maxar_grid.metersPerPixel)) { const metersPerPixel = maxar_grid.metersPerPixel; const metersPerPixelPath = path + "/metersPerPixel"; if ( !BasicValidator.validateNumberRange( metersPerPixelPath, "metersPerPixel", metersPerPixel, 0, true, undefined, false, context ) ) { result = false; } } if (defined(maxar_grid.face)) { const face = maxar_grid.face; const facePath = path + "/face"; if ( !BasicValidator.validateIntegerRange( facePath, "face", face, 0, true, 5, true, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/extensions/NgaGpmValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Validator } from "../Validator"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { StringValidator } from "../StringValidator"; import { RootPropertyValidator } from "../RootPropertyValidator"; import { ExtendedObjectsValidators } from "../ExtendedObjectsValidators"; import { JsonValidationIssues } from "../../issues/JsonValidationIssues"; import { StructureValidationIssues } from "../../issues/StructureValidationIssues"; import { NgaGpmValidatorCommon } from "./gpm/NgaGpmValidatorCommon"; import { NgaGpmValidationIssues } from "./gpm/NgaGpmValidationIssues"; import { StructureValidator } from "../StructureValidator"; /** * EPSG codes for WGS84 CRS realizations, as defined in the * epsgEcef structure of the schema. */ enum EpsgEcefCodes { G2139 = 9753, G1762 = 7664, G1674 = 7662, G1150 = 7660, G873 = 7658, G730 = 7656, Generic = 4978, } /** * The epsilon for the validation of the length of unit vectors. * * When the length (magnitude) of a unit vector deviates by more * than this epsilon from 1.0, then this is considered to be * a validation error. */ const UNIT_VECTOR_LENGTH_EPSILON = 0.00001; /** * The epsilon for the validation of orthogonality of unit vectors. * * When the absolute dot product between two unit vectors * is greater than this epsilon, then this is considered * to be a validation error. */ const ORTHOGONAL_VECTORS_DOT_PRODUCT_EPSILON = 0.01; /** * A class for the validation of `NGA_gpm` extension objects * * @internal */ export class NgaGpmValidator implements Validator { /** * Performs the validation of a `Tileset` object that may * contain a `NGA_gpm` extension object. * * @param path - The path for `ValidationIssue` instances * @param tileset - The tileset that may contain the extension object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ async validateObject( path: string, tileset: any, context: ValidationContext ): Promise { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "tileset", tileset, context)) { return false; } let result = true; // If there is a NGA_gpm extension, perform the // validation of the corresponding object const extensions = tileset.extensions; if (defined(extensions)) { const ngaGpm = extensions["NGA_gpm"]; const ngaGpmPath = path + "/NGA_gpm"; // If the extension object is not an object, then a validation // issue was already added when validating the extension objects // of the tileset, when it was validated to be a root property. if (defined(ngaGpm) && typeof ngaGpm === "object") { const numContentsInRootNode = NgaGpmValidator.computeNumContentsInRootNode(tileset); if ( !NgaGpmValidator.validateNgaGpm( ngaGpmPath, "NGA_gpm", ngaGpm, numContentsInRootNode, context ) ) { result = false; } } } return result; } /** * Returns the number of contents in the root node of the given * tileset. The given object is not defined, does not have a * root, or the root does not have contents, then 0 is returned. * * @param tileset - The tileset * @returns The number of contents in the root node */ private static computeNumContentsInRootNode(tileset: any) { if (!defined(tileset)) { return 0; } const root = tileset.root; if (!defined(root)) { return 0; } const content = root.content; if (defined(content)) { return 1; } const contents = root.contents; if (Array.isArray(contents)) { return contents.length; } return 0; } /** * Performs the validation to ensure that the given object is a * valid `NGA_gpm` object. * * @param path - The path for `ValidationIssue` instances * @param name - The name of the object * @param object - The object to validate * @param numContentsInRootNode - The number of contents in the root * node of the tileset. This is required for validating the 'contentIndex' * if the 'anchorPointMetadata' * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateNgaGpm( path: string, name: string, object: any, numContentsInRootNode: number, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, object, context)) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty(path, name, object, context) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject(path, object, context) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(object)) { return result; } // Validate the masterRecord const masterRecord = object.masterRecord; const masterRecordPath = path + "/masterRecord"; if ( !NgaGpmValidator.validateMasterRecord( masterRecordPath, "masterRecord", masterRecord, context ) ) { result = false; } // Validate the unmodeledErrorRecord const unmodeledErrorRecord = object.unmodeledErrorRecord; const unmodeledErrorRecordPath = path + "/unmodeledErrorRecord"; if ( !NgaGpmValidator.validateUnmodeledError( unmodeledErrorRecordPath, "unmodeledErrorRecord", unmodeledErrorRecord, context ) ) { result = false; } // Validate the interpolationParams const interpolationParams = object.interpolationParams; const interpolationParamsPath = path + "/interpolationParams"; if ( !NgaGpmValidator.validateInterpolationParams( interpolationParamsPath, "interpolationParams", interpolationParams, context ) ) { result = false; } // Validate the interTileCorrelationGroups const interTileCorrelationGroups = object.interTileCorrelationGroups; const interTileCorrelationGroupsPath = path + "/interTileCorrelationGroups"; if ( !NgaGpmValidatorCommon.validateCorrelationGroups( interTileCorrelationGroupsPath, "interTileCorrelationGroups", interTileCorrelationGroups, context ) ) { result = false; } // Validate the threeDimConformalParams const threeDimConformalParams = object.threeDimConformalParams; const threeDimConformalParamsPath = path + "/threeDimConformalParams"; if (defined(threeDimConformalParams)) { if ( !NgaGpmValidator.validateThreeDimensionalConformal( threeDimConformalParamsPath, "threeDimConformalParams", threeDimConformalParams, context ) ) { result = false; } } // Validate the ppeManifest const ppeManifest = object.ppeManifest; const ppeManifestPath = path + "/ppeManifest"; if (defined(ppeManifest)) { if ( !NgaGpmValidator.validatePpeManifest( ppeManifestPath, "ppeManifest", ppeManifest, context ) ) { result = false; } } // Validate the anchorPointMetadata const anchorPointMetadata = object.anchorPointMetadata; const anchorPointMetadataPath = path + "/anchorPointMetadata"; if (defined(anchorPointMetadata)) { if ( !NgaGpmValidator.validateAnchorPointMetadata( anchorPointMetadataPath, "anchorPointMetadata", anchorPointMetadata, numContentsInRootNode, context ) ) { result = false; } } return result; } /** * Validate the given masterRecord * * @param path - The path for validation issues * @param name - The name of the object * @param masterRecord - The masterRecord * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateMasterRecord( path: string, name: string, masterRecord: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, masterRecord, context)) { return false; } let result = true; // Validate the version const version = masterRecord.version; const versionPath = path + "/version"; if ( !BasicValidator.validateString(versionPath, "version", version, context) ) { result = false; } // Validate the implementation const implementation = masterRecord.implementation; const implementationPath = path + "/implementation"; if ( !BasicValidator.validateString( implementationPath, "implementation", implementation, context ) ) { result = false; } // Validate the modelCoordSystem const modelCoordSystem = masterRecord.modelCoordSystem; const modelCoordSystemPath = path + "/modelCoordSystem"; if ( !NgaGpmValidator.validateModelCoordSystem( modelCoordSystemPath, "modelCoordSystem", modelCoordSystem, context ) ) { result = false; } // Validate the idInformation const idInformation = masterRecord.idInformation; const idInformationPath = path + "/idInformation"; if ( !NgaGpmValidator.validateIdInformation( idInformationPath, "idInformation", idInformation, context ) ) { result = false; } // Validate the datasetExtentInformation const datasetExtentInformation = masterRecord.datasetExtentInformation; const datasetExtentInformationPath = path + "/datasetExtentInformation"; if (defined(datasetExtentInformation)) { if ( !NgaGpmValidator.validateExtentInformation( datasetExtentInformationPath, "datasetExtentInformation", datasetExtentInformation, context ) ) { result = false; } } // Validate the collectionRecordList const collectionRecordList = masterRecord.collectionRecordList; const collectionRecordListPath = path + "/collectionRecordList"; if (defined(collectionRecordList)) { if ( !NgaGpmValidator.validateCollectionRecordList( collectionRecordListPath, "collectionRecordList", collectionRecordList, context ) ) { result = false; } } return result; } /** * Validate the given modelCoordSystem * * @param path - The path for validation issues * @param name - The name of the object * @param modelCoordSystem - The modelCoordSystem * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateModelCoordSystem( path: string, name: string, modelCoordSystem: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, modelCoordSystem, context)) { return false; } // Validate the mcsType const mcsType = modelCoordSystem.mcsType; const mcsTypePath = path + "/mcsType"; // The mcsType MUST be one of these valid values const mcsTypeValues = ["ECEF", "LSR", "UTM"]; if ( !BasicValidator.validateEnum( mcsTypePath, "mcsType", mcsType, mcsTypeValues, context ) ) { // The remaining validation depends on the mcsType, // so bail out early when it is invalid return false; } // The actual structure of the object is defined // with a "oneOf [ nearly disjoint things ]", depending // on the mcsType. if (mcsType === "ECEF") { return NgaGpmValidator.validateModelCoordSystemEcef( path, modelCoordSystem, context ); } if (mcsType === "UTM") { return NgaGpmValidator.validateModelCoordSystemUtm( path, modelCoordSystem, context ); } return NgaGpmValidator.validateModelCoordSystemLsr( path, modelCoordSystem, context ); } /** * Validate the given modelCoordSystem, assuming that it * did contain the `mcsType === ECEF` * * @param path - The path for validation issues * @param name - The name of the object * @param modelCoordSystem - The modelCoordSystem * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateModelCoordSystemEcef( path: string, modelCoordSystem: any, context: ValidationContext ): boolean { // Value was already validated to be an object // in validateModelCoordSystem let result = true; // Validate the crsEcef const crsEcef = modelCoordSystem.crsEcef; const crsEcefPath = path + "/crsEcef"; if ( !NgaGpmValidator.validateEpsgEcef( crsEcefPath, "crsEcef", crsEcef, context ) ) { result = false; } // Validate that disallowed properties are not present const disallowedProperties = [ "crsHorizontalUtm", "crsVertical", "origin", "axisUnitVectors", ]; if ( !StructureValidator.validateDisallowedProperties( path, "modelCoordSystem with mcsType=ECEF", modelCoordSystem, disallowedProperties, context ) ) { result = false; } return result; } /** * Validate the given epsgEcef * * @param path - The path for validation issues * @param name - The name of the object * @param epsgEcef - The epsgEcef * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateEpsgEcef( path: string, name: string, epsgEcef: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, epsgEcef, context)) { return false; } // Validate the id const id = epsgEcef.id; const idPath = path + "/id"; // The id MUST be one of these valid values const idValues = [ EpsgEcefCodes.G2139, EpsgEcefCodes.G1762, EpsgEcefCodes.G1674, EpsgEcefCodes.G1150, EpsgEcefCodes.G873, EpsgEcefCodes.G730, EpsgEcefCodes.Generic, ]; if (!BasicValidator.validateEnum(idPath, "id", id, idValues, context)) { return false; } return true; } /** * Validate the given modelCoordSystem, assuming that it * did contain the `mcsType === UTM` * * @param path - The path for validation issues * @param name - The name of the object * @param modelCoordSystem - The modelCoordSystem * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateModelCoordSystemUtm( path: string, modelCoordSystem: any, context: ValidationContext ): boolean { // Value was already validated to be an object // in validateModelCoordSystem let result = true; // Validate the crsHorizontalUtm const crsHorizontalUtm = modelCoordSystem.crsHorizontalUtm; const crsHorizontalUtmPath = path + "/crsHorizontalUtm"; if ( !NgaGpmValidator.validateEpsgUtm( crsHorizontalUtmPath, "crsHorizontalUtm", crsHorizontalUtm, context ) ) { result = false; } // Validate the crsVertical const crsVertical = modelCoordSystem.crsVertical; const crsVerticalPath = path + "/crsVertical"; if ( !NgaGpmValidator.validateReferenceSystem( crsVerticalPath, "crsVertical", crsVertical, context ) ) { result = false; } // Validate that disallowed properties are not present const disallowedProperties = ["crsEcef", "origin", "axisUnitVectors"]; if ( !StructureValidator.validateDisallowedProperties( path, "modelCoordSystem with mcsType=UTM", modelCoordSystem, disallowedProperties, context ) ) { result = false; } return result; } /** * Validate the given epsgUtm * * @param path - The path for validation issues * @param name - The name of the object * @param epsgUtm - The epsgUtm * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateEpsgUtm( path: string, name: string, epsgUtm: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, epsgUtm, context)) { return false; } // Validate the id const id = epsgUtm.id; const idPath = path + "/id"; // The id MUST be a number if (!BasicValidator.validateNumber(idPath, "id", id, context)) { return false; } // The valid range for the id is described as // anyOf { // [32601, 32660] // [32701, 32760] // } // const isInRangeA = id >= 32601 && id <= 32601; const isInRangeB = id >= 32701 && id <= 32760; if (!isInRangeA && !isInRangeB) { const message = `The 'id' property must be in [32601, 32660] or ` + `in [32701, 32760], but is ${id}`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); return false; } return true; } /** * Validate the given referenceSystem * * @param path - The path for validation issues * @param name - The name of the object * @param referenceSystem - The referenceSystem * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateReferenceSystem( path: string, referenceSystemName: string, referenceSystem: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, referenceSystemName, referenceSystem, context ) ) { return false; } let result = true; // Validate the name const name = referenceSystem.name; const namePath = path + "/name"; // The name MUST be a string if (!BasicValidator.validateString(namePath, "name", name, context)) { result = false; } // Validate the description const description = referenceSystem.description; const descriptionPath = path + "/description"; // If the description is defined, then it MUST be a string if (defined(description)) { if ( !BasicValidator.validateString( descriptionPath, "description", description, context ) ) { result = false; } } // Both the name and the description MUST be "human readable". // Not gonna try and validate that... // The structure requires one of two combinations of // properties to be present: // // The organization + systemId (e.g. EPSG 4978) // required : [name, orgWithId, epoch] // disallowed: [definition] // The definition, as a WKT 2 string // required : [name, definition] // disallowed: [orgWithId, epoch] // // The name is always required, and already checked above. // So fetch the other properties, and check for these combinations: const orgWithId = referenceSystem.orgWithId; const orgWithIdPath = path + "/orgWithId"; const definition = referenceSystem.definition; const definitionPath = path + "/definition"; const epoch = referenceSystem.epoch; const epochPath = path + "/epoch"; if (defined(orgWithId) && defined(epoch)) { const disallowedProperties = ["definition"]; if ( !StructureValidator.validateDisallowedProperties( path, "referenceSystem with 'orgWithId' and 'epoch'", referenceSystem, disallowedProperties, context ) ) { result = false; } // Validate the orgWithId if ( !NgaGpmValidator.validateOrganizationSystemIdPair( orgWithIdPath, "orgWithId", orgWithId, context ) ) { result = false; } // Validate the epoch // The epoch MUST be a number if (!BasicValidator.validateNumber(epochPath, "epoch", epoch, context)) { result = false; } } else if (defined(definition)) { const disallowedProperties = ["orgWithId", "epoch"]; if ( !StructureValidator.validateDisallowedProperties( path, "referenceSystem with 'definition'", referenceSystem, disallowedProperties, context ) ) { result = false; } // Validate the definition // The definition MUST be a string if ( !BasicValidator.validateString( definitionPath, "definition", definition, context ) ) { result = false; } // The definition MUST be a WKT (Well-Known-Text) string. // This cannot sensibly be validated here for now. } else { const message = `The reference system must either define the ` + `'orgWithId' and 'epoch', or the 'definition'`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } return result; } /** * Validate the given organizationSystemIdPair * * @param path - The path for validation issues * @param name - The name of the object * @param organizationSystemIdPair - The organizationSystemIdPair * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateOrganizationSystemIdPair( path: string, name: string, organizationSystemIdPair: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, name, organizationSystemIdPair, context ) ) { return false; } let result = true; // Validate the organization const organization = organizationSystemIdPair.organization; const organizationPath = path + "/organization"; // The organization MUST be a string if ( !BasicValidator.validateString( organizationPath, "organization", organization, context ) ) { result = false; } // Validate the systemId const systemId = organizationSystemIdPair.systemId; const systemIdPath = path + "/systemId"; // The systemId MUST be a string if ( !BasicValidator.validateString( systemIdPath, "systemId", systemId, context ) ) { result = false; } return result; } /** * Validate the given modelCoordSystem, assuming that it * did contain the `mcsType === LSR` * * @param path - The path for validation issues * @param name - The name of the object * @param masterRecord - The modelCoordSystem * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateModelCoordSystemLsr( path: string, modelCoordSystem: any, context: ValidationContext ): boolean { // Value was already validated to be an object // in validateModelCoordSystem let result = true; // Validate the origin const origin = modelCoordSystem.origin; const originPath = path + "/origin"; if ( !NgaGpmValidator.validateEcefCoord(originPath, "origin", origin, context) ) { result = false; } // Validate the axisUnitVectors const axisUnitVectors = modelCoordSystem.axisUnitVectors; const axisUnitVectorsPath = path + "/axisUnitVectors"; if ( !NgaGpmValidator.validateUnitVectors( axisUnitVectorsPath, "axisUnitVectors", axisUnitVectors, context ) ) { result = false; } // Validate that disallowed properties are not present const disallowedProperties = ["crsEcef", "crsHorizontalUtm", "crsVertical"]; if ( !StructureValidator.validateDisallowedProperties( path, "modelCoordSystem with mcsType=LSR", modelCoordSystem, disallowedProperties, context ) ) { result = false; } return result; } /** * Validate the given ecefCoord * * @param path - The path for validation issues * @param name - The name of the object * @param ecefCoord - The ecefCoord * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateEcefCoord( path: string, name: string, ecefCoord: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, ecefCoord, context)) { return false; } let result = true; // Validate the coordinates const coordinates = ecefCoord.coordinates; const coordinatesPath = path + "/coordinates"; if ( !NgaGpmValidator.validatePoint3d( coordinatesPath, "coordinates", coordinates, context ) ) { result = false; } // Validate the crsEcef const crsEcef = ecefCoord.crsEcef; const crsEcefPath = path + "/crsEcef"; if ( !NgaGpmValidator.validateEpsgEcef( crsEcefPath, "crsEcef", crsEcef, context ) ) { result = false; } return result; } /** * Validate the given point3d * * @param path - The path for validation issues * @param name - The name of the object * @param point3d - The point3d * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validatePoint3d( path: string, name: string, point3d: any, context: ValidationContext ): boolean { // The point3d MUST be an array of 3 numbers if ( !BasicValidator.validateArray( path, name, point3d, 3, 3, "number", context ) ) { return false; } return true; } /** * Validate the given array of three unitVector objects that form * an orthogonal basis. * * @param path - The path for validation issues * @param name - The name of the object * @param unitVectors - The unitVectors * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateUnitVectors( path: string, name: string, unitVectors: any, context: ValidationContext ): boolean { // The unitVectors MUST be an array of 3 objects if ( !BasicValidator.validateArray( path, name, unitVectors, 3, 3, "object", context ) ) { return false; } let result = true; // Validate each unitVector for (let i = 0; i < unitVectors.length; i++) { const unitVector = unitVectors[i]; const unitVectorPath = path + "/" + i; if ( !NgaGpmValidator.validateUnitVector( unitVectorPath, name + `[${i}]`, unitVector, context ) ) { result = false; } } // If the basic structure of the vectors has been valid until now, // validate that they form an orthonormal basis. if (result) { const unitVector0 = unitVectors[0]; const unitVector1 = unitVectors[1]; const unitVector2 = unitVectors[2]; const dot01 = NgaGpmValidator.computeDotProduct(unitVector0, unitVector1); if (Math.abs(dot01) > ORTHOGONAL_VECTORS_DOT_PRODUCT_EPSILON) { const message = `The vectors ${name}[0] and ${name}[1] are not orthogonal, ` + `their dot product is ${dot01}`; const issue = NgaGpmValidationIssues.VECTORS_NOT_ORTHOGONAL( path, message ); context.addIssue(issue); result = false; } const dot12 = NgaGpmValidator.computeDotProduct(unitVector1, unitVector2); if (Math.abs(dot12) > ORTHOGONAL_VECTORS_DOT_PRODUCT_EPSILON) { const message = `The vectors ${name}[1] and ${name}[2] are not orthogonal, ` + `their dot product is ${dot12}`; const issue = NgaGpmValidationIssues.VECTORS_NOT_ORTHOGONAL( path, message ); context.addIssue(issue); result = false; } const dot20 = NgaGpmValidator.computeDotProduct(unitVector2, unitVector0); if (Math.abs(dot20) > ORTHOGONAL_VECTORS_DOT_PRODUCT_EPSILON) { const message = `The vectors ${name}[2] and ${name}[0] are not orthogonal, ` + `their dot product is ${dot20}`; const issue = NgaGpmValidationIssues.VECTORS_NOT_ORTHOGONAL( path, message ); context.addIssue(issue); result = false; } } return result; } /** * Computes the dot product between the given vectors * * @param v0 - The first vector * @param v1 - The second vector * @returns The dot product */ private static computeDotProduct( v0: [number, number, number], v1: [number, number, number] ): number { const x0 = v0[0]; const y0 = v0[1]; const z0 = v0[2]; const x1 = v1[0]; const y1 = v1[1]; const z1 = v1[2]; const dot = x0 * x1 + y0 * y1 + z0 * z1; return dot; } /** * Computes the length (magnitude) of the given vector * * @param v - The vector * @returns The length */ private static computeLength(v: [number, number, number]): number { const dot = NgaGpmValidator.computeDotProduct(v, v); return Math.sqrt(dot); } /** * Validate the given unitVector * * @param path - The path for validation issues * @param name - The name of the object * @param unitVector - The unitVector * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateUnitVector( path: string, name: string, unitVector: any, context: ValidationContext ): boolean { // The unitVector MUST be an array of 3 numbers if ( !BasicValidator.validateArray( path, name, unitVector, 3, 3, "number", context ) ) { return false; } let result = true; // Validate each unitVector component for (let i = 0; i < unitVector.length; i++) { const unitVectorComponent = unitVector[i]; const unitVectorComponentPath = path + "/" + i; // Each component MUST be a number in [-1.0, 1.0] if ( !BasicValidator.validateNumberRange( unitVectorComponentPath, name + `[${i}]`, unitVectorComponent, -1.0, true, 1.0, true, context ) ) { result = false; } } // If the basic structure of the vector was valid until now, // validate that it has unit length if (result) { const length = NgaGpmValidator.computeLength(unitVector); if (Math.abs(length - 1.0) > UNIT_VECTOR_LENGTH_EPSILON) { const message = `The vector ${name} must have unit length, but has a length ` + `of ${length}`; const issue = NgaGpmValidationIssues.VECTOR_NOT_UNIT_LENGTH( path, message ); context.addIssue(issue); result = false; } } return result; } /** * Validate the given idInformation * * @param path - The path for validation issues * @param name - The name of the object * @param idInformation - The idInformation * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateIdInformation( path: string, name: string, idInformation: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, idInformation, context)) { return false; } let result = true; // Validate the datasetId const datasetId = idInformation.datasetId; const datasetIdPath = path + "/datasetId"; // The datasetId MUST be a string if ( !BasicValidator.validateString( datasetIdPath, "datasetId", datasetId, context ) ) { result = false; } // Validate the referenceDateTime const referenceDateTime = idInformation.referenceDateTime; const referenceDateTimePath = path + "/referenceDateTime"; // The referenceDateTime MUST be an ISO8601 string if ( !StringValidator.validateIso8601String( referenceDateTimePath, "referenceDateTime", referenceDateTime, context ) ) { result = false; } return result; } /** * Validate the given extentInformation * * @param path - The path for validation issues * @param name - The name of the object * @param extentInformation - The extentInformation * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateExtentInformation( path: string, name: string, extentInformation: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, name, extentInformation, context) ) { return false; } let result = true; // Validate the origin const origin = extentInformation.origin; const originPath = path + "/origin"; if ( !NgaGpmValidator.validatePoint3d(originPath, "origin", origin, context) ) { result = false; } // Validate the lsrAxisUnitVectors const lsrAxisUnitVectors = extentInformation.lsrAxisUnitVectors; const lsrAxisUnitVectorsPath = path + "/lsrAxisUnitVectors"; if ( !NgaGpmValidator.validateUnitVectors( lsrAxisUnitVectorsPath, "lsrAxisUnitVectors", lsrAxisUnitVectors, context ) ) { result = false; } // Validate the lsrLengths const lsrLengths = extentInformation.lsrLengths; const lsrLengthsPath = path + "/lsrLengths"; // The lsrLengths MUST be an array of 3 numbers if ( !BasicValidator.validateArray( lsrLengthsPath, "lsrLengths", lsrLengths, 3, 3, "number", context ) ) { result = false; } return result; } /** * Validate the given list of collectionRecord objects * * @param path - The path for validation issues * @param name - The name of the object * @param collectionRecordList - The collectionRecordList * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateCollectionRecordList( path: string, name: string, collectionRecordList: any, context: ValidationContext ): boolean { // The collectionRecordList MUST be an array of at least 1 object if ( !BasicValidator.validateArray( path, "collectionRecordList", collectionRecordList, 1, undefined, "object", context ) ) { return false; } let result = true; // Validate each collectionRecord for (let i = 0; i < collectionRecordList.length; i++) { const collectionRecord = collectionRecordList[i]; const collectionRecordPath = path + "/" + i; if ( !NgaGpmValidator.validateCollectionRecord( collectionRecordPath, name + `[${i}]`, collectionRecord, context ) ) { result = false; } } return result; } /** * Validate the given collectionRecord * * @param path - The path for validation issues * @param name - The name of the object * @param collectionRecord - The collectionRecord * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateCollectionRecord( path: string, name: string, collectionRecord: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, collectionRecord, context)) { return false; } let result = true; // Validate the collectionId const collectionId = collectionRecord.collectionId; const collectionIdPath = path + "/collectionId"; // The collectionId MUST be a string if ( !BasicValidator.validateString( collectionIdPath, "collectionId", collectionId, context ) ) { result = false; } // Validate the platformId const platformId = collectionRecord.platformId; const platformIdPath = path + "/platformId"; // The platformId MUST be a string if ( !BasicValidator.validateString( platformIdPath, "platformId", platformId, context ) ) { result = false; } // Validate the sensorRecords const sensorRecords = collectionRecord.sensorRecords; const sensorRecordsPath = path + "/sensorRecords"; if ( !NgaGpmValidator.validateSensorRecords( sensorRecordsPath, "sensorRecords", sensorRecords, context ) ) { result = false; } return result; } /** * Validate the given list of sensorRecord objects * * @param path - The path for validation issues * @param name - The name of the object * @param sensorRecords - The sensorRecords * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateSensorRecords( path: string, name: string, sensorRecords: any, context: ValidationContext ): boolean { // The sensorRecords MUST be an array of at least 1 object if ( !BasicValidator.validateArray( path, name, sensorRecords, 1, undefined, "object", context ) ) { return false; } let result = true; // Validate each sensorRecord for (let i = 0; i < sensorRecords.length; i++) { const sensorRecord = sensorRecords[i]; const sensorRecordPath = path + "/" + i; if ( !NgaGpmValidator.validateSensorRecord( sensorRecordPath, name + `[${i}]`, sensorRecord, context ) ) { result = false; } } return result; } /** * Validate the given sensorRecord * * @param path - The path for validation issues * @param name - The name of the object * @param sensorRecord - The sensorRecord * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateSensorRecord( path: string, name: string, sensorRecord: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, sensorRecord, context)) { return false; } let result = true; // Validate the sensorId const sensorId = sensorRecord.sensorId; const sensorIdPath = path + "/sensorId"; // The sensorId MUST be a string if ( !BasicValidator.validateString( sensorIdPath, "sensorId", sensorId, context ) ) { result = false; } // Validate the sensorType const sensorType = sensorRecord.sensorType; const sensorTypePath = path + "/sensorType"; // The sensorType MUST be a string if ( !BasicValidator.validateString( sensorTypePath, "sensorType", sensorType, context ) ) { result = false; } // Validate the sensorMode const sensorMode = sensorRecord.sensorMode; const sensorModePath = path + "/sensorMode"; // The sensorMode MUST be a string if ( !BasicValidator.validateString( sensorModePath, "sensorMode", sensorMode, context ) ) { result = false; } // Validate the collectionUnitRecords const collectionUnitRecords = sensorRecord.collectionUnitRecords; const collectionUnitRecordsPath = path + "/collectionUnitRecords"; if ( !NgaGpmValidator.validateCollectionUnitRecords( collectionUnitRecordsPath, "collectionUnitRecords", collectionUnitRecords, context ) ) { result = false; } return result; } /** * Validate the given list of collectionUnitRecord objects * * @param path - The path for validation issues * @param name - The name of the object * @param collectionUnitRecords - The collectionUnitRecords * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateCollectionUnitRecords( path: string, name: string, collectionUnitRecords: any, context: ValidationContext ): boolean { // The collectionUnitRecords MUST be an array of at least 1 object if ( !BasicValidator.validateArray( path, name, collectionUnitRecords, 1, undefined, "object", context ) ) { return false; } let result = true; // Validate each collectionUnitRecord for (let i = 0; i < collectionUnitRecords.length; i++) { const collectionUnitRecord = collectionUnitRecords[i]; const collectionUnitRecordPath = path + "/" + i; if ( !NgaGpmValidator.validateCollectionUnitRecord( collectionUnitRecordPath, name + `[${i}]`, collectionUnitRecord, context ) ) { result = false; } } return result; } /** * Validate the given collectionUnitRecord * * @param path - The path for validation issues * @param name - The name of the object * @param collectionUnitRecord - The collectionUnitRecord * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateCollectionUnitRecord( path: string, name: string, collectionUnitRecord: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, name, collectionUnitRecord, context) ) { return false; } let result = true; // Validate the referenceDateTime const referenceDateTime = collectionUnitRecord.referenceDateTime; const referenceDateTimePath = path + "/referenceDateTime"; // The referenceDateTime MUST be an ISO8601 string if ( !StringValidator.validateIso8601String( referenceDateTimePath, "referenceDateTime", referenceDateTime, context ) ) { // TODO It should be an ISO8601 string. This could/should // be checked with the "validator.js" npm library. result = false; } // Validate the collectionUnitId const collectionUnitId = collectionUnitRecord.collectionUnitId; const collectionUnitIdPath = path + "/collectionUnitId"; // The collectionUnitId MUST be a string if ( !BasicValidator.validateString( collectionUnitIdPath, "collectionUnitId", collectionUnitId, context ) ) { result = false; } // Validate the pointSourceId const pointSourceId = collectionUnitRecord.pointSourceId; const pointSourceIdPath = path + "/pointSourceId"; // The pointSourceId MUST be an integer of at least 0 if ( !BasicValidator.validateIntegerRange( pointSourceIdPath, "pointSourceId", pointSourceId, 0, true, undefined, false, context ) ) { result = false; } // Validate the extentInformation const extentInformation = collectionUnitRecord.extentInformation; const extentInformationPath = path + "/extentInformation"; if ( !NgaGpmValidator.validateExtentInformation( extentInformationPath, "extentInformation", extentInformation, context ) ) { result = false; } return result; } /** * Validate the given unmodeledError * * @param path - The path for validation issues * @param name - The name of the object * @param unmodeledError - The unmodeledError * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateUnmodeledError( path: string, name: string, unmodeledError: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, unmodeledError, context)) { return false; } let result = true; // Validate the uniqueId const uniqueId = unmodeledError.uniqueId; const uniqueIdPath = path + "/uniqueId"; // The uniqueId MUST be a string if ( !BasicValidator.validateString( uniqueIdPath, "uniqueId", uniqueId, context ) ) { result = false; } // Validate the corrRotationThetas const corrRotationThetas = unmodeledError.corrRotationThetas; const corrRotationThetasPath = path + "/corrRotationThetas"; if ( NgaGpmValidator.validateRotationThetas( corrRotationThetasPath, "corrRotationThetas", corrRotationThetas, context ) ) { result = false; } // Validate the corrParams const corrParams = unmodeledError.corrParams; const corrParamsPath = path + "/corrParams"; if ( !NgaGpmValidatorCommon.validateCorrelationParameters( corrParamsPath, "corrParams", corrParams, context ) ) { result = false; } // Validate the posts const posts = unmodeledError.posts; const postsPath = path + "/posts"; if ( !NgaGpmValidator.validateUnmodeledErrorPosts( postsPath, "posts", posts, context ) ) { result = false; } return result; } /** * Validate the given rotationThetas * * @param path - The path for validation issues * @param name - The name of the object * @param rotationThetas - The rotationThetas * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateRotationThetas( path: string, name: string, rotationThetas: any, context: ValidationContext ): boolean { // The rotationThetas MUST be an array of 3 numbers if ( !BasicValidator.validateArray( path, name, rotationThetas, 3, 3, "number", context ) ) { return false; } return true; } /** * Validate the given array of unmodeledErrorPost objects * * @param path - The path for validation issues * @param name - The name of the object * @param unmodeledErrorPosts - The unmodeledErrorPosts * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateUnmodeledErrorPosts( path: string, name: string, unmodeledErrorPosts: any, context: ValidationContext ): boolean { // The unmodeledErrorPosts MUST be an array objects if ( !BasicValidator.validateArray( path, name, unmodeledErrorPosts, undefined, undefined, "object", context ) ) { return false; } let result = true; // Validate each unmodeledErrorPost for (let i = 0; i < unmodeledErrorPosts.length; i++) { const unmodeledErrorPost = unmodeledErrorPosts[i]; const unmodeledErrorPostPath = path + "/" + i; if ( !NgaGpmValidator.validateUnmodeledErrorPost( unmodeledErrorPostPath, name + `[${i}]`, unmodeledErrorPost, context ) ) { result = false; } } return result; } /** * Validate the given unmodeledErrorPost * * @param path - The path for validation issues * @param name - The name of the object * @param unmodeledErrorPost - The unmodeledErrorPost * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateUnmodeledErrorPost( path: string, name: string, unmodeledErrorPost: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, name, unmodeledErrorPost, context) ) { return false; } let result = true; // Validate the position const position = unmodeledErrorPost.position; const positionPath = path + "/position"; if ( !NgaGpmValidator.validatePoint3d( positionPath, "position", position, context ) ) { result = false; } // Validate the covariance const covariance = unmodeledErrorPost.covariance; const covariancePath = path + "/covariance"; if ( !NgaGpmValidator.validateCovarUpperTriangle( covariancePath, "covariance", covariance, context ) ) { result = false; } return result; } /** * Validate the given covarUpperTriangle * * @param path - The path for validation issues * @param name - The name of the object * @param covarUpperTriangle - The covarUpperTriangle * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateCovarUpperTriangle( path: string, name: string, covarUpperTriangle: any, context: ValidationContext ): boolean { // The covarUpperTriangle MUST be an array of 6 numbers if ( !BasicValidator.validateArray( path, name, covarUpperTriangle, 6, 6, "number", context ) ) { return false; } return true; } /** * Validate the given interpolationParams * * @param path - The path for validation issues * @param name - The name of the object * @param interpolationParams - The interpolationParams * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateInterpolationParams( path: string, name: string, interpolationParams: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, name, interpolationParams, context) ) { return false; } // Validate the interpolationMode const interpolationMode = interpolationParams.interpolationMode; const interpolationModePath = path + "/interpolationMode"; // The interpolationMode MUST be one of these valid values const interpolationModeValues = ["nearestNeighbor", "IDW"]; if ( !BasicValidator.validateEnum( interpolationModePath, "interpolationMode", interpolationMode, interpolationModeValues, context ) ) { // The remaining validation depends on the interpolationMode, // so bail out early when it is invalid return false; } let result = true; const interpNumPosts = interpolationParams.interpNumPosts; const interpNumPostsPath = path + "/interpNumPosts"; const dampeningParam = interpolationParams.dampeningParam; const dampeningParamPath = path + "/dampeningParam"; // When the interpolation mode is "nearestNeighbor", then // none of the other properties may be defined. if (interpolationMode === "nearestNeighbor") { const disallowedProperties = ["interpNumPosts", "dampeningParam"]; if ( !StructureValidator.validateDisallowedProperties( path, "interpolationParams with interpolationMode=nearestNeighbor", interpolationParams, disallowedProperties, context ) ) { result = false; } // Nothing else to check when interpolationMode // is "nearestNeighbor" - return immediately. return result; } // Validate the interpNumPosts // The interpNumPosts MUST be an integer of at least 1 if ( !BasicValidator.validateIntegerRange( interpNumPostsPath, "interpNumPosts", interpNumPosts, 1, true, undefined, false, context ) ) { result = false; } // Validate the dampeningParam // The dampeningParam MUST be number if ( !BasicValidator.validateNumber( dampeningParamPath, "dampeningParam", dampeningParam, context ) ) { result = false; } return result; } /** * Validate the given threeDimensionalConformal * * @param path - The path for validation issues * @param name - The name of the object * @param threeDimensionalConformal - The threeDimensionalConformal * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateThreeDimensionalConformal( path: string, name: string, threeDimensionalConformal: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, name, threeDimensionalConformal, context ) ) { return false; } let result = true; // Validate the flags const flags = threeDimensionalConformal.flags; const flagsPath = path + "/flags"; // The flags MUST be an array of 7 boolean values const flagsValid = BasicValidator.validateArray( flagsPath, "flags", flags, 7, 7, "boolean", context ); if (!flagsValid) { result = false; } // The subsequent constraints imply that there must be at least // one flag being set to 'true'. Check this explicitly. // Compute the number of flags that are set to 'true' if (flagsValid) { const numTrueFlags = flags.reduce( (n: number, f: boolean) => n + (f ? 1 : 0), 0 ); if (numTrueFlags === 0) { const message = `At least one of the flags of the threeDimensionalConformal ` + `must be set to 'true'`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); result = false; } } // Validate the recentering const recentering = threeDimensionalConformal.recentering; const recenteringPath = path + "/recentering"; // The recentering MUST be an array of 4 numbers if ( !BasicValidator.validateArray( recenteringPath, "recentering", recentering, 3, 3, "number", context ) ) { result = false; } // Validate the normalizingScaleFactor const normalizingScaleFactor = threeDimensionalConformal.normalizingScaleFactor; const normalizingScaleFactorPath = path + "/normalizingScaleFactor"; // The normalizingScaleFactor MUST be a number if ( !BasicValidator.validateNumber( normalizingScaleFactorPath, "normalizingScaleFactor", normalizingScaleFactor, context ) ) { result = false; } // Validate the parameters const parameters = threeDimensionalConformal.parameters; const parametersPath = path + "/parameters"; // The parameters MUST be an array of at least 1 and at most 7 numbers if ( !BasicValidator.validateArray( parametersPath, "parameters", parameters, 1, 7, "number", context ) ) { result = false; } // Validate the covariance const covariance = threeDimensionalConformal.covariance; const covariancePath = path + "/covariance"; // The covariance MUST be an array of at least 1 and at most 28 numbers if ( !BasicValidator.validateArray( covariancePath, "covariance", covariance, 1, 28, "number", context ) ) { result = false; } // Only if the object has been structurally valid on the JSON level, // validate its overall consistency in terms of array lengths if (result) { result = NgaGpmValidator.validateThreeDimensionalConformalConsistency( path, threeDimensionalConformal, context ); } return result; } /** * Validate the consistency of the given threeDimensionalConformal, * after its basic structural validity has been validated with * `validateThreeDimensionalConformal`. * * This validates the lengths of the 'parameters' and 'covariance' * arrays, depending on the number of 'flags' that have been * set to 'true'. * * Note that this COULD be covered with the basic validation in * `validateThreeDimensionalConformal`, by passing the expected * length to the `BasicValidator.validateArray` calls. But * differentiating between a length that is not valid according * to the schema, and a length that is not "consistent" with * the constraints of the specification allows to provide more * specific validation issues, with more helpful messages. * * @param path - The path for validation issues * @param name - The name of the object * @param threeDimensionalConformal - The threeDimensionalConformal * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateThreeDimensionalConformalConsistency( path: string, threeDimensionalConformal: any, context: ValidationContext ): boolean { let result = true; const flags = threeDimensionalConformal.flags; const parameters = threeDimensionalConformal.parameters; const covariance = threeDimensionalConformal.covariance; // Compute the number of flags that are set to 'true' const numTrueFlags = flags.reduce( (n: number, f: boolean) => n + (f ? 1 : 0), 0 ); // The length of the parameters array MUST match the number of // flags that are set to 'true' if (parameters.length !== numTrueFlags) { const message = `The number of parameters that are given in the ` + `threeDimensionalConformal must match the number of flags that ` + `are set to 'true'. There are ${numTrueFlags} flags that are ` + `set to 'true', but the number of parameters is ${parameters.length}`; const issue = NgaGpmValidationIssues.ARRAY_LENGTH_INCONSISTENT( path, message ); context.addIssue(issue); result = false; } // The length of the array for the upper-triangular of the covariance // matrix MUST be the n-th triangular number, for n being the number // of flags that are set to 'true' const expectedCovarianceLength = NgaGpmValidatorCommon.computeTriangularNumber(numTrueFlags); if (covariance.length !== expectedCovarianceLength) { const message = `The number of elements in the upper-triangular of the covariance of ` + `the threeDimensionalConformal must be 'n*(n+1)/2', for 'n' being the ` + `number of flags that are set to 'true'. There are ${numTrueFlags} ` + `flags that are set to 'true', meaning that the expected length is ` + `${expectedCovarianceLength}, but the length of the covariance array ` + `is ${covariance.length}`; const issue = NgaGpmValidationIssues.ARRAY_LENGTH_INCONSISTENT( path, message ); context.addIssue(issue); result = false; } return result; } /** * Validate the given ppeManifest * * @param path - The path for validation issues * @param name - The name of the object * @param ppeManifest - The ppeManifest * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validatePpeManifest( path: string, name: string, ppeManifest: any, context: ValidationContext ): boolean { // The ppeManifest MUST be an array of at least 1 and at most 7 objects if ( !BasicValidator.validateArray( path, name, ppeManifest, 1, 7, "object", context ) ) { return false; } let result = true; // Check each ppeManifest element to be a valid ppeMetadata for (let i = 0; i < ppeManifest.length; i++) { const ppeMetadata = ppeManifest[i]; const ppeMetadataPath = path + "/" + i; if ( !NgaGpmValidatorCommon.validatePpeMetadata( ppeMetadataPath, name + `[${i}]`, ppeMetadata, context ) ) { result = false; } } // If the basic structure was valid until now, then validate that // the values of the `ppeMetadata[i].source` entries are unique. if (result) { const sourceValues: string[] = []; for (let i = 0; i < ppeManifest.length; i++) { const ppeMetadata = ppeManifest[i]; const source = ppeMetadata.source; sourceValues.push(source); } const sourceValueSet = new Set(sourceValues); if (sourceValueSet.size !== ppeManifest.length) { const message = `The sources of PPE metadata entries must be unique, ` + `but are ${sourceValues} `; const issue = NgaGpmValidationIssues.PER_POINT_ERROR_SOURCE_VALUES_NOT_UNIQUE( path, message ); context.addIssue(issue); result = false; } } return result; } /** * Validate the given anchorPointMetadata * * @param path - The path for validation issues * @param name - The name of the object * @param anchorPointMetadata - The anchorPointMetadata * @param numContentsInRootNode - The number of contents in the root * node of the tileset. * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateAnchorPointMetadata( path: string, name: string, anchorPointMetadata: any, numContentsInRootNode: number, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, name, anchorPointMetadata, context) ) { return false; } let result = true; // Validate the placementType const placementType = anchorPointMetadata.placementType; const placementTypePath = path + "/placementType"; // The placementType MUST be one of these valid values const placementTypeValues = ["MeshContent", "SeparateContent"]; if ( !BasicValidator.validateEnum( placementTypePath, "placementType", placementType, placementTypeValues, context ) ) { // The remaining validation depends on the mcsType, // so bail out early when it is invalid return false; } const contentIndex = anchorPointMetadata.contentIndex; const contentIndexPath = path + "/contentIndex"; if (placementType === "MeshContent") { const disallowedProperties = ["contentIndex"]; if ( !StructureValidator.validateDisallowedProperties( path, "anchorPointMetadata with placementType=MeshContent", anchorPointMetadata, disallowedProperties, context ) ) { result = false; } // Nothing else to check when the placementType is "MeshContent" return result; } // The placementType is "SeparateContent" // Validate the contentIndex // The contentIndex MUST be an integer of which I now // just assume that it may not be negative, and that // may not be larger than the number of contents in // the root node of the tileset if ( !BasicValidator.validateIntegerRange( contentIndexPath, "contentIndex", contentIndex, 0, true, numContentsInRootNode, false, context ) ) { result = false; } return result; } } ================================================ FILE: src/validation/extensions/gpm/NgaGpmValidationIssues.ts ================================================ import { ValidationIssue } from "../../../validation/ValidationIssue"; import { ValidationIssueSeverity } from "../../../validation/ValidationIssueSeverity"; /** * Methods to create `ValidationIssue` instances that describe * issues that are specific for the `NGA_gpm` (3D Tiles) * or `NGA_gpm_local` (glTF) extensions. */ export class NgaGpmValidationIssues { /** * Indicates that the length of an array was not consistent with the * constraints that are implied by the specification. * * In contrast to the `ARRAY_LENGTH_MISMATCH` issue, this one * specifically refers to a constraint that is not modeled by * the `minItems/maxItems` properties in the JSON schema, but * by the meaning of a certain array in a certain context. * For example, a covariance matrix that must have a specific * size depending on the value of another property. Details * are supposed to be given in the `message`. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static ARRAY_LENGTH_INCONSISTENT(path: string, message: string) { const type = "ARRAY_LENGTH_INCONSISTENT"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the length (magnitude) of a 3D vector that is * supposed to be a `unitVector` deviated by more than a certain * epsilon from 1.0. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static VECTOR_NOT_UNIT_LENGTH(path: string, message: string) { const type = "VECTOR_NOT_UNIT_LENGTH"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that two vectors that are supposed to be part of an * orthonormal basis (as part of `lsrAxisUnitVectors`) are not * orthogonal. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static VECTORS_NOT_ORTHOGONAL(path: string, message: string) { const type = "VECTORS_NOT_ORTHOGONAL"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } /** * Indicates that the `source` values of a set of PPE metadata * objects have not been unique. * * @param path - The path for the `ValidationIssue` * @param message - The message for the `ValidationIssue` * @returns The `ValidationIssue` */ static PER_POINT_ERROR_SOURCE_VALUES_NOT_UNIQUE( path: string, message: string ) { const type = "PER_POINT_ERROR_SOURCE_VALUES_NOT_UNIQUE"; const severity = ValidationIssueSeverity.ERROR; const issue = new ValidationIssue(type, path, message, severity); return issue; } } ================================================ FILE: src/validation/extensions/gpm/NgaGpmValidatorCommon.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; /** * A class for validating the elements that can either appear in the * `NGA_gpm` (3D Tiles) extension, or in the `NGA_gpm_local` (glTF) * extension. * * @internal */ export class NgaGpmValidatorCommon { /** * Validate the given array of "correlationGroup" objects that * have been found as the interTileCorrelationGroups or * the intraTileCorrelationGroups * * @param path - The path for validation issues * @param name - The name of the property ("intraTileCorrelationGroups" * or "intraTileCorrelationGroups") * @param correlationGroups - The array of objects * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateCorrelationGroups( path: string, name: string, correlationGroups: any, context: ValidationContext ): boolean { // The correlationGroups MUST be an array of at most 3 objects if ( !BasicValidator.validateArray( path, name, correlationGroups, 0, 3, "object", context ) ) { return false; } let result = true; // Validate each correlationGroup for (let i = 0; i < correlationGroups.length; i++) { const correlationGroup = correlationGroups[i]; const correlationGroupPath = path + "/" + i; if ( !NgaGpmValidatorCommon.validateCorrelationGroup( correlationGroupPath, name + `[${i}]`, correlationGroup, context ) ) { result = false; } } return result; } /** * Validate the given correlationGroup * * @param path - The path for validation issues * @param name - The name of the object * @param correlationGroup - The correlationGroup * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateCorrelationGroup( path: string, name: string, correlationGroup: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, correlationGroup, context)) { return false; } let result = true; // Validate the groupFlags const groupFlags = correlationGroup.groupFlags; const groupFlagsPath = path + "/groupFlags"; // The groupFlags MUST be a 3-element array of booleans const groupFlagsValid = BasicValidator.validateArray( groupFlagsPath, "groupFlags", groupFlags, 3, 3, "boolean", context ); if (!groupFlagsValid) { result = false; } // Validate the rotationThetas const rotationThetas = correlationGroup.rotationThetas; const rotationThetasPath = path + "/rotationThetas"; // The rotationThetas MUST be a 3-element array of numbers const rotationThetasValid = BasicValidator.validateArray( rotationThetasPath, "rotationThetas", rotationThetas, 3, 3, "number", context ); if (!rotationThetasValid) { result = false; } // Validate the params const params = correlationGroup.params; const paramsPath = path + "/params"; if ( !NgaGpmValidatorCommon.validateCorrelationParameters( paramsPath, "params", params, context ) ) { result = false; } return result; } /** * Validate the given array of correlation parameters. This checks whether * the given object is an array of 3 SPDCF (Strictly Positive-Definite * Correlation Function) objects, using `validateSpdcf`. * * @param path - The path for validation issues * @param name - The name of the property * @param correlationParameters - The array of SPDCF objects * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateCorrelationParameters( path: string, name: string, correlationParameters: any, context: ValidationContext ): boolean { // The correlationParameters MUST be a 3-element array of objects if ( !BasicValidator.validateArray( path, name, correlationParameters, 3, 3, "object", context ) ) { return false; } let result = true; // Validate each correlationParameter (an SPDCF) for (let i = 0; i < correlationParameters.length; i++) { const correlationParameter = correlationParameters[i]; const correlationParameterPath = path + "/" + i; if ( !NgaGpmValidatorCommon.validateSpdcf( correlationParameterPath, name + `[${i}]`, correlationParameter, context ) ) { result = false; } } return result; } /** * Validate the given SPDCF (Strictly Positive-Definite Correlation Function) * * @param path - The path for validation issues * @param name - The name of the property * @param spdcf - The SPDCF * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateSpdcf( path: string, name: string, spdcf: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, spdcf, context)) { return false; } let result = true; // Sorry about the names here. I'm trying to be consistent... // Validate the A const A = spdcf.A; const APath = path + "/A"; // The A MUST be a number in (0, 1] const AValid = BasicValidator.validateNumberRange( APath, "A", A, 0, false, 1, true, context ); if (!AValid) { result = false; } // Validate the alpha const alpha = spdcf.alpha; const alphaPath = path + "/alpha"; // The alpha MUST be a number in [0, 1) const alphaValid = BasicValidator.validateNumberRange( alphaPath, "alpha", alpha, 0, true, 1, false, context ); if (!alphaValid) { result = false; } // Validate the beta const beta = spdcf.beta; const betaPath = path + "/beta"; // The beta MUST be a number in [0, 10] const betaValid = BasicValidator.validateNumberRange( betaPath, "beta", beta, 0, true, 10, true, context ); if (!betaValid) { result = false; } // Validate the T const T = spdcf.T; const TPath = path + "/T"; // The T MUST be a number in (0, +Inf) const TValid = BasicValidator.validateNumberRange( TPath, "T", T, 0, false, undefined, false, context ); if (!TValid) { result = false; } return result; } /** * Validate the given ppeMetadata object * * @param path - The path for validation issues * @param name - The name of the property * @param ppeMetadata - The ppeMetadata object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validatePpeMetadata( path: string, name: string, ppeMetadata: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, ppeMetadata, context)) { return false; } let result = true; // Validate the source const source = ppeMetadata.source; const sourcePath = path + "/source"; // The source MUST be one of these valid values const sourceValues = [ "SIGX", "SIGY", "SIGZ", "VARX", "VARY", "VARZ", "SIGR", ]; if ( !BasicValidator.validateEnum( sourcePath, "source", source, sourceValues, context ) ) { result = false; } // Validate the min const min = ppeMetadata.min; const minPath = path + "/min"; // If min is defined, then it MUST be a number if (defined(min)) { if (!BasicValidator.validateNumber(minPath, "min", min, context)) { result = false; } } // Validate the max const max = ppeMetadata.max; const maxPath = path + "/max"; // If max is defined, then it MUST be a number if (defined(max)) { if (!BasicValidator.validateNumber(maxPath, "max", max, context)) { result = false; } } return result; } /** * Returns the n-th triangular number, just so that this computation * has a name. * * The https://en.wikipedia.org/wiki/Triangular_number is the number * of elements in the "upper-triangular of covariance matrix" for * the given number of dimensions, which is the common representation * of covariance matrices in the NGA GPM extensions. * * @param n - The input * @returns The n-th triangular number */ static computeTriangularNumber(n: number): number { return (n * (n + 1)) / 2; } /** * Returns whether the given number is a triangular number. * * The https://en.wikipedia.org/wiki/Triangular_number is the number * of elements in the "upper-triangular of a covariance matrix", * as used in the NGA GPM extensions. * * @param n - The input * @returns Whether the given number is a triangular number */ static isTriangularNumber(n: number): boolean { // The n-th triangular number is T(n) = (n*(n+1))/2 // The inverse function for that is 0.5 * (sqrt(8*n+1) - 1) // So n is a triangular number when 8*n+1 is a square if (n <= 0) { return false; } const radicand = 8 * n + 1; const integralRoot = Math.round(Math.sqrt(radicand)); return integralRoot * integralRoot === radicand; } } ================================================ FILE: src/validation/extensions/maxar/MaxarValidatorCommon.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { JsonValidationIssues } from "../../../issues/JsonValidationIssues"; /** * A class for validating common elements that appear in both * `MAXAR_image_ortho` and `MAXAR_grid` extensions. * * @internal */ export class MaxarValidatorCommon { /** * Validates the spatial reference system (srs) object * * @param path - The path for ValidationIssue instances * @param srs - The srs object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ static validateSrs( path: string, srs: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "srs", srs, context)) { return false; } let result = true; // Validate referenceSystem enum const referenceSystem = srs.referenceSystem; const referenceSystemPath = path + "/referenceSystem"; const validReferenceSystemValues = ["WGS84-G1762", "ITRF2008"]; if ( !BasicValidator.validateEnum( referenceSystemPath, "referenceSystem", referenceSystem, validReferenceSystemValues, context ) ) { result = false; } // Validate epoch pattern const epoch = srs.epoch; const epochPath = path + "/epoch"; if (!BasicValidator.validateString(epochPath, "epoch", epoch, context)) { result = false; } else { const epochPattern = /^[0-9]+(\.[0-9]+)?$/; if (!epochPattern.test(epoch)) { const message = "The 'epoch' must match the pattern '^[0-9]+(\\.[0-9]+)?$'"; const issue = JsonValidationIssues.STRING_VALUE_INVALID( epochPath, message ); context.addIssue(issue); result = false; } } // Validate coordinateSystem const coordinateSystem = srs.coordinateSystem; const coordinateSystemPath = path + "/coordinateSystem"; if ( !BasicValidator.validateString( coordinateSystemPath, "coordinateSystem", coordinateSystem, context ) ) { result = false; } else { if ( !MaxarValidatorCommon.validateCoordinateSystem( coordinateSystemPath, coordinateSystem, context ) ) { result = false; } } // Validate elevation enum const elevation = srs.elevation; const elevationPath = path + "/elevation"; const validElevationValues = ["ELLIPSOID", "EGM2008"]; if ( !BasicValidator.validateEnum( elevationPath, "elevation", elevation, validElevationValues, context ) ) { result = false; } // Validate optional properties with defaults result = MaxarValidatorCommon.validateOptionalSrsProperties(path, srs, context) && result; return result; } /** * Validates the coordinateSystem property which has complex validation rules */ static validateCoordinateSystem( path: string, coordinateSystem: string, context: ValidationContext ): boolean { // Check if it's one of the simple enum values const simpleValues = ["GEOD", "ECEF"]; if (simpleValues.includes(coordinateSystem)) { return true; } // Check UTM pattern: UTM(01-60)[NS] const utmPattern = /^UTM(0[1-9]|[1-5][0-9]|60)[NS]$/; if (utmPattern.test(coordinateSystem)) { return true; } // Check S2 pattern: S2F[0-5] const s2Pattern = /^S2F[0-5]$/; if (s2Pattern.test(coordinateSystem)) { return true; } // If none of the patterns match, it's invalid const message = `The 'coordinateSystem' value '${coordinateSystem}' is invalid. It must be 'GEOD', 'ECEF', match UTM pattern 'UTM(01-60)[NS]', or S2 pattern 'S2F[0-5]'`; const issue = JsonValidationIssues.STRING_VALUE_INVALID(path, message); context.addIssue(issue); return false; } /** * Validates optional SRS properties with their default values and constraints */ static validateOptionalSrsProperties( path: string, srs: any, context: ValidationContext ): boolean { let result = true; // Validate axis enum (optional, default: "NED") const axis = srs.axis; if (defined(axis)) { const axisPath = path + "/axis"; const validAxisValues = ["NED", "ENU"]; if ( !BasicValidator.validateEnum( axisPath, "axis", axis, validAxisValues, context ) ) { result = false; } } // Validate unitHorizontal enum (optional, default: "METER") const unitHorizontal = srs.unitHorizontal; if (defined(unitHorizontal)) { const unitHorizontalPath = path + "/unitHorizontal"; const validUnitHorizontalValues = ["METER", "DEGREE"]; if ( !BasicValidator.validateEnum( unitHorizontalPath, "unitHorizontal", unitHorizontal, validUnitHorizontalValues, context ) ) { result = false; } } // Validate unitVertical enum (optional, default: "METER") const unitVertical = srs.unitVertical; if (defined(unitVertical)) { const unitVerticalPath = path + "/unitVertical"; const validUnitVerticalValues = ["METER"]; if ( !BasicValidator.validateEnum( unitVerticalPath, "unitVertical", unitVertical, validUnitVerticalValues, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/gltf/Accessors.ts ================================================ import { GltfData } from "./GltfData"; /** * Utility methods related to glTF accessors. * * NOTE: These methods are only intended for the use in the * glTF extension validation. They make assumptions about * the validity of the glTF asset (as established by the * glTF Validator), and the structure of the glTF asset * (as established by the extension validator). * * @internal */ export class Accessors { /** * Read the values of the given accessor into an array of numbers. * * This assumes that the accessor has the type SCALAR, and is * valid (in terms of its bufferView etc), as validated with * the glTF Validator. * * @param accessorIndex - The glTF accessor index * @param gltfData - The glTF data * @returns The accessor values (or undefined if the input * glTF data was invalid) */ static readScalarAccessorValues( accessorIndex: number, gltfData: GltfData ): number[] | undefined { const document = gltfData.gltfDocument; if (!document) { return undefined; } const root = document.getRoot(); const accessors = root.listAccessors(); const accessor = accessors[accessorIndex]; const count = accessor.getCount(); const result = []; for (let i = 0; i < count; i++) { const scalar = accessor.getScalar(i); result.push(scalar); } return result; } /** * Read the values of the given accessor into an array of * arrays of numbers. * * This assumes that the accessor has the type VECn or MATn, and * is valid (in terms of its bufferView etc), as validated with * the glTF Validator. * * @param accessorIndex - The glTF accessor index * @param gltfData - The glTF data * @returns The accessor values (or undefined if the input * glTF data was invalid) */ static readArrayAccessorValues( accessorIndex: number, gltfData: GltfData ): number[][] | undefined { const document = gltfData.gltfDocument; if (!document) { return undefined; } const root = document.getRoot(); const accessors = root.listAccessors(); const accessor = accessors[accessorIndex]; const count = accessor.getCount(); const elementSize = accessor.getElementSize(); const result = []; for (let i = 0; i < count; i++) { const target = Array(elementSize); const element = accessor.getElement(i, target); result.push(element); } return result; } } ================================================ FILE: src/validation/gltf/GltfData.ts ================================================ import { BinaryBufferData } from "3d-tiles-tools"; import { Document } from "@gltf-transform/core"; /** * A simple combination of a (parsed) glTF JSON object, * the optional binary buffer of a glTF asset, and * the glTF-Transform document for this data. * * @internal */ export type GltfData = { /** * The parsed glTF JSON object */ gltf: any; /** * The binary buffer, if the glTF was read from a GLB */ binary: Buffer | undefined; /** * The binary buffer data, containing the buffers for * the glTF buffer- and buffer view objects, resolved * from the binary data. */ binaryBufferData: BinaryBufferData; /** * The glTF-Transform document, or `undefined` if the document could * not be read. * * If the document could not be read, then this was caused by the glTF * being "structurally invalid", causing the glTF-Transform IO classes * to bail out at one point or another. Details about the reason * should be captured by the manual validation of the glTF JSON object. * * Specifically: If the glTF structure is 'invalid', then one cannot * expect this gltfDocument to be defined. If the glTF structure is * valid, then it _should_ be defined. Cases where the validator and * the glTF-Transform IO classes disagree should be considered to be * a bug in either of them, and reported as an internal validation * error. */ gltfDocument: Document | undefined; }; ================================================ FILE: src/validation/gltf/GltfDataReader.ts ================================================ import { Document } from "@gltf-transform/core"; import { JSONDocument } from "@gltf-transform/core"; import { Logger } from "@gltf-transform/core"; import { Verbosity } from "@gltf-transform/core"; import { BinaryBufferData } from "3d-tiles-tools"; import { BinaryBufferDataResolver } from "3d-tiles-tools"; import { BinaryBufferStructure } from "3d-tiles-tools"; import { Buffers } from "3d-tiles-tools"; import { GltfTransform } from "3d-tiles-tools"; import { ResourceResolver } from "3d-tiles-tools"; import { GltfUtilities } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { GltfData } from "./GltfData"; import { GltfExtensionValidationIssues } from "../../issues/GltfExtensionValidationIssues"; import { IoValidationIssues } from "../../issues/IoValidationIssue"; /** * A class for reading `GltfData` from a buffer. * * This is only used internally, to resolve all elements that are * part of a `GltfData` that is required for the validation. * * @internal */ export class GltfDataReader { /** * Read the glTF data from the given buffer. * * This currently supports binary glTF and embedded glTF assets. * * If the data can not be read, then the appropriate issue * will be added to the given context, and `undefined` will * be returned * * @param path - The path for `ValidationIssue` instances * @param input - The raw glTF data * @param context - The `ValidationContext` * @returns The glTF data, or `undefined` */ static async readGltfData( path: string, input: Buffer, context: ValidationContext ): Promise { const magicString = Buffers.getMagicString(input); if (magicString === "glTF") { return GltfDataReader.readBinaryGltfData(path, input, context); } return GltfDataReader.readJsonGltfData(path, input, context); } /** * Read the binary glTF data from the given buffer. * * If the data can not be read, then the appropriate issue * will be added to the given context, and `undefined` will * be returned * * @param path - The path for `ValidationIssue` instances * @param input - The raw glTF data * @param context - The `ValidationContext` * @returns The glTF data, or `undefined` */ private static async readBinaryGltfData( path: string, input: Buffer, context: ValidationContext ): Promise { // Obtain the JSON- and binary data from the given buffer let gltfJsonBuffer: Buffer | undefined = undefined; let gltfBinaryBuffer: Buffer | undefined = undefined; try { const glbData = GltfUtilities.extractDataFromGlb(input); gltfJsonBuffer = glbData.jsonData; gltfBinaryBuffer = glbData.binData; } catch (error) { // A TileFormatError may be thrown here const message = `Could not read GLB: ${error}`; const issue = GltfExtensionValidationIssues.GLTF_INVALID(path, message); context.addIssue(issue); return undefined; } // Parse the JSON into a glTF object let gltf: any = undefined; try { gltf = JSON.parse(gltfJsonBuffer.toString()); } catch (error) { const message = `Could not parse glTF JSON: ${error}`; const issue = IoValidationIssues.JSON_PARSE_ERROR(path, message); context.addIssue(issue); return undefined; } // Resolve the binary buffer data, which contains // one (Node) Buffer for each glTF buffer object // and each glTF buffer view object const resourceResolver = context.getResourceResolver(); const binaryBufferData = await GltfDataReader.resolveBinaryBufferData( gltf, gltfBinaryBuffer, resourceResolver ); // Create the glTF-Transform document for the glTF data const gltfDocument = await GltfDataReader.readBinaryGltfDocument(input); return { gltf: gltf, binary: gltfBinaryBuffer, binaryBufferData: binaryBufferData, gltfDocument: gltfDocument, }; } /** * Return the binary buffer data that is described by * the buffers/bufferViews of the given glTF, referring * to the given binary buffer data. * * @param gltf - The glTF object * @param binary - The binary buffer data * @param resourceResolver - The resource resolver * @returns The binary buffer data */ private static async resolveBinaryBufferData( gltf: any, binary: Buffer | undefined, resourceResolver: ResourceResolver ): Promise { // Resolve the data of the bufferView/buffer structure // of the glTF const binaryBufferStructure: BinaryBufferStructure = { buffers: gltf.buffers, bufferViews: gltf.bufferViews, }; const binaryBufferData = await BinaryBufferDataResolver.resolve( binaryBufferStructure, binary, resourceResolver ); return binaryBufferData; } /** * Try to read a glTF-Transform document from the given GLB buffer * data, returning `undefined` if the document cannot be read. * * @param input - The input GLB buffer * @returns The document, or `undefined` */ private static async readBinaryGltfDocument( input: Buffer ): Promise { try { const io = await GltfTransform.getIO(); // Avoid warning "Missing optional extension" io.setLogger(new Logger(Verbosity.ERROR)); const gltfDocument = await io.readBinary(input); return gltfDocument; } catch (error) { // This may happen when the glTF is invalid. The exact reason should // be reported by the validator. If the validator does not detect // a reason, and the document could still not be read, then this // should be treated as an internal error. return undefined; } } /** * Read the glTF data from the given buffer, which contains * glTF JSON. * * This currently only supports embedded glTF. * * If the data can not be read, then the appropriate issue * will be added to the given context, and `undefined` will * be returned * * @param path - The path for `ValidationIssue` instances * @param input - The raw glTF data * @param context - The `ValidationContext` * @returns The glTF data, or `undefined` */ private static async readJsonGltfData( path: string, input: Buffer, context: ValidationContext ): Promise { // Parse the glTF object from the input buffer let gltf: any = undefined; try { gltf = JSON.parse(input.toString()); } catch (error) { const message = `Could not parse glTF JSON: ${error}`; const issue = IoValidationIssues.JSON_PARSE_ERROR(path, message); context.addIssue(issue); return undefined; } // Resolve the binary data that is associated with // the glTF asset const resourceResolver = context.getResourceResolver(); const binaryBufferData = await GltfDataReader.resolveBinaryBufferData( gltf, undefined, resourceResolver ); // Create the glTF-Transform document for the glTF data const gltfDocument = await GltfDataReader.readJsonGltfDocument(input); return { gltf: gltf, binary: undefined, binaryBufferData: binaryBufferData, gltfDocument: gltfDocument, }; } /** * Try to read a glTF-Transform document from the given glTF JSON * data, returning `undefined` if the document cannot be read. * * @param input - The input buffer containing glTF JSON * @returns The document, or `undefined` */ private static async readJsonGltfDocument( input: Buffer ): Promise { // TODO There is no way to determine the resources that // are required for a glTF document, and there is no way // to resolve the resources at load time. // See https://github.com/donmccurdy/glTF-Transform/issues/1099 // and the NOTE in the error handling block below. const resources = {}; try { const io = await GltfTransform.getIO(); // Avoid warning "Missing optional extension" io.setLogger(new Logger(Verbosity.ERROR)); const json = JSON.parse(input.toString()); const jsonDoc = { json, resources } as JSONDocument; const gltfDocument = await io.readJSON(jsonDoc); return gltfDocument; } catch (error) { // This may happen when the glTF is invalid. The exact reason should // be reported by the validator. If the validator does not detect // a reason, and the document could still not be read, then this // should be treated as an internal error. // NOTE: The reason here may also be that a linked resource // was not found. There is hardly a way to identify that. // See the 'TODO' above. return undefined; } } } ================================================ FILE: src/validation/gltf/GltfExtensionValidators.ts ================================================ import { ValidationContext } from "../ValidationContext"; import { ExtInstanceFeaturesValidator } from "./instanceFeatures/ExtInstanceFeaturesValidator"; import { ExtMeshFeaturesValidator } from "./meshFeatures/ExtMeshFeaturesValidator"; import { ExtStructuralMetadataValidator } from "./structuralMetadata/ExtStructuralMetadataValidator"; import { MaxarNonvisualGeometryValidator } from "./nonvisualGeometry/MaxarNonvisualGeometryValidator"; import { GltfDataReader } from "./GltfDataReader"; import { NgaGpmLocalValidator } from "./gpmLocal/NgaGpmLocalValidator"; import { MaxarImageOrthoValidator } from "./imageOrtho/MaxarImageOrthoValidator"; import { KhrLightsPunctualValidator } from "./lightsPunctual/KhrLightsPunctualValidator"; /** * A class that only serves as an entry point for validating * glTF extensions, given the raw glTF input data (either * as embedded glTF, or as binary glTF). */ export class GltfExtensionValidators { /** * Ensure that the extensions in the given glTF data are valid. * * @param path - The path for `ValidationIssue` instances * @param input - The raw glTF data * @param context - The `ValidationContext` * @returns Whether the object is valid */ static async validateGltfExtensions( path: string, input: Buffer, context: ValidationContext ): Promise { const gltfData = await GltfDataReader.readGltfData(path, input, context); if (!gltfData) { // Issue was already added to context return false; } let result = true; // Validate `EXT_mesh_features` const extMeshFeaturesValid = await ExtMeshFeaturesValidator.validateGltf( path, gltfData, context ); if (!extMeshFeaturesValid) { result = false; } // Validate `EXT_instance_features` const extInstanceFeatures = await ExtInstanceFeaturesValidator.validateGltf( path, gltfData, context ); if (!extInstanceFeatures) { result = false; } // Validate `EXT_structural_metadata` const extStructuralMetadataValid = await ExtStructuralMetadataValidator.validateGltf( path, gltfData, context ); if (!extStructuralMetadataValid) { result = false; } // Validate `NGA_gpm_local` const ngaGpmLocalValid = await NgaGpmLocalValidator.validateGltf( path, gltfData, context ); if (!ngaGpmLocalValid) { result = false; } // Validate `MAXAR_image_ortho` const maxarImageOrthoValid = await MaxarImageOrthoValidator.validateGltf( path, gltfData, context ); if (!maxarImageOrthoValid) { result = false; } // Validate `KHR_lights_punctual` const khrLightsPunctualValid = await KhrLightsPunctualValidator.validateGltf(path, gltfData, context); if (!khrLightsPunctualValid) { result = false; } // Validate `MAXAR_nonvisual_geometry` const maxarNonvisualGeometryValid = await MaxarNonvisualGeometryValidator.validateGltf( path, gltfData, context ); if (!maxarNonvisualGeometryValid) { result = false; } return result; } } ================================================ FILE: src/validation/gltf/ImageData.ts ================================================ /** * An internal interface representing the image data * that was read for a feature ID- or property texture. * * @internal */ export interface ImageData { /** * The width of the image */ sizeX: number; /** * The height of the image */ sizeY: number; /** * The number of channels (e.g. 3 for RGB, or 4 for RGBA) */ channels: number; /** * The pixels. * * The channel `c` of the pixel at `x`, `y` is indexed * by `index = ((y * sizeX) + x) * channels) + c` */ pixels: number[]; } ================================================ FILE: src/validation/gltf/ImageDataReader.ts ================================================ import sharp from "sharp"; import { defined } from "3d-tiles-tools"; import { BinaryBufferData } from "3d-tiles-tools"; import { ImageData } from "./ImageData"; import { ValidationContext } from "../ValidationContext"; import { IoValidationIssues } from "../../issues/IoValidationIssue"; /** * A class for reading and accessing `ImageData` instances * * @internal */ export class ImageDataReader { /** * Read the `ImageData` from the given glTF image. * * This will read the image data from the `uri` of the given image, * or from the `bufferView` of the image. * * If the data cannot be read, then a validation error will be * added to the given context, and `undefined` will be returned. * * @param path - The path for the `ValidationIssue` instances * @param image - The glTF `image` object * @param binaryBufferData - The `BinaryBufferData` that contains * the buffer view data of the glTF * @param context - The `ValidationContext` that any issues will be added to * @returns The image data, or `undefined` */ static async readFromImage( path: string, image: any, binaryBufferData: BinaryBufferData, context: ValidationContext ): Promise { // Read the image data buffer, either from a data URI or from // the binary buffer data (using the buffer view index) let imageDataBuffer; const uri = image.uri; if (defined(uri)) { const resourceResolver = context.getResourceResolver(); imageDataBuffer = await resourceResolver.resolveData(uri); } else { const bufferViewIndex = image.bufferView; if (defined(bufferViewIndex)) { imageDataBuffer = binaryBufferData.bufferViewsData[bufferViewIndex]; } } if (!imageDataBuffer) { const message = `Could not resolve image data`; const issue = IoValidationIssues.IO_ERROR(path, message); context.addIssue(issue); return undefined; } // Try to read image data (pixels) from the image data buffer try { const imageData = await ImageDataReader.readUnchecked(imageDataBuffer); return imageData; } catch (error) { const message = `Could not read image data: ${error}`; const issue = IoValidationIssues.IO_ERROR(path, message); context.addIssue(issue); return undefined; } } /** * Obtains the value from the specified pixel and channels in the * given image data. * * This is computed by composing the (supposedly `UINT8`) channel * values of the pixels * * @param imageData - The ImageData object * @param x - The x-coordinate * @param y - The y-coordinate * @param channels - The `channels` definition from the texture * @returns The value */ static getValue( imageData: ImageData, x: number, y: number, channels: number[] ) { const sizeX = imageData.sizeX; const numChannels = imageData.channels; const pixels = imageData.pixels; let result = 0; const offset = (y * sizeX + x) * numChannels; for (let c = 0; c < channels.length; c++) { const channel = channels[c]; const shift = c * 8; const channelValue = pixels[offset + channel]; result |= channelValue << shift; } return result; } /** * Returns the value of the specified channel of the specified pixel * in the given image data. * * @param imageData - The ImageData object * @param x - The x-coordinate * @param y - The y-coordinate * @param channel - The `channel` (usually in [0...3] for RGBA) * @returns The value */ static getChannelValue( imageData: ImageData, x: number, y: number, channel: number ) { const sizeX = imageData.sizeX; const numChannels = imageData.channels; const pixels = imageData.pixels; const offset = (y * sizeX + x) * numChannels; const channelValue = pixels[offset + channel]; return channelValue; } /** * Try to read image data from the given buffer. * * The exact set of image formats that may be contained in the given * buffer is not specified. But it will support PNG and JPEG. * * @param imageDataBuffer - The image data buffer * @returns The `ImageData` * @throws An error if the image data can not be read */ static async readUnchecked(imageDataBuffer: Buffer): Promise { const sharpImage = sharp(imageDataBuffer); const metadata = await sharpImage.metadata(); const sizeX = metadata.width; const sizeY = metadata.height; const channels = metadata.channels; if (sizeX === undefined || sizeY === undefined || channels === undefined) { throw new Error("Could not read image metadata"); } const pixelsBuffer = await sharpImage.raw().toBuffer(); const pixels = [...pixelsBuffer]; return { sizeX: sizeX, sizeY: sizeY, channels: channels, pixels: pixels, }; } } ================================================ FILE: src/validation/gltf/SamplerValidator.ts ================================================ import { ValidationContext } from "../ValidationContext"; import { JsonValidationIssues } from "../../issues/JsonValidationIssues"; /** * Methods for validating glTF `sampler` objects in the context * of the glTF metadata extension validation. */ export class SamplerValidator { /** * Make sure that the given sampler has `minFilter` and `maxFilter` * properties that are either `undefined` or `NEAREST`. * * @param path - The path for the `ValidationIssue` instances * @param sampler - The sampler object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateSamplerNearest( path: string, sampler: any, context: ValidationContext ) { const NEAREST = 9728; const allowedValues = [undefined, NEAREST]; const allowedValuesString = "[undefined, 9728 (NEAREST)]"; return SamplerValidator.validateSampler( path, sampler, allowedValues, allowedValuesString, context ); } /** * Make sure that the given sampler has `minFilter` and `maxFilter` * properties that are either `undefined`, `NEAREST`, or `LINEAR`. * * @param path - The path for the `ValidationIssue` instances * @param sampler - The sampler object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateSamplerNearestOrLinear( path: string, sampler: any, context: ValidationContext ) { const NEAREST = 9728; const LINEAR = 9729; const allowedValues = [undefined, NEAREST, LINEAR]; const allowedValuesString = "[undefined, 9728 (NEAREST), 9729 (LINEAR)]"; return SamplerValidator.validateSampler( path, sampler, allowedValues, allowedValuesString, context ); } /** * Make sure that the given sampler has `minFilter` and `maxFilter` * properties that are one of the given allowed values, creating * a validation error in the given context if this is not the * case. * * @param path - The path for the `ValidationIssue` instances * @param sampler - The sampler object * @param allowedValues - The allowed values * @param allowedValuesString - A string that will describe the allowed * values in the validation issues * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateSampler( path: string, sampler: any, allowedValues: any[], allowedValuesString: string, context: ValidationContext ) { let result = true; if (!allowedValues.includes(sampler.minFilter)) { const message = `The texture refers to a sampler with 'minFilter' ` + `mode ${sampler.minFilter}, but the filter mode must ` + `be one of ${allowedValuesString}`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST(path, message); context.addIssue(issue); result = false; } if (!allowedValues.includes(sampler.magFilter)) { const message = `The texture refers to a sampler with 'magFilter' ` + `mode ${sampler.minFilter}, but the filter mode must ` + `be one of ${allowedValuesString}`; const issue = JsonValidationIssues.VALUE_NOT_IN_LIST(path, message); context.addIssue(issue); result = false; } return result; } } ================================================ FILE: src/validation/gltf/TextureValidator.ts ================================================ import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { StructureValidationIssues } from "../../issues/StructureValidationIssues"; import { GltfExtensionValidationIssues } from "../../issues/GltfExtensionValidationIssues"; /** * A class for validating feature ID or property textures in the * glTF metadata extensions. * * @internal */ export class TextureValidator { /** * Validate the `texCoord` definition of a texture. * * Without further context, this can only check whether the `texCoord` * property is a nonnegative integer. * * It can NOT check whether the `texCoord` results in a * `TEXCOORD_${texCoord}` attribute that actually appears in a * mesh primitive. For this, `validateTexCoordForMeshPrimitive` * can be used. * * If the given value is not valid, then a validation error will * be added to the given context, and `false` will be returned. * * @param path - The path for validation issues * @param texCoord - The the texture coordinate set index, used for * constructing the `TEXCOORD_${texCoord}` attribute name. * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateTexCoordDefinition( path: string, texCoord: number, context: ValidationContext ): boolean { // The texCoord MUST be an integer of at least 0 if ( !BasicValidator.validateIntegerRange( path, "texCoord", texCoord, 0, true, undefined, false, context ) ) { return false; } return true; } /** * Validate the `texCoord` definition of a texture. * * This will check whether the given value is a nonnegative integer, * and whether the resulting `TEXCOORD_${texCoord}` attribute * appears in the given mesh primitive. * * If the given value is not valid, then a validation error will * be added to the given context, and `false` will be returned. * * @param path - The path for validation issues * @param texCoord - The the texture coordinate set index, used for * constructing the `TEXCOORD_${texCoord}` attribute name. * @param gltf - The glTF object * @param meshPrimitive - The mesh primitive that contains the extension * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateTexCoordForMeshPrimitive( path: string, texCoord: number, meshPrimitive: any, context: ValidationContext ): boolean { // The texCoord MUST be an integer of at least 0 if ( !BasicValidator.validateIntegerRange( path, "texCoord", texCoord, 0, true, undefined, false, context ) ) { return false; } // For a given texCoord value, the attribute // with the name `TEXCOORD_${texCoord}` must // appear as an attribute in the mesh primitive const texCoordAttributeName = `TEXCOORD_${texCoord}`; const primitiveAttributes = meshPrimitive.attributes || {}; const texCoordAccessorIndex = primitiveAttributes[texCoordAttributeName]; if (texCoordAccessorIndex === undefined) { const message = `The texture defines the texCoord ${texCoord}, ` + `but the attribute ${texCoordAttributeName} was not ` + `found in the mesh primitive attributes`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( path, message ); context.addIssue(issue); return false; } // The presence and validity of the accessor for the TEXCOORD_n // attribute has already been validated by the glTF-Validator. // This includes the validation that... // - the accessor type MUST be "VEC2" // - the accessor componentType MUST be FLOAT, UNSIGNED_BYTE, // or UNSIGNED_SHORT // - when the accessor componentType is UNSIGNED_BYTE or // UNSIGNED_SHORT, then the accessor MUST be normalized return true; } /** * Validate the given `channels`, which may be part of a feature ID * texture or a property texture. * * In both cases, the `channels` must be an array with at least 1 * element, and all elements must be nonnegative integers. * * This only performs the structural validation. The validity of * the elements of the `channels` array for a given number of * image channels can be checked with `validateChannelsForImage`. * * The validity of the binary data that is supposed to be accessed * using these channels is not checked here. * * If the channels are not valid, then a validation error will be * added to the given context, and `false` will be returned. * * @param path - The path for validation issues * @param channels - The channels * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateChannels( path: string, channels: any, context: ValidationContext ): boolean { let result = true; const channelsPath = path + "/channels"; if (channels) { if ( !BasicValidator.validateArray( channelsPath, "channels", channels, 1, undefined, "number", context ) ) { result = false; } else { for (let i = 0; i < channels.length; i++) { const channelsElement = channels[i]; const channelsElementPath = path + "/" + i; if ( !BasicValidator.validateIntegerRange( channelsElementPath, "channel", channelsElement, 0, true, undefined, false, context ) ) { result = false; } } } } return result; } /** * Validate the given `channels`, which may be part of a feature ID * texture or a property texture, for an image that has the * given number of channels. * * If the channels are not valid, then a validation error will be * added to the given context, and `false` will be returned. * * @param path - The path for validation issues * @param name - A name for the source of the `channels` definition. * This may be "feature ID texture" or "property texture property". * @param channels - The channels * @param channelsInImage - The number of channels in the image * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateChannelsForImage( path: string, name: string, channels: number[], channelsInImage: number, context: ValidationContext ): boolean { // Make sure that the `channels` contains only elements that // are smaller than the number of channels in the image if (channels.length > channelsInImage) { const message = `The ${name} defines ${channels.length} channels, ` + `but the texture only contains ${channelsInImage} channels`; const issue = GltfExtensionValidationIssues.TEXTURE_CHANNELS_OUT_OF_RANGE( path, message ); context.addIssue(issue); return false; } for (let i = 0; i < channels.length; i++) { const c = channels[i]; if (c >= channelsInImage) { const message = `Channel ${i} of the ${name} is ${c}, ` + `but the texture only contains ${channelsInImage} channels`; const issue = GltfExtensionValidationIssues.TEXTURE_CHANNELS_OUT_OF_RANGE( path, message ); context.addIssue(issue); return false; } } return true; } } ================================================ FILE: src/validation/gltf/gpmLocal/NgaGpmLocalValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { GltfData } from "../GltfData"; import { StructureValidationIssues } from "../../../issues/StructureValidationIssues"; import { TextureValidator } from "../TextureValidator"; import { NgaGpmValidatorCommon } from "../../extensions/gpm/NgaGpmValidatorCommon"; import { NgaGpmValidationIssues } from "../../extensions/gpm/NgaGpmValidationIssues"; /** * A class for validating the `NGA_gpm_local` extension in glTF assets. * * This class assumes that the structure of the glTF asset itself * has already been validated (e.g. with the glTF Validator). * * @internal */ export class NgaGpmLocalValidator { /** * Performs the validation to ensure that the `NGA_gpm_local` * extensions in the given glTF are valid * * @param path - The path for validation issues * @param gltfData - The glTF data, containing the parsed JSON and the * (optional) binary buffer * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static async validateGltf( path: string, gltfData: GltfData, context: ValidationContext ): Promise { const gltf = gltfData.gltf; let result = true; // Check if the NGA_gpm_local extension object // at the root level is present and valid const rootExtensions = gltf.extensions; if (defined(rootExtensions)) { const gltfGpmLocal = rootExtensions["NGA_gpm_local"]; if (defined(gltfGpmLocal)) { const rootExtensionObjectIsValid = NgaGpmLocalValidator.validateGltfGpmLocal( path, gltfGpmLocal, context ); if (!rootExtensionObjectIsValid) { result = false; } } } // Check all mesh primitives, and see whether NGA_gpm_local // extension object is present and valid const meshes = gltf.meshes; if (defined(meshes) && Array.isArray(meshes)) { for (let m = 0; m < meshes.length; m++) { const mesh = meshes[m]; const primitives = mesh.primitives; if (defined(primitives) && Array.isArray(primitives)) { for (let p = 0; p < primitives.length; p++) { const primitive = primitives[p]; const primitiveExtensions = primitive.extensions; if (defined(primitiveExtensions)) { const primitiveGpmLocal = primitiveExtensions["NGA_gpm_local"]; if (defined(primitiveGpmLocal)) { const currentPath = path + "/meshes/" + m + "/primitives/" + p; const meshPrimitiveExtensionObjectIsValid = NgaGpmLocalValidator.validateMeshPrimitiveGpmLocal( currentPath, primitiveGpmLocal, gltf, primitive, context ); if (!meshPrimitiveExtensionObjectIsValid) { result = false; } } } } } } } return result; } /** * Validate the given root-level NGA_gpm_local extension object * * @param path - The path for validation issues * @param gltfGpmLocal - The root-level NGA_gpm_local extension object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateGltfGpmLocal( path: string, gltfGpmLocal: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "NGA_gpm_local", gltfGpmLocal, context ) ) { return false; } // Validate the storageType const storageType = gltfGpmLocal.storageType; const storageTypePath = path + "/storageType"; // The storageType MUST be one of these valid values const storageTypeValues = ["Direct", "Indirect"]; if ( !BasicValidator.validateEnum( storageTypePath, "storageType", storageType, storageTypeValues, context ) ) { // The remaining validation depends on the storageType, // so bail out early when it is invalid return false; } // The actual structure of the extension object is defined // with a "oneOf [ two nearly disjoint things ]", depending // on the storageType. if (storageType === "Indirect") { return NgaGpmLocalValidator.validateGltfGpmLocalIndirect( path, gltfGpmLocal, context ); } return NgaGpmLocalValidator.validateGltfGpmLocalDirect( path, gltfGpmLocal, context ); } /** * Validate the given root-level NGA_gpm_local extension object, * assuming that it already has been checked to contain the * `storageType === "Indirect"`. * * @param path - The path for validation issues * @param gltfGpmLocal - The root-level NGA_gpm_local extension object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateGltfGpmLocalIndirect( path: string, gltfGpmLocal: any, context: ValidationContext ): boolean { const storageType = "Indirect"; let result = true; // Validate that the properties that are disallowed for // the storageType===Indirect are NOT defined: const anchorPointsDirect = gltfGpmLocal.anchorPointsDirect; if (defined(anchorPointsDirect)) { const message = `For storageType===${storageType}, ` + `the 'anchorPointsDirect' may not be defined`; const issue = StructureValidationIssues.DISALLOWED_VALUE_FOUND( path, message ); context.addIssue(issue); result = false; } const covarianceDirectUpperTriangle = gltfGpmLocal.covarianceDirectUpperTriangle; if (defined(covarianceDirectUpperTriangle)) { const message = `For storageType===${storageType}, ` + `the 'covarianceDirectUpperTriangle' may not be defined`; const issue = StructureValidationIssues.DISALLOWED_VALUE_FOUND( path, message ); context.addIssue(issue); result = false; } // Validate the anchorPointsIndirect const anchorPointsIndirect = gltfGpmLocal.anchorPointsIndirect; const anchorPointsIndirectPath = path + "/anchorPointsIndirect"; if (!defined(anchorPointsIndirect)) { const message = `For storageType===${storageType}, ` + `the 'anchorPointsIndirect' must be defined`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else { const anchorPointsIndirectValid = NgaGpmLocalValidator.validateAnchorPointsIndirect( anchorPointsIndirectPath, "anchorPointsIndirect", anchorPointsIndirect, context ); if (!anchorPointsIndirectValid) { result = false; } } // Validate the intraTileCorrelationGroups const intraTileCorrelationGroups = gltfGpmLocal.intraTileCorrelationGroups; const intraTileCorrelationGroupsPath = path + "/intraTileCorrelationGroups"; if (!defined(intraTileCorrelationGroups)) { const message = `For storageType===${storageType}, ` + `the 'intraTileCorrelationGroups' must be defined`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else { const intraTileCorrelationGroupsValid = NgaGpmValidatorCommon.validateCorrelationGroups( intraTileCorrelationGroupsPath, "intraTileCorrelationGroups", intraTileCorrelationGroups, context ); if (!intraTileCorrelationGroupsValid) { result = false; } } return result; } /** * Validate the given array of "anchorPointIndirect" objects * * @param path - The path for validation issues * @param name - The name of the object * @param anchorPointsIndirect - The array of objects * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateAnchorPointsIndirect( path: string, name: string, anchorPointsIndirect: any, context: ValidationContext ): boolean { // The anchorPointsIndirect MUST be an array of at least 1 object if ( !BasicValidator.validateArray( path, name, anchorPointsIndirect, 1, undefined, "object", context ) ) { return false; } let result = true; // Validate each anchorPointIndirect for (let i = 0; i < anchorPointsIndirect.length; i++) { const anchorPointIndirect = anchorPointsIndirect[i]; const anchorPointIndirectPath = path + "/" + i; if ( !NgaGpmLocalValidator.validateAnchorPointIndirect( anchorPointIndirectPath, name + `[${i}]`, anchorPointIndirect, context ) ) { result = false; } } return result; } /** * Validate the given anchorPointIndirect * * @param path - The path for validation issues * @param name - The name of the object * @param anchorPointIndirect - The anchorPointIndirect * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateAnchorPointIndirect( path: string, name: string, anchorPointIndirect: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, name, anchorPointIndirect, context) ) { return false; } let result = true; // Validate the position const position = anchorPointIndirect.position; const positionPath = path + "/position"; // The position MUST be a 3-element array of numbers const positionValid = BasicValidator.validateArray( positionPath, "position", position, 3, 3, "number", context ); if (!positionValid) { result = false; } // Validate the adjustmentParams const adjustmentParams = anchorPointIndirect.adjustmentParams; const adjustmentParamsPath = path + "/adjustmentParams"; // The adjustmentParams MUST be a 3-element array of numbers const adjustmentParamsValid = BasicValidator.validateArray( adjustmentParamsPath, "adjustmentParams", adjustmentParams, 3, 3, "number", context ); if (!adjustmentParamsValid) { result = false; } // Validate the covarianceMatrix const covarianceMatrix = anchorPointIndirect.covarianceMatrix; const covarianceMatrixPath = path + "/covarianceMatrix"; // The covarianceMatrix MUST be a 6-element array of numbers const covarianceMatrixValid = BasicValidator.validateArray( covarianceMatrixPath, "covarianceMatrix", covarianceMatrix, 6, 6, "number", context ); if (!covarianceMatrixValid) { result = false; } return result; } /** * Validate the given root-level NGA_gpm_local extension object, * assuming that it already has been checked to contain the * `storageType === "Direct"`. * * @param path - The path for validation issues * @param gltfGpmLocal - The root-level NGA_gpm_local extension object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateGltfGpmLocalDirect( path: string, gltfGpmLocal: any, context: ValidationContext ): boolean { const storageType = "Direct"; let result = true; // Validate that the properties that are disallowed for // the storageType===Direct are NOT defined: const anchorPointsIndirect = gltfGpmLocal.anchorPointsIndirect; if (defined(anchorPointsIndirect)) { const message = `For storageType===${storageType}, ` + `the 'anchorPointsIndirect' may not be defined`; const issue = StructureValidationIssues.DISALLOWED_VALUE_FOUND( path, message ); context.addIssue(issue); result = false; } const intraTileCorrelationGroups = gltfGpmLocal.intraTileCorrelationGroups; if (defined(intraTileCorrelationGroups)) { const message = `For storageType===${storageType}, ` + `the 'intraTileCorrelationGroups' may not be defined`; const issue = StructureValidationIssues.DISALLOWED_VALUE_FOUND( path, message ); context.addIssue(issue); result = false; } // Validate the anchorPointsDirect const anchorPointsDirect = gltfGpmLocal.anchorPointsDirect; const anchorPointsDirectPath = path + "/anchorPointsDirect"; if (!defined(anchorPointsDirect)) { const message = `For storageType===${storageType}, ` + `the 'anchorPointsDirect' must be defined`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else { const anchorPointsDirectValid = NgaGpmLocalValidator.validateAnchorPointsDirect( anchorPointsDirectPath, "anchorPointsDirect", anchorPointsDirect, context ); if (!anchorPointsDirectValid) { result = false; } } // Validate the covarianceDirectUpperTriangle const covarianceDirectUpperTriangle = gltfGpmLocal.covarianceDirectUpperTriangle; const covarianceDirectUpperTrianglePath = path + "/covarianceDirectUpperTriangle"; if (!defined(covarianceDirectUpperTriangle)) { const message = `For storageType===${storageType}, ` + `the 'covarianceDirectUpperTriangle' must be defined`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else { const covarianceDirectUpperTriangleValid = NgaGpmLocalValidator.validateCovarianceDirectUpperTriangle( covarianceDirectUpperTrianglePath, covarianceDirectUpperTriangle, context ); if (!covarianceDirectUpperTriangleValid) { result = false; } } return result; } /** * Validate the given array of anchorPointDirect objects * * @param path - The path for validation issues * @param name - The name of the object * @param anchorPointsDirect - The array object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateAnchorPointsDirect( path: string, name: string, anchorPointsDirect: any, context: ValidationContext ): boolean { // The anchorPointsDirect MUST be an array of at least 1 object if ( !BasicValidator.validateArray( path, name, anchorPointsDirect, 1, undefined, "object", context ) ) { return false; } let result = true; // Validate each anchorPointDirect for (let i = 0; i < anchorPointsDirect.length; i++) { const anchorPointDirect = anchorPointsDirect[i]; const anchorPointDirectPath = path + "/" + i; if ( !NgaGpmLocalValidator.validateAnchorPointDirect( anchorPointDirectPath, name + `[${i}]`, anchorPointDirect, context ) ) { result = false; } } return result; } /** * Validate the given anchorPointDirect * * @param path - The path for validation issues * @param name - The name of the object * @param anchorPointDirect - The anchorPointDirect * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateAnchorPointDirect( path: string, name: string, anchorPointDirect: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, name, anchorPointDirect, context) ) { return false; } let result = true; // Validate the position const position = anchorPointDirect.position; const positionPath = path + "/position"; // The position MUST be a 3-element array of numbers const positionValid = BasicValidator.validateArray( positionPath, "position", position, 3, 3, "number", context ); if (!positionValid) { result = false; } // Validate the adjustmentParams const adjustmentParams = anchorPointDirect.adjustmentParams; const adjustmentParamsPath = path + "/adjustmentParams"; // The adjustmentParams MUST be a 3-element array of numbers const adjustmentParamsValid = BasicValidator.validateArray( adjustmentParamsPath, "adjustmentParams", adjustmentParams, 3, 3, "number", context ); if (!adjustmentParamsValid) { result = false; } return result; } /** * Validate the given covarianceDirectUpperTriangle * * @param path - The path for validation issues * @param covarianceDirectUpperTriangle - The covarianceDirectUpperTriangle * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateCovarianceDirectUpperTriangle( path: string, covarianceDirectUpperTriangle: any, context: ValidationContext ): boolean { // The covarianceDirectUpperTriangle MUST be an array of at least 1 number if ( !BasicValidator.validateArray( path, "covarianceDirectUpperTriangle", covarianceDirectUpperTriangle, 1, undefined, "number", context ) ) { return false; } let result = true; // The length of the array for the upper-triangular of the covariance // matrix MUST be a triangular number const n = covarianceDirectUpperTriangle.length; const isTriangularNumber = NgaGpmValidatorCommon.isTriangularNumber(n); if (!isTriangularNumber) { const message = `The number of elements in the upper-triangular of the covariance ` + `matrix must be a triangular number, but is ${n}`; const issue = NgaGpmValidationIssues.ARRAY_LENGTH_INCONSISTENT( path, message ); context.addIssue(issue); result = false; } return result; } /** * Validate the given mesh-primitive NGA_gpm_local extension object * * @param path - The path for validation issues * @param meshPrimitiveGpmLocal - The mesh-primitive NGA_gpm_local extension object * @param gltf - The glTF that contains this object * @param meshPrimitive - The mesh primitive that contains this object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateMeshPrimitiveGpmLocal( path: string, meshPrimitiveGpmLocal: any, gltf: any, meshPrimitive: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "NGA_gpm_local", meshPrimitiveGpmLocal, context ) ) { return false; } // Validate the ppeTextures const ppeTextures = meshPrimitiveGpmLocal.ppeTextures; const ppeTexturesPath = path + "/ppeTextures"; return NgaGpmLocalValidator.validatePpeTextures( ppeTexturesPath, "ppeTextures", ppeTextures, gltf, meshPrimitive, context ); } /** * Validate the given mesh-primitive NGA_gpm_local extension object * * @param path - The path for validation issues * @param meshPrimitiveGpmLocal - The mesh-primitive NGA_gpm_local extension object * @param gltf - The glTF that contains this object * @param meshPrimitive - The mesh primitive that contains this object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validatePpeTextures( path: string, name: string, ppeTextures: any, gltf: any, meshPrimitive: any, context: ValidationContext ): boolean { // The ppeTextures MUST be an array of objects if ( !BasicValidator.validateArray( path, name, ppeTextures, 1, undefined, "object", context ) ) { return false; } let result = true; // Validate each ppeTexture for (let i = 0; i < ppeTextures.length; i++) { const ppeTexture = ppeTextures[i]; const ppeTexturePath = path + "/" + i; if ( !NgaGpmLocalValidator.validatePpeTexture( ppeTexturePath, name + `[${i}]`, ppeTexture, gltf, meshPrimitive, context ) ) { result = false; } } return result; } /** * Validate the given ppeTexture object * * @param path - The path for validation issues * @param name - The name of the object * @param ppeTexture - The ppeTexture object * @param gltf - The glTF that contains this object * @param meshPrimitive - The mesh primitive that contains this object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validatePpeTexture( path: string, name: string, ppeTexture: any, gltf: any, meshPrimitive: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, ppeTexture, context)) { return false; } let result = true; // Validate the index (this is part of the textureInfo) const index = ppeTexture.index; const indexPath = path + "/index"; // The index MUST be defined, and must be a valid texture index const textures = gltf.textures ?? []; if ( !BasicValidator.validateIntegerRange( indexPath, "index", index, 0, true, textures.length, false, context ) ) { result = false; } // Validate the texCoord (this is part of the textureInfo) const texCoord = ppeTexture.texCoord; const texCoordPath = path + "/texCoord"; if (defined(texCoord)) { if ( !TextureValidator.validateTexCoordForMeshPrimitive( texCoordPath, texCoord, meshPrimitive, context ) ) { result = false; } } // Validate the traits const traits = ppeTexture.traits; const traitsPath = path + "/traits"; if ( !NgaGpmValidatorCommon.validatePpeMetadata( traitsPath, "traits", traits, context ) ) { result = false; } // Validate the noData const noData = ppeTexture.noData; const noDataPath = path + "/noData"; // If noData is defined, then it MUST be an integer if (defined(noData)) { if ( !BasicValidator.validateInteger(noDataPath, "noData", noData, context) ) { result = false; } } // Validate the offset const offset = ppeTexture.offset; const offsetPath = path + "/offset"; // If offset is defined, then it MUST be a number if (defined(offset)) { if ( !BasicValidator.validateNumber(offsetPath, "offset", offset, context) ) { result = false; } } // Validate the scale const scale = ppeTexture.scale; const scalePath = path + "/scale"; // If scale is defined, then it MUST be a number if (defined(scale)) { if (!BasicValidator.validateNumber(scalePath, "scale", scale, context)) { result = false; } } return result; } } ================================================ FILE: src/validation/gltf/imageOrtho/MaxarImageOrthoValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { GltfData } from "../GltfData"; import { MaxarValidatorCommon } from "../../extensions/maxar/MaxarValidatorCommon"; /** * A class for validating the `MAXAR_image_ortho` extension in * glTF assets. * * This class assumes that the structure of the glTF asset itself * has already been validated (e.g. with the glTF Validator). * * @internal */ export class MaxarImageOrthoValidator { /** * Performs the validation to ensure that the `MAXAR_image_ortho` * extensions in the given glTF are valid * * @param path - The path for validation issues * @param gltfData - The glTF data, containing the parsed JSON and the * (optional) binary buffer * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static async validateGltf( path: string, gltfData: GltfData, context: ValidationContext ): Promise { const gltf = gltfData.gltf; // Check if the extension is used const extensionsUsed = gltf.extensionsUsed; if (!extensionsUsed || !extensionsUsed.includes("MAXAR_image_ortho")) { return true; // Extension not used, nothing to validate } let result = true; // Validate MAXAR_image_ortho extensions in images const images = gltf.images; if (defined(images)) { for (let i = 0; i < images.length; i++) { const image = images[i]; if ( defined(image.extensions) && defined(image.extensions.MAXAR_image_ortho) ) { const imagePath = path + "/images/" + i; const extensionPath = imagePath + "/extensions/MAXAR_image_ortho"; if ( !MaxarImageOrthoValidator.validateMaxarImageOrtho( extensionPath, image.extensions.MAXAR_image_ortho, context ) ) { result = false; } } } } return result; } /** * Validates a MAXAR_image_ortho extension object * * @param path - The path for ValidationIssue instances * @param maxarImageOrtho - The MAXAR_image_ortho object to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the object was valid */ static validateMaxarImageOrtho( path: string, maxarImageOrtho: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "MAXAR_image_ortho", maxarImageOrtho, context ) ) { return false; } let result = true; // Validate the transform property (optional) const transform = maxarImageOrtho.transform; if (defined(transform)) { const transformPath = path + "/transform"; if ( !MaxarImageOrthoValidator.validateTransform( transformPath, transform, context ) ) { result = false; } } // Validate the srs property (required) const srs = maxarImageOrtho.srs; const srsPath = path + "/srs"; if (!MaxarValidatorCommon.validateSrs(srsPath, srs, context)) { result = false; } return result; } /** * Validates the transform property * * @param path - The path for ValidationIssue instances * @param transform - The transform array to validate * @param context - The ValidationContext that any issues will be added to * @returns Whether the transform was valid */ static validateTransform( path: string, transform: any, context: ValidationContext ): boolean { // The transform MUST be an array with exactly 6 numbers const expectedLength = 6; const expectedElementType = "number"; return BasicValidator.validateArray( path, "transform", transform, expectedLength, expectedLength, expectedElementType, context ); } } ================================================ FILE: src/validation/gltf/instanceFeatures/ExtInstanceFeaturesValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { ValidatedElement } from "../../ValidatedElement"; import { GltfData } from "../GltfData"; import { FeatureIdValidator } from "../meshFeatures/FeatureIdValidator"; import { PropertyTableDefinitionValidator } from "../structuralMetadata/PropertyTableDefinitionValidator"; import { FeatureIdAccessorValidator } from "../meshFeatures/FeatureIdAccessorValidator"; import { GltfExtensionValidationIssues } from "../../../issues/GltfExtensionValidationIssues"; import { StructureValidationIssues } from "../../../issues/StructureValidationIssues"; /** * A class for validating the `EXT_instance_features` extension in * glTF assets. * * This class assumes that the structure of the glTF asset itself * has already been validated (e.g. with the glTF Validator). * * @internal */ export class ExtInstanceFeaturesValidator { /** * Performs the validation to ensure that the `EXT_instance_features` * extensions in the given glTF are valid * * @param path - The path for validation issues * @param gltfData - The glTF data, containing the parsed JSON and the * (optional) binary buffer * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static async validateGltf( path: string, gltfData: GltfData, context: ValidationContext ): Promise { const gltf = gltfData.gltf; // Dig into the (untyped) JSON representation of the // glTF, to find the nodes that carry the // EXT_instance_features extension const nodes = gltf.nodes; if (!nodes) { return true; } if (!Array.isArray(nodes)) { return true; } let result = true; for (let n = 0; n < nodes.length; n++) { const node = nodes[n]; const nodePath = path + `/nodes[${n}]`; const extensions = node.extensions; if (!extensions) { continue; } const instanceFeatures = extensions["EXT_instance_features"]; if (defined(instanceFeatures)) { const meshGpuInstancing = extensions["EXT_mesh_gpu_instancing"]; if (!defined(meshGpuInstancing)) { const message = `The node contains an 'EXT_instance_features' extension ` + `object, but no 'EXT_mesh_gpu_instancing' extension object`; const issue = GltfExtensionValidationIssues.INVALID_GLTF_STRUCTURE( nodePath, message ); context.addIssue(issue); result = false; } else { const objectIsValid = await ExtInstanceFeaturesValidator.validateExtInstanceFeatures( nodePath, instanceFeatures, meshGpuInstancing, gltfData, context ); if (!objectIsValid) { result = false; } } } } return result; } /** * Validate the given EXT_instance_features extension object that was * found in the given node * * This assumes that the given object has already been validated * to the extent that is checked by the `FeatureIdValidator`, * with the `validateCommonFeatureId` method. * * @param path - The path for validation issues * @param instanceFeatures - The EXT_instance_features extension object * @param meshGpuInstancing - The EXT_mesh_gpu_instancing extension object * @param gltfData - The glTF data * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static async validateExtInstanceFeatures( path: string, instanceFeatures: any, meshGpuInstancing: any, gltfData: GltfData, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "instanceFeatures", instanceFeatures, context ) ) { return false; } let result = true; // Validate the featureIds const featureIds = instanceFeatures.featureIds; const featureIdsPath = path + "/featureIds"; if (defined(featureIds)) { // The featureIds MUST be an array of at least 1 objects if ( !BasicValidator.validateArray( featureIdsPath, "featureIds", featureIds, 1, undefined, "object", context ) ) { result = false; } else { // Validate each featureId for (let i = 0; i < featureIds.length; i++) { const featureId = featureIds[i]; const featureIdPath = featureIdsPath + "/" + i; const commonFeatureIdValid = FeatureIdValidator.validateCommonFeatureId( featureIdPath, featureId, context ); if (!commonFeatureIdValid) { result = false; } else { const featureIdValid = await ExtInstanceFeaturesValidator.validateInstanceFeaturesFeatureId( featureIdPath, featureId, meshGpuInstancing, gltfData, context ); if (!featureIdValid) { result = false; } } } } } return result; } /** * Validate the given feature ID object that was found in the * `featureIds` array of an EXT_instance_features extension object * * @param path - The path for validation issues * @param featureId - The feature ID * @param meshGpuInstancing - The `EXT_mesh_gpu_instancing` extension object * that contains the attribute definitions * @param gltfData - The glTF data * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static async validateInstanceFeaturesFeatureId( path: string, featureId: any, meshGpuInstancing: any, gltfData: GltfData, context: ValidationContext ): Promise { // Validate the propertyTable const propertyTable = featureId.propertyTable; const propertyTablePath = path + "/propertyTable"; const propertyTableState = PropertyTableDefinitionValidator.validatePropertyTableDefinition( propertyTablePath, propertyTable, gltfData, context ); let result = true; const featureCount = featureId.featureCount; const nullFeatureId = featureId.nullFeatureId; // Validate the attribute const attribute = featureId.attribute; const attributePath = path + "/attribute"; if (defined(attribute)) { const attributeValid = ExtInstanceFeaturesValidator.validateFeatureIdAttribute( attributePath, attribute, featureCount, meshGpuInstancing, gltfData, propertyTableState, nullFeatureId, context ); if (!attributeValid) { result = false; } } return result; } /** * Validate the given feature ID `attribute` value that was found in * a feature ID definition * * @param path - The path for validation issues * @param attribute - The attribute (i.e. the supposed number that * will be used for the `_FEATURE_ID_${attribute}` attribute name) * @param featureCount - The `featureCount` value from the feature ID definition * @param meshGpuInstancing - The `EXT_mesh_gpu_instancing` extension object * that contains the attribute definitions * @param gltfData - The glTF data * @param propertyTableState - The validation state of the property table * definition (i.e. the index into the property tables array) * @param nullFeatureId - The `nullFeatureId` of the `featureId` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateFeatureIdAttribute( path: string, attribute: any, featureCount: number, meshGpuInstancing: any, gltfData: GltfData, propertyTableState: ValidatedElement<{ count: number }>, nullFeatureId: number | undefined, context: ValidationContext ): boolean { // Validate the attribute // The attribute MUST be an integer of at least 0 if ( !BasicValidator.validateIntegerRange( path, "attribute", attribute, 0, true, undefined, false, context ) ) { return false; } let result = true; // For a given attribute value, the attribute with the // name `_FEATURE_ID_${attribute}` must appear as an // attribute in the `EXT_mesh_gpu_instancing` attributes const featureIdAttributeName = `_FEATURE_ID_${attribute}`; const primitiveAttributes = meshGpuInstancing.attributes || {}; const featureIdAccessorIndex = primitiveAttributes[featureIdAttributeName]; if (featureIdAccessorIndex === undefined) { const message = `The feature ID defines the attribute ${attribute}, ` + `but the attribute ${featureIdAttributeName} was not ` + `found in the 'EXT_mesh_gpu_instancing' attributes`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else { const accessorValid = FeatureIdAccessorValidator.validateFeatureIdAccessor( path, featureIdAccessorIndex, featureCount, gltfData, propertyTableState, nullFeatureId, context ); if (!accessorValid) { result = false; } } return result; } } ================================================ FILE: src/validation/gltf/lightsPunctual/KhrLightsPunctualValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { GltfData } from "../GltfData"; import { GltfExtensionValidationIssues } from "../../../issues/GltfExtensionValidationIssues"; import { MaxarTemporalLightTraitsValidator } from "./MaxarTemporalLightTraits/MaxarTemporalLightTraitsValidator"; /** * A class for validating the `MAXAR_temporal_light_traits` extension * that extends `KHR_lights_punctual` lights in glTF assets. * * This validator only validates MAXAR_temporal_light_traits extensions * and assumes that KHR_lights_punctual structure validation is handled * by the glTF Validator. * * @internal */ export class KhrLightsPunctualValidator { /** * Performs the validation to ensure that the `MAXAR_temporal_light_traits` * extensions in KHR_lights_punctual lights are valid * * @param path - The path for validation issues * @param gltfData - The glTF data, containing the parsed JSON and the * (optional) binary buffer * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static async validateGltf( path: string, gltfData: GltfData, context: ValidationContext ): Promise { const gltf = gltfData.gltf; // Check if KHR_lights_punctual extension is used const extensionsUsed = gltf.extensionsUsed; if (!extensionsUsed || !extensionsUsed.includes("KHR_lights_punctual")) { return true; // Extension not used, nothing to validate } // Check if MAXAR_temporal_light_traits is also used const hasTemporalTraits = extensionsUsed.includes( "MAXAR_temporal_light_traits" ); let result = true; // Get the root extension to find lights array const rootExtensions = gltf.extensions; let lightsPunctual = undefined; if (defined(rootExtensions)) { lightsPunctual = rootExtensions["KHR_lights_punctual"]; } // Validate MAXAR_temporal_light_traits extensions in lights // We need to check all lights regardless of whether MAXAR_temporal_light_traits // is declared in extensionsUsed, to catch undeclared usage if (defined(lightsPunctual) && defined(lightsPunctual.lights)) { const lights = lightsPunctual.lights; for (let i = 0; i < lights.length; i++) { const light = lights[i]; const lightPath = path + "/extensions/KHR_lights_punctual/lights/" + i; if ( !KhrLightsPunctualValidator.validateLightTemporalTraits( lightPath, light, hasTemporalTraits, context ) ) { result = false; } } } return result; } /** * Validates MAXAR_temporal_light_traits extensions in a light object * * @param path - The path for validation issues * @param light - The light object * @param hasTemporalTraits - Whether MAXAR_temporal_light_traits extension is used * @param context - The validation context * @returns Whether the light temporal traits are valid */ private static validateLightTemporalTraits( path: string, light: any, hasTemporalTraits: boolean, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "light", light, context)) { return false; } let result = true; // Validate MAXAR_temporal_light_traits extension if present const extensions = light.extensions; if (defined(extensions)) { const temporalTraits = extensions["MAXAR_temporal_light_traits"]; if (defined(temporalTraits)) { if (!hasTemporalTraits) { const message = "MAXAR_temporal_light_traits extension is used but not declared in extensionsUsed"; const issue = GltfExtensionValidationIssues.INVALID_GLTF_STRUCTURE( path + "/extensions/MAXAR_temporal_light_traits", message ); context.addIssue(issue); result = false; } else { const temporalTraitsPath = path + "/extensions/MAXAR_temporal_light_traits"; if ( !MaxarTemporalLightTraitsValidator.validateTemporalLightTraits( temporalTraitsPath, temporalTraits, context ) ) { result = false; } } } } return result; } } ================================================ FILE: src/validation/gltf/lightsPunctual/MaxarTemporalLightTraits/MaxarTemporalLightTraitsValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../../../ValidationContext"; import { BasicValidator } from "../../../BasicValidator"; import { GltfExtensionValidationIssues } from "../../../../issues/GltfExtensionValidationIssues"; /** * A class for validating the `MAXAR_temporal_light_traits` extension * that extends `KHR_lights_punctual` lights. * * @internal */ export class MaxarTemporalLightTraitsValidator { /** * Validates the MAXAR_temporal_light_traits extension * * @param path - The path for validation issues * @param extension - The temporal light traits extension object * @param context - The validation context * @returns Whether the extension is valid */ static validateTemporalLightTraits( path: string, extension: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "MAXAR_temporal_light_traits", extension, context ) ) { return false; } let result = true; // Validate the flashing property (optional) const flashing = extension.flashing; if (defined(flashing)) { if ( !MaxarTemporalLightTraitsValidator.validateFlashing( path + "/flashing", flashing, context ) ) { result = false; } } return result; } /** * Validates a flashing trait object * * @param path - The path for validation issues * @param flashing - The flashing object * @param context - The validation context * @returns Whether the flashing trait is valid */ private static validateFlashing( path: string, flashing: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "flashing", flashing, context)) { return false; } let result = true; // Validate the waveform property (required) const waveform = flashing.waveform; const validWaveforms = ["sine", "square", "triangle"]; if ( !BasicValidator.validateEnum( path + "/waveform", "waveform", waveform, validWaveforms, context ) ) { result = false; } // Validate the frequency property (required) const frequency = flashing.frequency; if ( !BasicValidator.validateNumberRange( path + "/frequency", "frequency", frequency, 0.0, false, undefined, false, context ) ) { result = false; } // Validate the duty property (optional) const duty = flashing.duty; if (defined(duty)) { if ( !BasicValidator.validateNumberRange( path + "/duty", "duty", duty, 0.0, true, 1.0, true, context ) ) { result = false; } // Validate that duty is only used with square waveforms if (waveform !== "square") { const message = "The 'duty' property is only applicable for 'square' waveforms"; const issue = GltfExtensionValidationIssues.INVALID_GLTF_STRUCTURE( path + "/duty", message ); context.addIssue(issue); result = false; } } // Validate the amplitudeOffset property (optional) const amplitudeOffset = flashing.amplitudeOffset; if (defined(amplitudeOffset)) { if ( !BasicValidator.validateNumber( path + "/amplitudeOffset", "amplitudeOffset", amplitudeOffset, context ) ) { result = false; } } // Validate the amplitudeScale property (optional) const amplitudeScale = flashing.amplitudeScale; if (defined(amplitudeScale)) { if ( !BasicValidator.validateNumber( path + "/amplitudeScale", "amplitudeScale", amplitudeScale, context ) ) { result = false; } } // Validate the phaseOffset property (optional) const phaseOffset = flashing.phaseOffset; if (defined(phaseOffset)) { if ( !BasicValidator.validateNumber( path + "/phaseOffset", "phaseOffset", phaseOffset, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/gltf/meshFeatures/ExtMeshFeaturesValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { ValidatedElement } from "../../ValidatedElement"; import { GltfData } from "../GltfData"; import { ImageDataReader } from "../ImageDataReader"; import { SamplerValidator } from "../SamplerValidator"; import { TextureValidator } from "../TextureValidator"; import { FeatureIdValidator } from "./FeatureIdValidator"; import { FeatureIdAccessorValidator } from "./FeatureIdAccessorValidator"; import { PropertyTableDefinitionValidator } from "../structuralMetadata/PropertyTableDefinitionValidator"; import { StructureValidationIssues } from "../../../issues/StructureValidationIssues"; /** * A class for validating the `EXT_mesh_features` extension in * glTF assets. * * This class assumes that the structure of the glTF asset itself * has already been validated (e.g. with the glTF Validator). * * @internal */ export class ExtMeshFeaturesValidator { /** * Performs the validation to ensure that the `EXT_mesh_features` * extensions in the given glTF are valid * * @param path - The path for validation issues * @param gltfData - The glTF data, containing the parsed JSON and the * (optional) binary buffer * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static async validateGltf( path: string, gltfData: GltfData, context: ValidationContext ): Promise { const gltf = gltfData.gltf; // Dig into the (untyped) JSON representation of the // glTF, to find the mesh primitives that carry the // EXT_mesh_features extension const meshes = gltf.meshes; if (!meshes) { return true; } if (!Array.isArray(meshes)) { return true; } let result = true; for (const mesh of meshes) { const primitives = mesh.primitives; if (!primitives) { continue; } if (!Array.isArray(primitives)) { continue; } for (const primitive of primitives) { if (!primitive) { continue; } const extensions = primitive.extensions; if (!extensions) { continue; } const meshFeatures = extensions["EXT_mesh_features"]; if (defined(meshFeatures)) { const objectIsValid = await ExtMeshFeaturesValidator.validateExtMeshFeatures( path, meshFeatures, primitive, gltfData, context ); if (!objectIsValid) { result = false; } } } } return result; } /** * Validate the given EXT_mesh_features extension object that was * found in the given mesh primitive. * * @param path - The path for validation issues * @param meshFeatures - The EXT_mesh_features extension object * @param meshPrimitive - The mesh primitive that contains the extension * @param gltfData - The glTF data * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static async validateExtMeshFeatures( path: string, meshFeatures: any, meshPrimitive: any, gltfData: GltfData, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "meshFeatures", meshFeatures, context ) ) { return false; } let result = true; // Validate the featureIds const featureIds = meshFeatures.featureIds; const featureIdsPath = path + "/featureIds"; if (defined(featureIds)) { // The featureIds MUST be an array of at least 1 objects if ( !BasicValidator.validateArray( featureIdsPath, "featureIds", featureIds, 1, undefined, "object", context ) ) { result = false; } else { // Validate each featureId for (let i = 0; i < featureIds.length; i++) { const featureId = featureIds[i]; const featureIdPath = featureIdsPath + "/" + i; const commonFeatureIdValid = FeatureIdValidator.validateCommonFeatureId( featureIdPath, featureId, context ); if (!commonFeatureIdValid) { result = false; } else { const featureIdValid = await ExtMeshFeaturesValidator.validateMeshFeaturesFeatureId( featureIdPath, featureId, meshPrimitive, gltfData, context ); if (!featureIdValid) { result = false; } } } } } return result; } /** * Validate the given feature ID object that was found in the * `featureIds` array of an EXT_mesh_features extension object. * * This assumes that the given object has already been validated * to the extent that is checked by the `FeatureIdValidator`, * with the `validateCommonFeatureId` method. * * @param path - The path for validation issues * @param featureId - The feature ID * @param meshPrimitive - The mesh primitive that contains the extension * @param gltfData - The glTF data * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static async validateMeshFeaturesFeatureId( path: string, featureId: any, meshPrimitive: any, gltfData: GltfData, context: ValidationContext ): Promise { // Validate the propertyTable const propertyTable = featureId.propertyTable; const propertyTablePath = path + "/propertyTable"; const propertyTableState = PropertyTableDefinitionValidator.validatePropertyTableDefinition( propertyTablePath, propertyTable, gltfData, context ); let result = true; const featureCount = featureId.featureCount; const nullFeatureId = featureId.nullFeatureId; // Validate the attribute const attribute = featureId.attribute; const attributePath = path + "/attribute"; if (defined(attribute)) { const attributeValid = ExtMeshFeaturesValidator.validateFeatureIdAttribute( attributePath, attribute, featureCount, meshPrimitive, gltfData, propertyTableState, nullFeatureId, context ); if (!attributeValid) { result = false; } } // Validate the texture const texture = featureId.texture; const texturePath = path + "/texture"; if (defined(texture)) { const textureValid = await ExtMeshFeaturesValidator.validateFeatureIdTexture( texturePath, texture, featureCount, meshPrimitive, gltfData, propertyTableState, nullFeatureId, context ); if (!textureValid) { result = false; } } return result; } /** * Validate the given feature ID `attribute` value that was found in * a feature ID definition * * @param path - The path for validation issues * @param attribute - The attribute (i.e. the supposed number that * will be used for the `_FEATURE_ID_${attribute}` attribute name) * @param featureCount - The `featureCount` value from the feature ID definition * @param meshPrimitive - The mesh primitive that contains the extension * @param gltfData - The glTF data * @param propertyTableState - The validation state of the property table * definition (i.e. the index into the property tables array) * @param nullFeatureId - The `nullFeatureId` of the `featureId` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateFeatureIdAttribute( path: string, attribute: any, featureCount: number, meshPrimitive: any, gltfData: GltfData, propertyTableState: ValidatedElement<{ count: number }>, nullFeatureId: number | undefined, context: ValidationContext ): boolean { // Validate the attribute // The attribute MUST be an integer of at least 0 if ( !BasicValidator.validateIntegerRange( path, "attribute", attribute, 0, true, undefined, false, context ) ) { return false; } let result = true; // For a given attribute value, the attribute // with the name `_FEATURE_ID_${attribute}` must // appear as an attribute in the mesh primitive const featureIdAttributeName = `_FEATURE_ID_${attribute}`; const primitiveAttributes = meshPrimitive.attributes || {}; const featureIdAccessorIndex = primitiveAttributes[featureIdAttributeName]; if (featureIdAccessorIndex === undefined) { const message = `The feature ID defines the attribute ${attribute}, ` + `but the attribute ${featureIdAttributeName} was not ` + `found in the mesh primitive attributes`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else { const accessorValid = FeatureIdAccessorValidator.validateFeatureIdAccessor( path, featureIdAccessorIndex, featureCount, gltfData, propertyTableState, nullFeatureId, context ); if (!accessorValid) { result = false; } } return result; } /** * Validate the given feature ID `texture` value that was found in * a feature ID definition * * @param path - The path for validation issues * @param featureIdTexture - The feature ID texture definition * @param featureCount - The `featureCount` value from the feature ID definition * @param meshPrimitive - The mesh primitive that contains the extension * @param gltfData - The glTF data * @param propertyTableState - The validation state of the property table * definition (i.e. the index into the property tables array) * @param nullFeatureId - The `nullFeatureId` of the `featureId` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static async validateFeatureIdTexture( path: string, featureIdTexture: any, featureCount: number, meshPrimitive: any, gltfData: GltfData, propertyTableState: ValidatedElement<{ count: number }>, nullFeatureId: number | undefined, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject(path, "texture", featureIdTexture, context) ) { return false; } const gltf = gltfData.gltf; const textures = gltf.textures || []; const numTextures = textures.length; // Validate the index // The index MUST be defined // The index MUST be an integer in [0, numTextures) const index = featureIdTexture.index; const indexPath = path + "/index"; if ( !BasicValidator.validateIntegerRange( indexPath, "index", index, 0, true, numTextures, false, context ) ) { return false; } let result = true; // Validate the texCoord const texCoord = featureIdTexture.texCoord; const texCoordPath = path + "/texCoord"; if (defined(texCoord)) { if ( !TextureValidator.validateTexCoordForMeshPrimitive( texCoordPath, texCoord, meshPrimitive, context ) ) { result = false; } } // Validate the channels. // This will only check the basic validity, namely that the channels // (if they are defined) are an array of nonnegative integers. Whether // the channels match the image structure is validated later const channels = featureIdTexture.channels; if (!TextureValidator.validateChannels(path, channels, context)) { result = false; } // Make sure that the sampler of the texture (if present) uses the // allowed values (namely, 'undefined' or 9728 (NEAREST)) for // its minFilter and magFilter // (Note: The validity of the `texture.sampler` index has // already been checked by the glTF Validator) const texture = textures[index]; const samplerIndex = texture.sampler; if (samplerIndex !== undefined) { const samplers = gltf.samplers || []; const sampler = samplers[samplerIndex]; if (!SamplerValidator.validateSamplerNearest(path, sampler, context)) { result = false; } } // Only if the structures have been valid until now, // validate the actual data of the texture if (result) { const dataValid = await ExtMeshFeaturesValidator.validateFeatureIdTextureData( path, featureIdTexture, featureCount, gltfData, propertyTableState, nullFeatureId, context ); if (!dataValid) { result = false; } } return result; } /** * Validate the data of the given feature ID texture. * * This will try to read the image data, check whether it matches * the `channels` definition of the feature ID texture, and whether * the number of feature IDs (created from the respective channels * of the image pixels) actually matches the given `featureCount`. * * @param path - The path for validation issues * @param featureIdTexture - The feature ID texture * @param featureCount - The `featureCount` value from the feature ID definition * @param gltfData - The glTF data * @param propertyTableState - The validation state of the property table * definition (i.e. the index into the property tables array) * @param nullFeatureId - The `nullFeatureId` of the `featureId` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static async validateFeatureIdTextureData( path: string, featureIdTexture: any, featureCount: number, gltfData: GltfData, propertyTableState: ValidatedElement<{ count: number }>, nullFeatureId: number | undefined, context: ValidationContext ) { const gltf = gltfData.gltf; const textureIndex = featureIdTexture.index; const textures = gltf.textures || []; const texture = textures[textureIndex]; const images = gltf.images || []; const imageIndex = texture.source; const image = images[imageIndex]; // Try to read the image data from the glTF image. // If this fails, then the appropriate issues will // be added to the given context, and `undefined` // will be returned. const imageData = await ImageDataReader.readFromImage( path, image, gltfData.binaryBufferData, context ); if (!defined(imageData)) { return false; } // Make sure that the `channels` contains only elements that // are smaller than the number of channels in the image const channelsInImage = imageData.channels; const channels = defaultValue(featureIdTexture.channels, [0]); const channelsValid = TextureValidator.validateChannelsForImage( path, "feature ID texture", channels, channelsInImage, context ); if (!channelsValid) { return false; } // Collect the set of different values that appear in the texture const featureIdSet = new Set(); const sizeX = imageData.sizeX; const sizeY = imageData.sizeY; for (let y = 0; y < sizeY; y++) { for (let x = 0; x < sizeX; x++) { const value = ImageDataReader.getValue(imageData, x, y, channels); featureIdSet.add(value); } } // Validate the set of feature ID values if ( !FeatureIdValidator.validateFeatureIdSet( path, "texture", featureIdSet, featureCount, propertyTableState, nullFeatureId, context ) ) { return false; } return true; } } ================================================ FILE: src/validation/gltf/meshFeatures/FeatureIdAccessorValidator.ts ================================================ import { ValidationContext } from "../../ValidationContext"; import { ValidatedElement } from "../../ValidatedElement"; import { GltfData } from "../GltfData"; import { Accessors } from "../Accessors"; import { FeatureIdValidator } from "./FeatureIdValidator"; import { GltfExtensionValidationIssues } from "../../../issues/GltfExtensionValidationIssues"; import { ValidationIssues } from "../../../issues/ValidationIssues"; /** * Methods related to the validation of accessors that store * feature IDs, in the context of the `EXT_mesh_features` and * `EXT_instance_features` extensions. */ export class FeatureIdAccessorValidator { /** * Validate the given feature ID attribute accessor index that * was found in the mesh primitive attributes for the * `_FEATURE_ID_${attribute}` attribute. * * @param path - The path for validation issues * @param accessorIndex - The accessor index * @param featureCount - The `featureCount` value from the feature ID definition * @param gltfData - The glTF data * @param propertyTableState - The validation state of the property table * definition (i.e. the index into the property tables array) * @param nullFeatureId - The `nullFeatureId` of the `featureId` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateFeatureIdAccessor( path: string, accessorIndex: number, featureCount: number, gltfData: GltfData, propertyTableState: ValidatedElement<{ count: number }>, nullFeatureId: number | undefined, context: ValidationContext ): boolean { // The validity of the accessor index and the accessor // have already been checked by the glTF-Validator const gltf = gltfData.gltf; const accessors = gltf.accessors || []; const accessor = accessors[accessorIndex]; let result = true; // The accessor type must be "SCALAR" if (accessor.type !== "SCALAR") { const message = `The feature ID attribute accessor must have the type 'SCALAR', ` + `but has the type ${accessor.type}`; const issue = GltfExtensionValidationIssues.INVALID_GLTF_STRUCTURE( path, message ); context.addIssue(issue); result = false; } // The accessor must not be normalized if (accessor.normalized === true) { const message = `The feature ID attribute accessor may not be normalized`; const issue = GltfExtensionValidationIssues.INVALID_GLTF_STRUCTURE( path, message ); context.addIssue(issue); result = false; } // Only if the structures have been valid until now, // validate the actual data of the accessor if (result && gltfData.gltfDocument) { const dataValid = FeatureIdAccessorValidator.validateFeatureIdAccessorData( path, accessorIndex, featureCount, gltfData, propertyTableState, nullFeatureId, context ); if (!dataValid) { result = false; } } return result; } /** * Validate the data of the given feature ID attribute. * * This assumes that the glTF data is valid as determined by the * glTF Validator, **AND** as determined by the validation of * the JSON part of the extension. So this method should only * be called when no issues have been detected that may prevent * the validation of the accessor values. If this is called * with a `gltfData` object where the `gltfDocument` is * `undefined`, then an `INTERNAL_ERROR` will be caused. * * @param path - The path for validation issues * @param accessorIndex - The feature ID attribute accessor index * @param featureCount - The `featureCount` value from the feature ID definition * @param gltfData - The glTF data * @param propertyTableState - The validation state of the property table * definition (i.e. the index into the property tables array) * @param nullFeatureId - The `nullFeatureId` of the `featureId` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateFeatureIdAccessorData( path: string, accessorIndex: number, featureCount: number, gltfData: GltfData, propertyTableState: ValidatedElement<{ count: number }>, nullFeatureId: number | undefined, context: ValidationContext ): boolean { const accessorValues = Accessors.readScalarAccessorValues( accessorIndex, gltfData ); if (!accessorValues) { // This should only happen for invalid glTF assets (e.g. ones that // use wrong accessor component types), or when the gltfDocument // could not be read due to another structural error that should // be detected by the extension validation. const message = `Could not read data for feature ID attribute accessor`; const issue = ValidationIssues.INTERNAL_ERROR(path, message); context.addIssue(issue); return false; } // Validate the set of feature ID values const featureIdSet = new Set(accessorValues); if ( !FeatureIdValidator.validateFeatureIdSet( path, "attribute", featureIdSet, featureCount, propertyTableState, nullFeatureId, context ) ) { return false; } return true; } } ================================================ FILE: src/validation/gltf/meshFeatures/FeatureIdValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { ValidatedElement } from "../../ValidatedElement"; import { BasicValidator } from "../../BasicValidator"; import { StringValidator } from "../../StringValidator"; import { GltfData } from "../GltfData"; import { GltfExtensionValidationIssues } from "../../../issues/GltfExtensionValidationIssues"; import { JsonValidationIssues } from "../../../issues/JsonValidationIssues"; /** * A class for validation functionality related to feature IDs, as they * appear in the `EXT_mesh_features` and `EXT_instance_features` * extensions. * * @internal */ export class FeatureIdValidator { /** * Validate the common elements of a feature ID object. * * This refers to `featureId` objects that are found in the * `EXT_mesh_features` and `EXT_instance_features` extension * objects. * * It ensures that... * - the value being an object * - the nullFeatureId (if present) being valid * - the label (if present) being valid * - the featureCount being present and valid * * It does NOT validate the `texture` or `attribute` properties * that may be found in the object, depending on whether it is * part of the `EXT_mesh_features` or `EXT_instance_features` * extension object. * * @param path - The path for validation issues * @param featureId - The feature ID * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateCommonFeatureId( path: string, featureId: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "featureId", featureId, context)) { return false; } let result = true; // Validate the nullFeatureId // The nullFeatureId MUST be an integer of at least 0 const nullFeatureId = featureId.nullFeatureId; const nullFeatureIdPath = path + "/nullFeatureId"; if (defined(nullFeatureId)) { if ( !BasicValidator.validateIntegerRange( nullFeatureIdPath, "nullFeatureId", nullFeatureId, 0, true, undefined, false, context ) ) { result = false; } } // Validate the label // The label MUST be a string // The label MUST match the ID regex const label = featureId.label; const labelPath = path + "/label"; if (defined(label)) { if (!BasicValidator.validateString(labelPath, "label", label, context)) { result = false; } else { if ( !StringValidator.validateIdentifierString( labelPath, "label", label, context ) ) { result = false; } } } // Validate the featureCount // The featureCount MUST be defined // The featureCount MUST be an integer of at least 1 const featureCount = featureId.featureCount; const featureCountPath = path + "/featureCount"; if ( !BasicValidator.validateIntegerRange( featureCountPath, "featureCount", featureCount, 1, true, undefined, false, context ) ) { result = false; } return result; } /** * Validate the given set of feature ID values that have either * been found in an feature ID texture or in a feature ID attribute. * * This will check the validity of the 'featureCount' for the * given set of features, depending on the presence of the * 'nullFeatureId', and whether the feature IDs are valid * indices into a property table (if the property table count * was given) * * @param path - The path for validation issues * @param sourceName - The source, 'texture' or 'attribute' * @param featureIdSet - The feature ID set. Note that This set * might be modified by this method! * @param featureCount - The `featureCount` value from the feature ID definition * @param propertyTableState - The validation state of the property table * definition (i.e. the index into the property tables array) * @param nullFeatureId - The `nullFeatureId` of the `featureId` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateFeatureIdSet( path: string, sourceName: string, featureIdSet: Set, featureCount: number, propertyTableState: ValidatedElement<{ count: number }>, nullFeatureId: number | undefined, context: ValidationContext ) { // Make sure that the actual number of different values that appear // in the source (excluding the nullFeatureId, if it was defined) // is not larger than the `featureCount` if (defined(nullFeatureId)) { featureIdSet.delete(nullFeatureId); if (featureIdSet.size > featureCount) { const message = `The featureID ${sourceName} contains ${featureIdSet.size} different values ` + `(excluding the nullFeatureId value), but the featureCount was ${featureCount}`; const issue = GltfExtensionValidationIssues.FEATURE_COUNT_MISMATCH( path, message ); context.addIssue(issue); return false; } } else { if (featureIdSet.size > featureCount) { const message = `The feature ID ${sourceName} contains ${featureIdSet.size} different values ` + `but the featureCount was ${featureCount}`; const issue = GltfExtensionValidationIssues.FEATURE_COUNT_MISMATCH( path, message ); context.addIssue(issue); return false; } } // If the feature ID refers to a property table, then make // sure that it only contains feature ID values that are in // the range [0, propertyTable.count) if ( propertyTableState.wasPresent && propertyTableState.validatedElement !== undefined ) { const propertyTableCount = propertyTableState.validatedElement.count; const featureIdValues = [...featureIdSet]; const maximumFeatureId = Math.max(...featureIdValues); const minimumFeatureId = Math.min(...featureIdValues); if (minimumFeatureId < 0 || maximumFeatureId >= propertyTableCount) { const message = `The feature ID refers to a property table with ${propertyTableCount} ` + `rows, so the feature IDs must be in the range ` + `[0,${propertyTableCount - 1}], but the feature ID ${sourceName} ` + `contains values in [${minimumFeatureId},${maximumFeatureId}]`; const issue = JsonValidationIssues.VALUE_NOT_IN_RANGE(path, message); context.addIssue(issue); return false; } } return true; } /** * Obtain the `count` of the property table that is referred to * with the given index. * * This assumes that the validity of this index has already been * checked with `validateFeatureIdPropertyTable`. If any * element that leads to the `count` is invalid or not defined, * then `undefined` will be returned. * * @param propertyTableIndex - The value that was found as the `propertyTable` * in the definition, indicating the index into the property tables array * @param gltfData - The glTF data * @returns The `count` of the property table */ static obtainPropertyTableCount( propertyTableIndex: number, gltfData: GltfData ): number | undefined { const gltf = gltfData.gltf; const extensions = gltf.extensions || {}; const structuralMetadata = extensions["EXT_structural_metadata"] || {}; const propertyTables = structuralMetadata.propertyTables; if (!propertyTables || propertyTableIndex >= propertyTables.length) { return undefined; } const propertyTable = propertyTables[propertyTableIndex]; const count = propertyTable.count; return count; } } ================================================ FILE: src/validation/gltf/nonvisualGeometry/MaxarNonvisualGeometryValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { GltfData } from "../GltfData"; import { GltfExtensionValidationIssues } from "../../../issues/GltfExtensionValidationIssues"; /** * A class for validating the `MAXAR_nonvisual_geometry` extension in * glTF assets. * * This class assumes that the structure of the glTF asset itself * has already been validated (e.g. with the glTF Validator). * * @internal */ export class MaxarNonvisualGeometryValidator { /** * Performs the validation to ensure that the `MAXAR_nonvisual_geometry` * extensions in the given glTF are valid * * @param path - The path for validation issues * @param gltfData - The glTF data, containing the parsed JSON and the * (optional) binary buffer * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static async validateGltf( path: string, gltfData: GltfData, context: ValidationContext ): Promise { const gltf = gltfData.gltf; let result = true; // Validate node extensions const nodes = gltf.nodes || []; for (let n = 0; n < nodes.length; n++) { const node = nodes[n]; if (!node) { continue; } const extensions = node.extensions; if (!extensions) { continue; } const nonvisualGeometry = extensions["MAXAR_nonvisual_geometry"]; if (defined(nonvisualGeometry)) { const nodePath = path + "/nodes/" + n + "/extensions/MAXAR_nonvisual_geometry"; const objectIsValid = MaxarNonvisualGeometryValidator.validateNodeExtension( nodePath, nonvisualGeometry, gltf, context ); if (!objectIsValid) { result = false; } } } // Validate mesh primitive extensions const meshes = gltf.meshes || []; for (let m = 0; m < meshes.length; m++) { const mesh = meshes[m]; if (!mesh) { continue; } const primitives = mesh.primitives; if (!primitives || !Array.isArray(primitives)) { continue; } for (let p = 0; p < primitives.length; p++) { const primitive = primitives[p]; if (!primitive) { continue; } const extensions = primitive.extensions; if (!extensions) { continue; } const nonvisualGeometry = extensions["MAXAR_nonvisual_geometry"]; if (defined(nonvisualGeometry)) { const primitivePath = path + "/meshes/" + m + "/primitives/" + p + "/extensions/MAXAR_nonvisual_geometry"; const objectIsValid = MaxarNonvisualGeometryValidator.validatePrimitiveExtension( primitivePath, nonvisualGeometry, primitive, context ); if (!objectIsValid) { result = false; } } } } return result; } /** * Validate the given MAXAR_nonvisual_geometry extension object that was * found in a glTF node. * * @param path - The path for validation issues * @param nodeExtension - The MAXAR_nonvisual_geometry extension object * @param gltf - The glTF root object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validateNodeExtension( path: string, nodeExtension: any, gltf: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "nodeExtension", nodeExtension, context ) ) { return false; } let result = true; // Validate the mesh property const mesh = nodeExtension.mesh; const meshPath = path + "/mesh"; const meshes = gltf.meshes || []; // The mesh must be a valid glTF ID (non-negative integer) if ( !BasicValidator.validateIntegerRange( meshPath, "mesh", mesh, 0, true, meshes.length, false, context ) ) { result = false; } return result; } /** * Validate the given MAXAR_nonvisual_geometry extension object that was * found in a mesh primitive. * * @param path - The path for validation issues * @param primitiveExtension - The MAXAR_nonvisual_geometry extension object * @param primitive - The mesh primitive that contains the extension * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validatePrimitiveExtension( path: string, primitiveExtension: any, primitive: any, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "primitiveExtension", primitiveExtension, context ) ) { return false; } let result = true; // Validate the shape property const shape = primitiveExtension.shape; const shapePath = path + "/shape"; // The shape must be one of the allowed enum values const allowedShapes = ["points", "path", "surface", "volume"]; if ( !BasicValidator.validateEnum( shapePath, "shape", shape, allowedShapes, context ) ) { result = false; } else { // Validate shape-to-primitive-mode compatibility const shapeCompatibilityValid = MaxarNonvisualGeometryValidator.validateShapeCompatibility( path, shape, primitive, context ); if (!shapeCompatibilityValid) { result = false; } } // Validate the type property const type = primitiveExtension.type; const typePath = path + "/type"; // The type property is required and must be a non-empty string if ( !BasicValidator.validateStringLength( typePath, "type", type, 1, undefined, context ) ) { result = false; } return result; } /** * Validate that the shape is compatible with the primitive mode. * * @param path - The path for validation issues * @param shape - The shape value from the extension * @param primitive - The mesh primitive * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the shape is compatible with the primitive mode */ private static validateShapeCompatibility( path: string, shape: string, primitive: any, context: ValidationContext ): boolean { const mode = primitive.mode !== undefined ? primitive.mode : 4; // Default to TRIANGLES (4) let allowedModes: number[] = []; let shapeDescription = ""; switch (shape) { case "points": allowedModes = [0]; // POINTS shapeDescription = "Points shape requires primitive mode 0 (POINTS)"; break; case "path": allowedModes = [1, 2, 3]; // LINES, LINE_LOOP, LINE_STRIP shapeDescription = "Path shape requires primitive mode 1 (LINES), 2 (LINE_LOOP), or 3 (LINE_STRIP)"; break; case "surface": allowedModes = [4, 5, 6]; // TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN shapeDescription = "Surface shape requires primitive mode 4 (TRIANGLES), 5 (TRIANGLE_STRIP), or 6 (TRIANGLE_FAN)"; break; case "volume": allowedModes = [4, 5]; // TRIANGLES, TRIANGLE_STRIP shapeDescription = "Volume shape requires primitive mode 4 (TRIANGLES) or 5 (TRIANGLE_STRIP)"; break; } if (!allowedModes.includes(mode)) { const message = `Shape '${shape}' is not compatible with primitive mode ${mode}. ` + shapeDescription; const issue = GltfExtensionValidationIssues.INVALID_GLTF_STRUCTURE( path, message ); context.addIssue(issue); return false; } return true; } } ================================================ FILE: src/validation/gltf/structuralMetadata/ExtStructuralMetadataValidator.ts ================================================ import { BinaryBufferStructure, BinaryMetadata, BinaryPropertyTable, MetadataUtilities, Schema, defined, } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { ValidatedElement } from "../../ValidatedElement"; import { GltfData } from "../GltfData"; import { PropertyTexturesDefinitionValidator } from "./PropertyTexturesDefinitionValidator"; import { PropertyAttributesDefinitionValidator } from "./PropertyAttributesDefinitionValidator"; import { PropertyTextureValuesValidator } from "./PropertyTextureValuesValidator"; import { SchemaDefinitionValidator } from "../../metadata/SchemaDefinitionValidator"; import { PropertyTablesDefinitionValidator } from "../../metadata/PropertyTablesDefinitionValidator"; import { GltfExtensionValidationIssues } from "../../../issues/GltfExtensionValidationIssues"; import { JsonValidationIssues } from "../../../issues/JsonValidationIssues"; import { PropertyAttributeValuesValidator } from "./PropertyAttributeValuesValidator"; import { BinaryPropertyTableValidator } from "../../metadata/BinaryPropertyTableValidator"; /** * A class for validating the `EXT_structural_metadata` extension in * glTF assets. * * This class assumes that the structure of the glTF asset itself * has already been validated (e.g. with the glTF Validator). * * @internal */ export class ExtStructuralMetadataValidator { /** * Performs the validation to ensure that the `EXT_structural_metadata` * extensions in the given glTF are valid * * @param path - The path for validation issues * @param gltfData - The glTF data, containing the parsed JSON and the * (optional) binary buffer * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static async validateGltf( path: string, gltfData: GltfData, context: ValidationContext ): Promise { let result = true; // Try to find and validate the top-level extension object. let schema = undefined; let gltfStructuralMetadata = undefined; const gltf = gltfData.gltf; const extensions = gltf.extensions; if (extensions) { const structuralMetadata = extensions["EXT_structural_metadata"]; if (structuralMetadata) { // Validate the schema definition, consisting of the // `schema` or `schemaUri` const schemaState = await SchemaDefinitionValidator.validateSchemaDefinition( path, "structuralMetadata", structuralMetadata.schema, structuralMetadata.schemaUri, context ); // The schema or schemaUri MUST be present if (!schemaState.wasPresent) { const issue = JsonValidationIssues.ANY_OF_ERROR( path, "structuralMetadata", "schema", "schemaUri" ); context.addIssue(issue); return false; } // Bail out early if there was a schema definition, but the schema // itself was not valid if (schemaState.wasPresent && !defined(schemaState.validatedElement)) { return false; } const structuralMetadataValid = await ExtStructuralMetadataValidator.validateTopLevelStructuralMetadata( path, structuralMetadata, schemaState, gltfData, context ); // Bail out early if the top-level extension object is invalid. if (!structuralMetadataValid) { return false; } gltfStructuralMetadata = structuralMetadata; schema = schemaState.validatedElement; } } // Dive into the mesh primitives of the glTF, and check if they // contain EXT_structural_metadata extension objects const meshes = gltf.meshes; if (meshes) { if (Array.isArray(meshes)) { for (let m = 0; m < meshes.length; m++) { const mesh = meshes[m]; const primitives = mesh.primitives; if (!primitives) { continue; } if (!Array.isArray(primitives)) { continue; } for (let p = 0; p < primitives.length; p++) { const primitive = primitives[p]; if (!primitive) { continue; } const extensions = primitive.extensions; if (!extensions) { continue; } const extensionObject = extensions["EXT_structural_metadata"]; if (defined(extensionObject)) { // When there is an extension object in one of the mesh // primitives, and there was no top-level extension object, // then bail out: There is no need to report the missing // top-level object multiple times. if (!defined(gltfStructuralMetadata)) { const message = `The primitive ${p} of mesh ${m} uses the ` + `EXT_structural_metadata extension, but ` + `no top-level EXT_structural_metadata ` + `object was found.`; const issue = GltfExtensionValidationIssues.INVALID_GLTF_STRUCTURE( path, message ); context.addIssue(issue); return false; } // Here, the `gltfStructuralMetadata` and the `schema` // have been validated const objectIsValid = await ExtStructuralMetadataValidator.validateMeshPrimitiveStructuralMetadata( path, extensionObject, primitive, m, p, schema!, gltfStructuralMetadata, gltfData, context ); if (!objectIsValid) { result = false; } } } } } } return result; } /** * Validate the given top-level EXT_structural_metadata extension object * that was found in the given glTF. * * @param path - The path for validation issues * @param structuralMetadata - The EXT_structural_metadata extension object * @param schemaState - The object holding information about the presence * and validity of the schema * @param gltfData - The glTF data * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static async validateTopLevelStructuralMetadata( path: string, structuralMetadata: any, schemaState: ValidatedElement, gltfData: GltfData, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "structuralMetadata", structuralMetadata, context ) ) { return false; } let result = true; const gltf = gltfData.gltf; const numBufferViews = defaultValue(gltf.bufferViews?.length, 0); // Validate the property tables definition const propertyTablesState = PropertyTablesDefinitionValidator.validatePropertyTablesDefinition( path, "structuralMetadata", structuralMetadata.propertyTables, numBufferViews, schemaState, context ); // When there was a property tables definition, but the // property tables are not valid, then the overall result // is invalid if ( propertyTablesState.wasPresent && !defined(propertyTablesState.validatedElement) ) { result = false; } else { // When there was a property table, and it was structurally // valid, then validate the VALUES of the property tables if (defined(schemaState.validatedElement)) { const schema = schemaState.validatedElement; const valuesValid = ExtStructuralMetadataValidator.validatePropertyTablesValues( path, structuralMetadata.propertyTables, schema, gltfData, context ); if (!valuesValid) { result = false; } } } // Validate the property textures definition const propertyTexturesState = PropertyTexturesDefinitionValidator.validatePropertyTexturesDefinition( path, "structuralMetadata", structuralMetadata.propertyTextures, gltf, schemaState, context ); // When there was a property textures definition, but the // property textures are not valid, then the overall result // is invalid if ( propertyTexturesState.wasPresent && !defined(propertyTexturesState.validatedElement) ) { result = false; } // Validate the property attributes definition const propertyAttributesState = PropertyAttributesDefinitionValidator.validatePropertyAttributesDefinition( path, "structuralMetadata", structuralMetadata.propertyAttributes, schemaState, context ); // When there was a property attributes definition, but the // property attributes are not valid, then the overall result // is invalid if ( propertyAttributesState.wasPresent && !defined(propertyAttributesState.validatedElement) ) { result = false; } return result; } /** * Validate the given EXT_structural_metadata extension object * that was found in the given mesh primitive. * * @param path - The path for validation issues * @param meshPrimitiveStructuralMetadata - The EXT_mesh_features * extension object that was found in the mesh primitive * @param meshPrimitive - The mesh primitive that contained * the extension object * @param meshIndex - The index of the mesh (only for details * in validation messages) * @param primitiveIndex - The index of the primitive (only for details * in validation messages) * @param schema - The metadata schema * @param gltfStructuralMetadata - The EXT_mesh_features object * that was found at the top level in the glTF asset * @param gltfData - The glTF data * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static async validateMeshPrimitiveStructuralMetadata( path: string, meshPrimitiveStructuralMetadata: any, meshPrimitive: any, meshIndex: number, primitiveIndex: number, schema: Schema, gltfStructuralMetadata: any, gltfData: GltfData, context: ValidationContext ): Promise { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "structuralMetadata", meshPrimitiveStructuralMetadata, context ) ) { return false; } let result = true; // Validate the propertyTextures const numPropertyTextures = gltfStructuralMetadata.propertyTextures?.length ?? 0; const propertyTextures = meshPrimitiveStructuralMetadata.propertyTextures; const propertyTexturesPath = path + "/propertyTextures"; if (defined(propertyTextures)) { // The propertyTextures MUST be an an array of at least 1 index if ( !BasicValidator.validateIndexArray( propertyTexturesPath, "propertyTextures", propertyTextures, numPropertyTextures, context ) ) { result = false; } else { for (let i = 0; i < propertyTextures.length; i++) { const propertyTexturePath = propertyTexturesPath + "/" + i; const propertyTextureIndex = propertyTextures[i]; const propertyTextureValuesValid = await PropertyTextureValuesValidator.validatePropertyTextureValues( propertyTexturePath, propertyTextureIndex, meshPrimitive, meshIndex, primitiveIndex, schema, gltfStructuralMetadata, gltfData, context ); if (!propertyTextureValuesValid) { result = false; } } } } // Validate the propertyAttributes const numPropertyAttributes = gltfStructuralMetadata.propertyAttributes?.length ?? 0; const propertyAttributes = meshPrimitiveStructuralMetadata.propertyAttributes; const propertyAttributesPath = path + "/propertyAttributes"; if (defined(propertyAttributes)) { // The propertyAttributes MUST be an an array of at least 1 index if ( !BasicValidator.validateIndexArray( propertyAttributesPath, "propertyAttributes", propertyAttributes, numPropertyAttributes, context ) ) { result = false; } else { for (let i = 0; i < propertyAttributes.length; i++) { const propertyAttributePath = propertyAttributesPath + "/" + i; const propertyAttributeIndex = propertyAttributes[i]; const propertyAttributeValuesValid = await PropertyAttributeValuesValidator.validatePropertyAttributeValues( propertyAttributePath, propertyAttributeIndex, meshPrimitive, meshIndex, primitiveIndex, schema, gltfStructuralMetadata, gltfData, context ); if (!propertyAttributeValuesValid) { result = false; } } } } return result; } /** * Validate the values that are stored in property tables. * * This assumes that the structural validity of the schema and the * property table JSON objects has already been verified, as of * PropertyTablesDefinitionValidator.validatePropertyTablesDefinition. * * If will obtain the actual metadata values from the buffer views * that are defined in the glTF and referred to by the property tables * (i.e. the values, arrayOffsets, and stringOffsets). This is done * by BinaryPropertyTableValidator.validateBinaryPropertyTable. * * @param path - The path for validation issues * @param structuralMetadataPropertyTables - The propertyTables array * that has been obtained from the top-level structural metadata object * @param schema - The metadata schema * @param gltfData - The glTF data that contained the structural metadata * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ private static validatePropertyTablesValues( path: string, structuralMetadataPropertyTables: any, schema: Schema, gltfData: GltfData, context: ValidationContext ): boolean { let result = true; // Define the binary buffer structure that will be used // for creating the BinaryPropertyTable. Here, the required // buffers and buffer views are sourced from the glTF. const gltf = gltfData.gltf; const binaryBufferStructure: BinaryBufferStructure = { buffers: gltf.buffers, bufferViews: gltf.bufferViews, }; const binaryBufferData = gltfData.binaryBufferData; // Obtain the structural information about the schema // that is required for validating each property table const classes = defaultValue(schema.classes, {}); const binaryEnumInfo = MetadataUtilities.computeBinaryEnumInfo(schema); const propertyTables = defaultValue(structuralMetadataPropertyTables, []); for (const propertyTable of propertyTables) { const classId = propertyTable.class; const metadataClass = classes[classId]; // Create the `BinaryPropertyTable` for each property table, // which contains everything that is required for the // validation of the binary representation of the // property table const binaryMetadata: BinaryMetadata = { metadataClass: metadataClass, binaryEnumInfo: binaryEnumInfo, binaryBufferStructure: binaryBufferStructure, binaryBufferData: binaryBufferData, }; const binaryPropertyTable: BinaryPropertyTable = { propertyTable: propertyTable, binaryMetadata: binaryMetadata, }; if ( !BinaryPropertyTableValidator.validateBinaryPropertyTable( path, binaryPropertyTable, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyAttributePropertyModel.ts ================================================ import { ClassProperty } from "3d-tiles-tools"; import { MetadataValues } from "3d-tiles-tools"; import { MetadataPropertyModel } from "../../metadata/MetadataPropertyModel"; /** * Implementation of a metadata property model for a * property attribute property, backed by glTF accessor * data. */ export class PropertyAttributePropertyModel implements MetadataPropertyModel { /** * The data that was obtained from the accessor, in its * original form (i.e. including the normalization that * may be part of the accessor itself, but without * the offset/scale that may be part of the attribute * definition) */ private readonly accessorData: number[] | number[][]; /** * The property attribute property that is represented by this model */ private readonly propertyAttributeProperty: any; /** * The class property that defines the structure of the property */ private readonly classProperty: ClassProperty; /** * Creates a new instance * * @param accessorData - The accessor data * @param propertyAttributeProperty - The property attribute property * @param classProperty - The class property */ constructor( accessorData: number[] | number[][], propertyAttributeProperty: any, classProperty: ClassProperty ) { this.accessorData = accessorData; this.propertyAttributeProperty = propertyAttributeProperty; this.classProperty = classProperty; } /** {@inheritDoc MetadataPropertyModel.getPropertyValue} */ getPropertyValue(index: number): number | number[] { const propertyAttributeProperty = this.propertyAttributeProperty; const classProperty = this.classProperty; const offsetOverride = propertyAttributeProperty.offset; const scaleOverride = propertyAttributeProperty.scale; const value = this.getRawPropertyValue(index); const processedValue = MetadataValues.processValue( classProperty, offsetOverride, scaleOverride, value ); return processedValue; } /** {@inheritDoc MetadataPropertyModel.getRawPropertyValue} */ getRawPropertyValue(index: number): number | number[] { const accessorData = this.accessorData; return accessorData[index]; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyAttributePropertyValidator.ts ================================================ import { ClassProperties, ClassProperty, defined } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { MetadataPropertyValidator } from "../../metadata/MetadataPropertyValidator"; import { GltfExtensionValidationIssues } from "../../../issues/GltfExtensionValidationIssues"; /** * A class for validations related to `propertyAttribute.property` objects. * * @internal */ export class PropertyAttributePropertyValidator { /** * Performs the validation to ensure that the given object is a * valid `propertyAttribute.property` object. * * @param path - The path for the `ValidationIssue` instances * @param propertyName - The name of the property * @param propertyAttributeProperty - The object to validate * @param classProperty - The `ClassProperty` definition from the schema * @param enumValueType - The `valueType` of the enum, if the class * property is an ENUM type * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validatePropertyAttributeProperty( path: string, propertyName: string, propertyAttributeProperty: any, classProperty: ClassProperty, enumValueType: string | undefined, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, propertyName, propertyAttributeProperty, context ) ) { return false; } // Validate the attribute // The attribute MUST be defined // The attribute MUST be a string const attribute = propertyAttributeProperty.attribute; const attributePath = path + "/attribute"; if ( !BasicValidator.validateString( attributePath, "attribute", attribute, context ) ) { return false; } let result = true; // Make sure that the type of the class property is valid for // a property attribute in general. const typeIsValid = PropertyAttributePropertyValidator.validateClassPropertyForPropertyAttributeProperty( path, propertyName, classProperty, enumValueType, context ); if (!typeIsValid) { result = false; } // Validate the offset/scale/max/min properties const elementsAreValid = MetadataPropertyValidator.validateOffsetScaleMaxMin( path, propertyAttributeProperty, propertyName, classProperty, context ); if (!elementsAreValid) { result = false; } return result; } /** * Validates that the given `classProperty` is basically suitable * for a property attribute, meaning that its type is one of the * types that can be represented with a glTF vertex attribute. * * If the type is not valid, then a validation error will be added * to the given context, and `false` will be returned. * * @param path - The path for the `ValidationIssue` instances * @param propertyName - The name of the property * @param classProperty - The `ClassProperty` definition from the schema * @param enumValueType - The `valueType` of the enum, if the class * property is an ENUM type * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateClassPropertyForPropertyAttributeProperty( path: string, propertyName: string, classProperty: ClassProperty, enumValueType: string | undefined, context: ValidationContext ): boolean { // The specification says // > The property types that are supported via property attributes are // > therefore restricted to the types that are supported by standard // > glTF accessors. // glTF accessors cannot represent arrays if (classProperty.array === true) { const message = `The property '${propertyName}' is an array, ` + `which is not supported for property attributes`; const issue = GltfExtensionValidationIssues.INVALID_METADATA_PROPERTY_TYPE( path, message ); context.addIssue(issue); return false; } // glTF accessors cannot represent STRING or BOOLEAN const type = classProperty.type; if (type === "STRING" || type === "BOOLEAN") { const message = `The property '${propertyName}' has the type ${type}, ` + `which is not supported for property attributes`; const issue = GltfExtensionValidationIssues.INVALID_METADATA_PROPERTY_TYPE( path, message ); context.addIssue(issue); return false; } // glTF accessors can only represent certain component // types for numeric (SCALAR, VECn, and MATn) types if (ClassProperties.hasNumericType(classProperty)) { const componentType = classProperty.componentType!; const validComponentTypes = [ "INT8", "UINT8", "INT16", "UINT16", "FLOAT32", ]; if (!validComponentTypes.includes(componentType)) { const message = `The property '${propertyName}' has the component ` + `type ${componentType}, but the type must be ` + `one of ${validComponentTypes} for property attributes`; const issue = GltfExtensionValidationIssues.INVALID_METADATA_PROPERTY_TYPE( path, message ); context.addIssue(issue); return false; } } // glTF accessors can only represent certain ENUM value types if (defined(enumValueType)) { // The enum valueType can be one of these types (i.e. // it can not be INT32, UINT32, INT64, or UINT64) const validEnumValueTypes = ["INT8", "UINT8", "INT16", "UINT16"]; if (!validEnumValueTypes.includes(enumValueType)) { const message = `The property '${propertyName}' has the type 'ENUM', with ` + `the enum type '${classProperty.enumType}', which has a ` + `value type of ${enumValueType}, but the type must be ` + `one of ${validEnumValueTypes} for property attributes`; const issue = GltfExtensionValidationIssues.INVALID_METADATA_PROPERTY_TYPE( path, message ); context.addIssue(issue); return false; } } return true; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyAttributeValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { RootPropertyValidator } from "../../RootPropertyValidator"; import { ExtendedObjectsValidators } from "../../ExtendedObjectsValidators"; import { MetadataStructureValidator } from "../../metadata/MetadataStructureValidator"; import { PropertyAttributePropertyValidator } from "./PropertyAttributePropertyValidator"; /** * A class for validations related to `propertyAttribute` objects. * * This class performs the basic JSON-level validation of the * property attributes. * * The validation of any of the underlying binary data of * a property attribute has to start at the mesh primitive * that refers to the property attribute, because it requires * knowledge about the attributes that are defined in the * referring mesh primitive. * * @internal */ export class PropertyAttributeValidator { /** * Performs the validation to ensure that the given object is a * valid `propertyAttribute` object. * * @param path - The path for the `ValidationIssue` instances * @param propertyAttribute - The object to validate * @param schema - The `Schema` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validatePropertyAttribute( path: string, propertyAttribute: any, schema: Schema, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "propertyAttribute", propertyAttribute, context ) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, "propertyAttribute", propertyAttribute, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( path, propertyAttribute, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(propertyAttribute)) { return result; } // Validate that the class and properties are structurally // valid and comply to the metadata schema const className = propertyAttribute.class; const attributeProperties = propertyAttribute.properties; if ( !MetadataStructureValidator.validateMetadataStructure( path, "property attribute", className, attributeProperties, schema, context ) ) { // Bail out early if the structure is not valid! return false; } // Validate the name. // If the name is defined, it MUST be a string. if ( !BasicValidator.validateOptionalString( path, propertyAttribute, "name", context ) ) { result = false; } // Here, the basic structure of the class and properties // have been determined to be valid. Continue to validate // the values of the properties. const validProperties = defaultValue(attributeProperties, {}); const validPropertyNames = Object.keys(validProperties); const classes = defaultValue(schema.classes, {}); const metadataClass = classes[className]; const classProperties = defaultValue(metadataClass.properties, {}); // Validate each property for (const propertyName of validPropertyNames) { const propertyPath = path + "/properties/" + propertyName; const classProperty = classProperties[propertyName]; let enumValueType = undefined; const enumType = classProperty.enumType; if (defined(enumType)) { const enums = defaultValue(schema.enums, {}); const metadataEnum = enums[enumType]; enumValueType = metadataEnum.valueType || "UINT16"; } // Note: The check whether 'required' properties are // present and have values was already done by the // MetadataStructureValidator const propertyValue = validProperties[propertyName]; if (defined(propertyValue)) { if ( !PropertyAttributePropertyValidator.validatePropertyAttributeProperty( propertyPath, propertyName, propertyValue, classProperty, enumValueType, context ) ) { result = false; } } } return result; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyAttributeValuesValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ClassProperties } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { GltfData } from "../GltfData"; import { Accessors } from "../Accessors"; import { PropertyAttributePropertyModel } from "./PropertyAttributePropertyModel"; import { StructureValidationIssues } from "../../../issues/StructureValidationIssues"; import { ValidationIssues } from "../../../issues/ValidationIssues"; import { MetadataValidationUtilities } from "../../metadata/MetadataValidationUtilities"; import { MetadataPropertyValuesValidator } from "../../metadata/MetadataPropertyValuesValidator"; import { RangeIterables } from "../../metadata/RangeIterables"; /** * A class for the validation of values that are stored * in property attributes. * * The methods in this class assume that the structural * validity of the input objects has already been checked * by a `PropertyAttributeValidator`. * * @internal */ export class PropertyAttributeValuesValidator { /** * Performs the validation to ensure that the specified property * attribute contains valid values. * * This is supposed to be called after the validity of the top-level * extension object, the schema, and the property attribute itself have * been checked (the latter with * `PropertyAttributeValidator.validatePropertyAttribute`). * * It assumes that they are structurally valid, and ONLY checks the * validity of the values in the context of the mesh primitive * that refers to the property attribute. * * @param path - The path for the `ValidationIssue` instances * @param propertyAttributeIndex - The index that was found as * an element `propertyAttributes[i]` of the extension object * that was found in the extension object in the mesh primitive * @param meshPrimitive - The glTF mesh primitive that contained * the extension object * @param meshIndex - The index of the mesh (only for details * in validation messages) * @param primitiveIndex - The index of the primitive (only for details * in validation messages) * @param schema - The metadata schema * @param gltfStructuralMetadata - The top-level glTF structural * metadata object * @param gltfData - The glTF data * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the values in the object have been valid */ static async validatePropertyAttributeValues( path: string, propertyAttributeIndex: number, meshPrimitive: any, meshIndex: number, primitiveIndex: number, schema: Schema, gltfStructuralMetadata: any, gltfData: GltfData, context: ValidationContext ): Promise { let result = true; // The presence of the 'propertyAttributes', the validity of // the 'propertyAttributeIndex', and the STRUCTURAL validity // of the property attribute have already been checked const propertyAttributes = defaultValue( gltfStructuralMetadata.propertyAttributes, [] ); const propertyAttribute = propertyAttributes[propertyAttributeIndex]; const propertyAttributeProperties = defaultValue( propertyAttribute.properties, {} ); const meshPrimitiveAttributes = defaultValue(meshPrimitive.attributes, {}); // Make sure that the `attribute` values of the properties // refer to valid attributes of the mesh primitive const propertyAttributePropertyNames = Object.keys( propertyAttributeProperties ); for (const propertyName of propertyAttributePropertyNames) { const propertyAttributeProperty = propertyAttributeProperties[propertyName]; const propertyAttributePropertyPath = path + "/properties/" + propertyName; const attribute = propertyAttributeProperty.attribute; const meshPrimitiveAttribute = meshPrimitiveAttributes[attribute]; if (!defined(meshPrimitiveAttribute)) { const message = `The property attribute property defines the attribute ` + `${attribute}, but this attribute was not ` + `found in the attributes of primitive ${primitiveIndex} ` + `of mesh ${meshIndex}`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( propertyAttributePropertyPath, message ); context.addIssue(issue); result = false; } } // If everything appeared to be valid until now, validate // the values of the property attribute properties in view // of the glTF mesh primitive attribute that they refer to if (result && gltfData.gltfDocument) { for (const propertyName of propertyAttributePropertyNames) { const propertyAttributeProperty = propertyAttributeProperties[propertyName]; const propertyAttributePropertyPath = path + "/properties/" + propertyName; const metadataClassName = propertyAttribute.class; // Assuming structural validity for the classProperty const classProperty = MetadataValidationUtilities.computeClassProperty( schema, metadataClassName, propertyName )!; const propertyValuesValid = await PropertyAttributeValuesValidator.validatePropertyAttributePropertyValues( propertyAttributePropertyPath, propertyName, propertyAttributeProperty, meshPrimitive, meshIndex, primitiveIndex, schema, metadataClassName, classProperty, gltfData, context ); if (!propertyValuesValid) { result = false; } } } return result; } /** * Validate the values of a single property of a property attribute. * * This assumes that the gltfData contains a valid gltfDocument. * * @param path - The path for `ValidationIssue` instances * @param propertyName - The property name * @param propertyAttributeProperty - The property attribute property * @param meshPrimitive - The mesh primitive * @param meshIndex - The index of the mesh (only for details * in validation messages) * @param primitiveIndex - The index of the primitive (only for details * in validation messages) * @param schema - The metadata schema * @param metadataClassName - Te class name that was given in the * surrounding property attribute * @param gltfData - The glTF data * @param context - The `ValidationContext` * @returns Whether the property is valid */ private static async validatePropertyAttributePropertyValues( path: string, propertyName: string, propertyAttributeProperty: any, meshPrimitive: any, meshIndex: number, primitiveIndex: number, schema: Schema, metadataClassName: string, classProperty: ClassProperty, gltfData: GltfData, context: ValidationContext ): Promise { let result = true; const meshPrimitiveAttributes = defaultValue(meshPrimitive.attributes, {}); const attribute = propertyAttributeProperty.attribute; const meshPrimitiveAttribute = meshPrimitiveAttributes[attribute]; let accessorValues; if (classProperty.array === true) { accessorValues = Accessors.readArrayAccessorValues( meshPrimitiveAttribute, gltfData ); } else { accessorValues = Accessors.readScalarAccessorValues( meshPrimitiveAttribute, gltfData ); } if (accessorValues === undefined) { // When it is not possible to obtain the accessor data, then // this means that the gltfDocument has been undefined // because it could not be read. This can be caused by // - the glTF structure being invalid (but this should have // been caught by the glTF validator) // - the extension object structure being invalid (in which // case an issue should already have been added to the // context, and this method should not have been called) // In both cases, reaching this point indicates an internal error: const message = `Could not read accessor data from glTF document`; const issue = ValidationIssues.INTERNAL_ERROR(path, message); context.addIssue(issue); return false; } const keys = RangeIterables.range1D(accessorValues.length); const metadataPropertyModel = new PropertyAttributePropertyModel( accessorValues, propertyAttributeProperty, classProperty ); // Perform the checks that only apply to ENUM types, if (classProperty.type === "ENUM") { // Assuming structural validity for the validEnumValueValues const validEnumValueValues = MetadataValidationUtilities.computeValidEnumValueValues( schema, metadataClassName, propertyName )!; if ( !MetadataPropertyValuesValidator.validateEnumValues( path, propertyName, keys, metadataPropertyModel, validEnumValueValues, context ) ) { result = false; } } const propertyAttributeContextDescription = `attribute ${attribute} of primitive ${primitiveIndex} of mesh ${meshIndex}`; // Perform the checks that only apply to numeric types if (ClassProperties.hasNumericType(classProperty)) { if ( !MetadataPropertyValuesValidator.validateMinMax( path, propertyName, keys, metadataPropertyModel, propertyAttributeProperty, propertyAttributeContextDescription, classProperty, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyAttributesDefinitionValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { ValidatedElement } from "../../ValidatedElement"; import { BasicValidator } from "../../BasicValidator"; import { PropertyAttributeValidator } from "./PropertyAttributeValidator"; import { StructureValidationIssues } from "../../../issues/StructureValidationIssues"; /** * A class for validating the definition of property attributes. */ export class PropertyAttributesDefinitionValidator { /** * Validate the given definition of property attributes. * * The returned object will contain two properties: * - `wasPresent`: Whether property attributes have been given * - `validatedElement`: The validated `PropertyAttribute[]` object * * When no property attributes are given, then it will just return * `{false, undefined}`. * * If the given `schemaState` indicates that no schema was present, * or the property attributes have not been valid according to the * schema, then an error will be added to the given context, * and `{true, undefined}` is returned. * * The method will return `{true, propertyAttributes}` only if the * given property attributes have been valid. * * @param path - The path for `ValidationIssue` instances * @param name - The name of the object containing the definition * (for example, 'metadata extension object') * @param propertyAttributes - The actual property attributes * @param gltf - The containing glTF object * @param schemaState - The state of the schema validation * @param context - The `ValidationContext` * @returns Information about the validity of the definition */ static validatePropertyAttributesDefinition( path: string, name: string, propertyAttributes: any[] | undefined, schemaState: ValidatedElement, context: ValidationContext ): ValidatedElement { // Return immediately when there are no property attributes const propertyAttributesState: ValidatedElement = { wasPresent: false, validatedElement: undefined, }; if (!defined(propertyAttributes)) { return propertyAttributesState; } // There are property attributes. propertyAttributesState.wasPresent = true; // Validate the propertyAttributes, returning as soon as they // have been determined to be invalid const propertyAttributesPath = path + "/propertyAttributes"; if (!schemaState.wasPresent) { // If there are property attributes, then there MUST be a schema definition const message = `The ${name} defines 'propertyAttributes' but ` + `there was no schema definition`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); return propertyAttributesState; } if (defined(schemaState.validatedElement)) { // The propertyAttributes MUST be an array of at least 1 objects if ( !BasicValidator.validateArray( propertyAttributesPath, "propertyAttributes", propertyAttributes, 1, undefined, "object", context ) ) { return propertyAttributesState; } // Validate each propertyAttribute for (let i = 0; i < propertyAttributes.length; i++) { const propertyAttribute = propertyAttributes[i]; const propertyAttributePath = propertyAttributesPath + "/" + i; if ( !PropertyAttributeValidator.validatePropertyAttribute( propertyAttributePath, propertyAttribute, schemaState.validatedElement, context ) ) { return propertyAttributesState; } } } // The property attributes have been determined to be valid. // Return them as the validatedElement in the returned // state: propertyAttributesState.validatedElement = propertyAttributes; return propertyAttributesState; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyTableDefinitionValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { ValidatedElement } from "../../ValidatedElement"; import { BasicValidator } from "../../BasicValidator"; import { GltfData } from "../GltfData"; import { GltfExtensionValidationIssues } from "../../../issues/GltfExtensionValidationIssues"; /** * A class for the validation of a single property table that * is referred to by a feature ID definition. * */ export class PropertyTableDefinitionValidator { /** * Validate the given feature ID `propertyTable` value that was found in * a feature ID definition. * * The returned object will contain two properties: * - `wasPresent`: Whether a propertyTable (index) was given * - `validatedElement`: The validated property table object, only * insofar that it contains a defined `count` value * * This will check whether the `propertyTable` refers to an existing * property table in the `EXT_structural_metadata` extension object, * and this property table has a valid `count`. * * It will NOT check the validity of the property table itself. This * will be done by the `EXT_structural_metadata` validator. * * @param path - The path for validation issues * @param propertyTableIndex - The value that was found as the `propertyTable` * in the definition, indicating the index into the property tables array * @param gltfData - The glTF data * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the state summarizing the definition */ static validatePropertyTableDefinition( path: string, propertyTableIndex: number | undefined, gltfData: GltfData, context: ValidationContext ): ValidatedElement<{ count: number }> { // Return immediately when there are no property table const propertyTableState: ValidatedElement<{ count: number }> = { wasPresent: false, validatedElement: undefined, }; if (!defined(propertyTableIndex)) { return propertyTableState; } propertyTableState.wasPresent = true; const gltf = gltfData.gltf; const extensions = gltf.extensions || {}; const structuralMetadata = extensions["EXT_structural_metadata"]; if (!structuralMetadata) { const message = `The feature ID refers to a property table with index ` + `${propertyTableIndex}, but the glTF did not contain an ` + `'EXT_structural_metadata' extension object`; const issue = GltfExtensionValidationIssues.INVALID_GLTF_STRUCTURE( path, message ); context.addIssue(issue); return propertyTableState; } const propertyTables = structuralMetadata.propertyTables; if (!propertyTables) { const message = `The feature ID refers to a property table with index ` + `${propertyTableIndex}, but the 'EXT_structural_metadata' ` + `extension object did not define property tables`; const issue = GltfExtensionValidationIssues.INVALID_GLTF_STRUCTURE( path, message ); context.addIssue(issue); return propertyTableState; } // Validate the propertyTable(Index) // The propertyTable MUST be an integer in [0,numPropertyTables) const numPropertyTables = defaultValue(propertyTables.length, 0); if ( !BasicValidator.validateIntegerRange( path, "propertyTable", propertyTableIndex, 0, true, numPropertyTables, false, context ) ) { return propertyTableState; } const propertyTable = propertyTables[propertyTableIndex]; if (!propertyTable) { // An issue will be added to the validation context by // the `EXT_structural_metadata` validation return propertyTableState; } const count = propertyTable.count; if (count === undefined) { // An issue will be added to the validation context by // the `EXT_structural_metadata` validation return propertyTableState; } propertyTableState.validatedElement = propertyTable; return propertyTableState; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyTextureBooleanMetadataPropertyModel.ts ================================================ import { ClassProperty } from "3d-tiles-tools"; import { MetadataValues } from "3d-tiles-tools"; import { NumericBuffers } from "3d-tiles-tools"; import { ImageData } from "../ImageData"; import { ImageDataReader } from "../ImageDataReader"; import { MetadataPropertyModel } from "../../metadata/MetadataPropertyModel"; /** * Implementation of a MetadataPropertyModel for a single * property texture property that contains boolean values. * * @internal */ export class PropertyTextureBooleanMetadataPropertyModel implements MetadataPropertyModel<[number, number]> { /** * The image data that was read from the glTF texture */ private readonly imageData: ImageData; /** * The property texture property that is represented by this model */ private readonly propertyTextureProperty: any; /** * The class property that defines the structure of the property */ private readonly classProperty: ClassProperty; /** * Creates a new instance * * @param imageData - The image data * @param propertyTextureProperty - The property texture property * @param classProperty - The class property */ constructor( imageData: ImageData, propertyTextureProperty: any, classProperty: ClassProperty ) { this.imageData = imageData; this.propertyTextureProperty = propertyTextureProperty; this.classProperty = classProperty; } /** {@inheritDoc MetadataPropertyModel.getPropertyValue} */ getPropertyValue(pixelCoordinates: [number, number]): boolean | boolean[] { const propertyTextureProperty = this.propertyTextureProperty; const classProperty = this.classProperty; const offsetOverride = propertyTextureProperty.offset; const scaleOverride = propertyTextureProperty.scale; const value = this.getRawPropertyValue(pixelCoordinates); const processedValue = MetadataValues.processValue( classProperty, offsetOverride, scaleOverride, value ); return processedValue; } /** {@inheritDoc MetadataPropertyModel.getRawPropertyValue} */ getRawPropertyValue(pixelCoordinates: [number, number]): boolean | boolean[] { const propertyTextureProperty = this.propertyTextureProperty; const classProperty = this.classProperty; const channels = propertyTextureProperty.channels; // First, collect the actual values from the image // data in a buffer const x = pixelCoordinates[0]; const y = pixelCoordinates[1]; const buffer = Buffer.alloc(channels.length); for (let c = 0; c < channels.length; c++) { const channelValue = ImageDataReader.getChannelValue( this.imageData, x, y, c ); buffer.writeUInt8(channelValue & 0xff, c); } // Handle boolean array properties if (classProperty.array) { // Variable-length arrays are not supported for property // textures, so the `count` must be defined here const count = classProperty.count!; const value = Array(count); for (let e = 0; e < count; e++) { const element = NumericBuffers.getBooleanFromBuffer(buffer, e); value[e] = element; } return value; } // Handle boolean (non-array) properties const value = NumericBuffers.getBooleanFromBuffer(buffer, 0); return value; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyTextureEnumMetadataPropertyModel.ts ================================================ import { ClassProperty } from "3d-tiles-tools"; import { MetadataValues } from "3d-tiles-tools"; import { NumericBuffers } from "3d-tiles-tools"; import { ImageData } from "../ImageData"; import { ImageDataReader } from "../ImageDataReader"; import { MetadataPropertyModel } from "../../metadata/MetadataPropertyModel"; /** * Implementation of a MetadataPropertyModel for a single * property texture property that contains enum values. * * @internal */ export class PropertyTextureEnumMetadataPropertyModel implements MetadataPropertyModel<[number, number]> { /** * The image data that was read from the glTF texture */ private readonly imageData: ImageData; /** * The property texture property that is represented by this model */ private readonly propertyTextureProperty: any; /** * The class property that defines the structure of the property */ private readonly classProperty: ClassProperty; /** * The value type of the enum that is represented with the * given class property */ private readonly enumValueType: string; /** * The mapping from enum value values to enum value names for * the enum type of the given class property */ private readonly enumValueValueNames: { [key: number]: string }; /** * Creates a new instance * * @param imageData - The image data * @param propertyTextureProperty - The property texture property * @param classProperty - The class property * @param enumValueType - The `valueType` of the enum type of * the given class property * @param valueValueNames - The mapping from enum value values * to enum value names for the enum type of the given class * property */ constructor( imageData: ImageData, propertyTextureProperty: any, classProperty: ClassProperty, enumValueType: string, enumValueValueNames: { [key: number]: string } ) { this.imageData = imageData; this.propertyTextureProperty = propertyTextureProperty; this.classProperty = classProperty; this.enumValueType = enumValueType; this.enumValueValueNames = enumValueValueNames; } /** {@inheritDoc MetadataPropertyModel.getPropertyValue} */ getPropertyValue(pixelCoordinates: [number, number]): string | string[] { const classProperty = this.classProperty; const value = this.getRawPropertyValue(pixelCoordinates); const valueNames = this.enumValueValueNames; const processedValue = MetadataValues.processNumericEnumValue( classProperty, valueNames, value ); return processedValue; } /** {@inheritDoc MetadataPropertyModel.getRawPropertyValue} */ getRawPropertyValue(pixelCoordinates: [number, number]): number | number[] { const propertyTextureProperty = this.propertyTextureProperty; const classProperty = this.classProperty; const channels = propertyTextureProperty.channels; // First, collect the actual values from the image // data in a buffer const x = pixelCoordinates[0]; const y = pixelCoordinates[1]; const buffer = Buffer.alloc(channels.length); for (let c = 0; c < channels.length; c++) { const channelValue = ImageDataReader.getChannelValue( this.imageData, x, y, c ); buffer.writeUInt8(channelValue & 0xff, c); } // The enum value type is assumed to be defined // for enum properties const enumValueType = this.enumValueType!; // Handle enum array properties if (classProperty.array) { // Variable-length arrays are not supported for property // textures, so the `count` must be defined here const count = classProperty.count!; const value = Array(count); for (let e = 0; e < count; e++) { const element = NumericBuffers.getNumericFromBuffer( buffer, e, enumValueType ); value[e] = element; } return value; } // Handle enum (non-array) properties const value = NumericBuffers.getNumericFromBuffer(buffer, 0, enumValueType); return Number(value); } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyTextureMetadataPropertyModels.ts ================================================ import { ClassProperty } from "3d-tiles-tools"; import { ImageData } from "../ImageData"; import { PropertyTextureNumericMetadataPropertyModel } from "./PropertyTextureNumericMetadataPropertyModel"; import { PropertyTextureBooleanMetadataPropertyModel } from "./PropertyTextureBooleanMetadataPropertyModel"; import { PropertyTextureEnumMetadataPropertyModel } from "./PropertyTextureEnumMetadataPropertyModel"; import { MetadataPropertyModel } from "../../metadata/MetadataPropertyModel"; /** * Methods to create MetadataPropertyModel instances for * property textures. */ export class PropertyTextureMetadataPropertyModels { /** * Creates a new MetadataPropertyModel for the given * enum property texture property * * @param imageData - The image data * @param propertyTextureProperty - The property texture property * @param classProperty - The class property * @param enumValueType - The `valueType` of the enum type of * the given class property * @param valueValueNames - The mapping from enum value values * to enum value names for the enum type of the given class * property * @returns The resulting model */ static createEnum( imageData: ImageData, propertyTextureProperty: any, classProperty: ClassProperty, enumValueType: string, enumValueValueNames: { [key: number]: string } ): MetadataPropertyModel<[number, number]> { return new PropertyTextureEnumMetadataPropertyModel( imageData, propertyTextureProperty, classProperty, enumValueType, enumValueValueNames ); } /** * Creates a new MetadataPropertyModel for the given * boolean property texture property * * @param imageData - The image data * @param propertyTextureProperty - The property texture property * @param classProperty - The class property * @returns The resulting model */ static createBoolean( imageData: ImageData, propertyTextureProperty: any, classProperty: ClassProperty ): MetadataPropertyModel<[number, number]> { return new PropertyTextureBooleanMetadataPropertyModel( imageData, propertyTextureProperty, classProperty ); } /** * Creates a new MetadataPropertyModel for the given * numeric property texture property * * @param imageData - The image data * @param propertyTextureProperty - The property texture property * @param classProperty - The class property * @returns The resulting model */ static createNumeric( imageData: ImageData, propertyTextureProperty: any, classProperty: ClassProperty ): MetadataPropertyModel<[number, number]> { return new PropertyTextureNumericMetadataPropertyModel( imageData, propertyTextureProperty, classProperty ); } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyTextureNumericMetadataPropertyModel.ts ================================================ import { ClassProperty } from "3d-tiles-tools"; import { MetadataValues } from "3d-tiles-tools"; import { NumericBuffers } from "3d-tiles-tools"; import { ImageData } from "../ImageData"; import { ImageDataReader } from "../ImageDataReader"; import { MetadataPropertyModel } from "../../metadata/MetadataPropertyModel"; /** * Implementation of a MetadataPropertyModel for a single * property texture property that contains numeric values. * * @internal */ export class PropertyTextureNumericMetadataPropertyModel implements MetadataPropertyModel<[number, number]> { /** * The image data that was read from the glTF texture */ private readonly imageData: ImageData; /** * The property texture property that is represented by this model */ private readonly propertyTextureProperty: any; /** * The class property that defines the structure of the property */ private readonly classProperty: ClassProperty; /** * Creates a new instance * * @param imageData - The image data * @param propertyTextureProperty - The property texture property * @param classProperty - The class property */ constructor( imageData: ImageData, propertyTextureProperty: any, classProperty: ClassProperty ) { this.imageData = imageData; this.propertyTextureProperty = propertyTextureProperty; this.classProperty = classProperty; } /** {@inheritDoc MetadataPropertyModel.getPropertyValue} */ getPropertyValue(pixelCoordinates: [number, number]): number | number[] { const propertyTextureProperty = this.propertyTextureProperty; const classProperty = this.classProperty; const offsetOverride = propertyTextureProperty.offset; const scaleOverride = propertyTextureProperty.scale; const value = this.getRawPropertyValue(pixelCoordinates); const processedValue = MetadataValues.processValue( classProperty, offsetOverride, scaleOverride, value ); return processedValue; } /** {@inheritDoc MetadataPropertyModel.getRawPropertyValue} */ getRawPropertyValue(pixelCoordinates: [number, number]): number | number[] { const propertyTextureProperty = this.propertyTextureProperty; const classProperty = this.classProperty; const channels = propertyTextureProperty.channels; // First, collect the actual values from the image // data in a buffer const x = pixelCoordinates[0]; const y = pixelCoordinates[1]; const buffer = Buffer.alloc(channels.length); for (let c = 0; c < channels.length; c++) { const channelValue = ImageDataReader.getChannelValue( this.imageData, x, y, c ); buffer.writeUInt8(channelValue & 0xff, c); } const componentType = classProperty.componentType!; // Handle array properties if (classProperty.array) { // Variable-length arrays are not supported for property // textures, so the `count` must be defined here const count = classProperty.count!; const value = Array(count); for (let e = 0; e < count; e++) { const element = NumericBuffers.getNumericFromBuffer( buffer, e, componentType ); value[e] = Number(element); } return value; } // Handle (non-array) properties const value = NumericBuffers.getNumericFromBuffer(buffer, 0, componentType); return Number(value); } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyTexturePropertyValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { MetadataComponentTypes } from "3d-tiles-tools"; import { MetadataTypes } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { MetadataPropertyValidator } from "../../metadata/MetadataPropertyValidator"; import { GltfExtensionValidationIssues } from "../../../issues/GltfExtensionValidationIssues"; import { TextureValidator } from "../TextureValidator"; import { SamplerValidator } from "../SamplerValidator"; /** * A class for validations related to `propertyTexture.property` objects. * * @internal */ export class PropertyTexturePropertyValidator { /** * Performs the validation to ensure that the given object is a * valid `propertyTexture.property` object. * * This checks the basic validity of the property, namely * - it is an object * - its `index` refers to an existing texture in the glTF * - its `texCoord` is a nonnegative integer * - its `channels` (if defined) is an array of at least one nonnegative integers * - its type (defined via the `classProperty`) is suitable for a property texture * - the sampler of the texture is suitable for a property texture * - its `offset/scale/min/max` properties match the `classProperty` structure * * Checking the validity of the `texCoord` for a mesh primitive, and * checking the values (whether they are valid enum values, or whether * their min/max are valid) is done by the PropertyTextureValuesValidator. * * @param path - The path for the `ValidationIssue` instances * @param propertyName - The name of the property * @param propertyTextureProperty - The object to validate * @param gltf - The containing glTF object * @param meshPrimitive - The mesh primitive that contains the extension * @param classProperty - The `ClassProperty` definition from the schema * @param enumValueType - The value type of the enum that is represented * with the given class property, or `undefined` if it is not an enum * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validatePropertyTextureProperty( path: string, propertyName: string, propertyTextureProperty: any, gltf: any, classProperty: ClassProperty, enumValueType: string | undefined, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, propertyName, propertyTextureProperty, context ) ) { return false; } const textures = gltf.textures || []; const numTextures = textures.length; // Validate the index // The index MUST be defined // The index MUST be an integer in [0, numTextures) const index = propertyTextureProperty.index; const indexPath = path + "/index"; if ( !BasicValidator.validateIntegerRange( indexPath, "index", index, 0, true, numTextures, false, context ) ) { return false; } let result = true; // Validate the texCoord const texCoord = propertyTextureProperty.texCoord; const texCoordPath = path + "/texCoord"; if (defined(texCoord)) { if ( !TextureValidator.validateTexCoordDefinition( texCoordPath, texCoord, context ) ) { result = false; } } // Make sure that the type of the class property is valid for // a property texture in general. const typeIsValid = PropertyTexturePropertyValidator.validateClassPropertyForPropertyTextureProperty( path, propertyName, classProperty, context ); if (!typeIsValid) { result = false; } // Validate the channels. // This will only check the basic validity, namely that the channels // (if they are defined) are an array of nonnegative integers. Whether // the channels match the image structure is validated later const channels = propertyTextureProperty.channels; if (!TextureValidator.validateChannels(path, channels, context)) { result = false; } else { // If the type and channels are basically valid, ensure that the // length of the channels array matches the number of bytes of // the type that is defined with the `classProperty`. if (typeIsValid) { // The channels are defaulting to `[ 0 ]` const numChannels = defaultValue(channels?.length, 1); if ( !PropertyTexturePropertyValidator.validatePropertyTexturePropertyTypeSize( path, propertyName, numChannels, classProperty, enumValueType, context ) ) { result = false; } } } // Make sure that the sampler of the texture (if present) uses the // allowed values (namely, 'undefined' or 9728 (NEAREST) or // 9729 (LINEAR)) for its minFilter and magFilter. // (Note: The validity of the `texture.sampler` index has // already been checked by the glTF Validator) const texture = textures[index]; const samplerIndex = texture.sampler; if (samplerIndex !== undefined) { const samplers = gltf.samplers || []; const sampler = samplers[samplerIndex]; if ( !SamplerValidator.validateSamplerNearestOrLinear(path, sampler, context) ) { result = false; } } // Validate the offset/scale/max/min properties const elementsAreValid = MetadataPropertyValidator.validateOffsetScaleMaxMin( path, propertyTextureProperty, propertyName, classProperty, context ); if (!elementsAreValid) { result = false; } return result; } /** * Validates that the given number of channels matches the * number of bytes of the type of the given `classProperty`. * * The given number is the length of the `channels` array of * a property texture property (if it is defined). If the * `channels` array is not defined, then this value should be * `1`, because the default value for the `channels` is `[0]`. * * This assumes that the given `classProperty` does not have * the type `STRING`, and has already been determined to be * structurally valid. * * If the number is not valid, then a validation warning will be * added to the given context. * * This makes the assumption that one channel of the image * indeed consists of 8 bits. Since there is no reasonable * way validate the bit depth of the image, any mismatch * will only result in a WARNING (and not an error). * * @param path - The path for the `ValidationIssue` instances * @param propertyName - The name of the property * @param numberOfChannels - The number of channels * @param classProperty - The `ClassProperty` definition from the schema * @param enumValueType - The value type of the enum that is represented * with the given class property, or `undefined` if it is not an enum * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the number was valid */ static validatePropertyTexturePropertyTypeSize( path: string, propertyName: string, numberOfChannels: number, classProperty: ClassProperty, enumValueType: string | undefined, context: ValidationContext ): boolean { // When the type is an enum, compute the required size // based on the enum value type const enumType = classProperty.enumType; if (defined(enumType)) { // It is assumed that the schema and classProperty are valid, // so that a valid enum value type was given here: const byteSize = MetadataComponentTypes.byteSizeForComponentType( enumValueType! ); if (classProperty.array === true) { // Handle properties that are enum arrays const totalByteSize = classProperty.count! * byteSize; if (totalByteSize !== numberOfChannels) { const message = `The property '${propertyName}' has the enum type ` + `${enumType} with a value type of ${enumValueType} which ` + `consists of ${byteSize} bytes, and the property is an ` + `array with ${classProperty.count} elements, resulting in ` + `a total number of ${totalByteSize}, but the number of channels ` + `in the property texture property was ${numberOfChannels}`; const issue = GltfExtensionValidationIssues.TEXTURE_CHANNELS_SIZE_MISMATCH( path, message ); context.addIssue(issue); } } else { // Handle properties that are single enums if (byteSize !== numberOfChannels) { const message = `The property '${propertyName}' has the enum type ` + `${enumType} with a value type of ${enumValueType}, which ` + `consists of ${byteSize} bytes, but the number of channels ` + `in the property texture property was ${numberOfChannels}`; const issue = GltfExtensionValidationIssues.TEXTURE_CHANNELS_SIZE_MISMATCH( path, message ); context.addIssue(issue); } } return true; } // When the type is ENUM, compute the size based on the // number of required bits const type = classProperty.type; if (type === "BOOLEAN") { if (classProperty.array === true) { // Handle BOOLEAN properties that are arrays const count = classProperty.count!; const totalByteSize = Math.ceil(count / 8); if (totalByteSize !== numberOfChannels) { const message = `The property '${propertyName}' is has the type 'BOOLEAN' and it ` + `is an array with ${count} elements, resulting in a total number of ` + `ceil(${count}/8) = ${totalByteSize} bytes, but the number of channels ` + `in the property texture property was ${numberOfChannels}`; const issue = GltfExtensionValidationIssues.TEXTURE_CHANNELS_SIZE_MISMATCH( path, message ); context.addIssue(issue); } } // For BOOLEAN properties that are not arrays, even a single // channel is sufficient return true; } // For non-ENUM and non-BOOLEAN types, compute the required size // based on the number of bytes per component, and the number // of components per element const componentType = classProperty.componentType; const componentCount = MetadataTypes.componentCountForType(type); const componentByteSize = MetadataComponentTypes.byteSizeForComponentType( componentType! ); const elementByteSize = componentCount * componentByteSize; if (classProperty.array === true) { // Handle properties that are arrays const totalByteSize = classProperty.count! * elementByteSize; if (totalByteSize !== numberOfChannels) { const message = `The property '${propertyName}' has the component type ` + `${componentType}, with a size of ${componentByteSize} bytes, ` + `and the type ${type} with ${componentCount} components, ` + `resulting in ${elementByteSize} bytes per element, and it ` + `is an array with ${classProperty.count} elements, resulting in ` + `a total number of ${totalByteSize}, but the number of channels ` + `in the property texture property was ${numberOfChannels}`; const issue = GltfExtensionValidationIssues.TEXTURE_CHANNELS_SIZE_MISMATCH( path, message ); context.addIssue(issue); } } else { // Handle properties that are not arrays if (elementByteSize !== numberOfChannels) { const message = `The property '${propertyName}' has the component type ` + `${componentType}, with a size of ${componentByteSize} bytes, ` + `and the type ${type} with ${componentCount} components, ` + `resulting in ${elementByteSize} bytes per element, but ` + `the number of channels in the property texture property ` + `was ${numberOfChannels}`; const issue = GltfExtensionValidationIssues.TEXTURE_CHANNELS_SIZE_MISMATCH( path, message ); context.addIssue(issue); } } return true; } /** * Validates that the given `classProperty` is basically suitable * for a property texture (meaning that it is not a variable-length * array and not of type STRING). * * If the type is not valid, then a validation error will be added * to the given context, and `false` will be returned. * * @param path - The path for the `ValidationIssue` instances * @param propertyName - The name of the property * @param classProperty - The `ClassProperty` definition from the schema * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateClassPropertyForPropertyTextureProperty( path: string, propertyName: string, classProperty: ClassProperty, context: ValidationContext ): boolean { // From the specification text for property textures: // Variable-length arrays are not supported in property textures const isVariableLengthArray = classProperty.array && !defined(classProperty.count); if (isVariableLengthArray) { const message = `The property '${propertyName}' is a variable-length array, ` + `which is not supported for property textures`; const issue = GltfExtensionValidationIssues.INVALID_METADATA_PROPERTY_TYPE( path, message ); context.addIssue(issue); return false; } // From the specification text for property textures: // Strings are not supported in property textures const isString = classProperty.type === "STRING"; if (isString) { const message = `The property '${propertyName}' has the type 'STRING', ` + `which is not supported for property textures`; const issue = GltfExtensionValidationIssues.INVALID_METADATA_PROPERTY_TYPE( path, message ); context.addIssue(issue); return false; } return true; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyTextureValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { MetadataUtilities } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { BasicValidator } from "../../BasicValidator"; import { RootPropertyValidator } from "../../RootPropertyValidator"; import { ExtendedObjectsValidators } from "../../ExtendedObjectsValidators"; import { MetadataStructureValidator } from "../../metadata/MetadataStructureValidator"; import { PropertyTexturePropertyValidator } from "./PropertyTexturePropertyValidator"; /** * A class for validations related to `propertyTexture` objects. * * This class performs the basic JSON-level validation of the * property texture. * * The validation of any of the underlying binary data of * a property texture has to start at the mesh primitive * that refers to the property texture, because it requires * knowledge about the attributes (texture coordinates) * that are defined in the referring mesh primitive, and * the glTF texture that the definition refers to. * * @internal */ export class PropertyTextureValidator { /** * Performs the validation to ensure that the given object is a * valid `propertyTexture` object. * * @param path - The path for the `ValidationIssue` instances * @param propertyTexture - The object to validate * @param gltf - The glTF object that contains the definitions * @param meshPrimitive - The mesh primitive that contains the extension * @param schema - The `Schema` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validatePropertyTexture( path: string, propertyTexture: any, gltf: any, schema: Schema, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "propertyTexture", propertyTexture, context ) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, "propertyTexture", propertyTexture, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( path, propertyTexture, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(propertyTexture)) { return result; } // Validate that the class and properties are structurally // valid and comply to the metadata schema const className = propertyTexture.class; const textureProperties = propertyTexture.properties; if ( !MetadataStructureValidator.validateMetadataStructure( path, "property texture", className, textureProperties, schema, context ) ) { // Bail out early if the structure is not valid! return false; } // Validate the name. // If the name is defined, it MUST be a string. if ( !BasicValidator.validateOptionalString( path, propertyTexture, "name", context ) ) { result = false; } // Here, the basic structure of the class and properties // have been determined to be valid. Continue to validate // the values of the properties. const validProperties = defaultValue(textureProperties, {}); const validPropertyNames = Object.keys(validProperties); const classes = defaultValue(schema.classes, {}); const metadataClass = classes[className]; const classProperties = defaultValue(metadataClass.properties, {}); // Validate each property for (const propertyName of validPropertyNames) { const propertyPath = path + "/properties/" + propertyName; const classProperty = classProperties[propertyName]; const enumValueType = MetadataUtilities.computeEnumValueType( schema, classProperty ); // Note: The check whether 'required' properties are // present and have values was already done by the // MetadataStructureValidator const propertyValue = validProperties[propertyName]; if (defined(propertyValue)) { if ( !PropertyTexturePropertyValidator.validatePropertyTextureProperty( propertyPath, propertyName, propertyValue, gltf, classProperty, enumValueType, context ) ) { result = false; } } } return result; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyTextureValuesValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ClassProperties } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { GltfData } from "../GltfData"; import { ImageDataReader } from "../ImageDataReader"; import { TextureValidator } from "../TextureValidator"; import { PropertyTextureMetadataPropertyModels } from "./PropertyTextureMetadataPropertyModels"; import { StructureValidationIssues } from "../../../issues/StructureValidationIssues"; import { RangeIterables } from "../../metadata/RangeIterables"; import { MetadataPropertyValuesValidator } from "../../metadata/MetadataPropertyValuesValidator"; import { MetadataValidationUtilities } from "../../metadata/MetadataValidationUtilities"; /** * A class for the validation of values that are stored * in property textures. * * The methods in this class assume that the structural * validity of the input objects has already been checked * by a `PropertyTextureValidator`. * * @internal */ export class PropertyTextureValuesValidator { /** * Performs the validation to ensure that the specified property * texture contains valid values. * * This is supposed to be called after the validity of the top-level * extension object, the schema, and the property texture itself have * been checked (the latter with * `PropertyTexturePropertyValidator.validatePropertyTextureProperty`). * * It assumes that they are structurally valid, and ONLY checks the * validity of the values in the context of the mesh primitive * that refers to the property texture, and the glTF texture * that the property texture refers to. * * @param path - The path for the `ValidationIssue` instances * @param propertyTextureIndex - The index that was given in the * `propertyTextures` array of the mesh primitive extension * object, and that refers to the property textures array in * the top-level glTF structural metadata object. * @param meshPrimitive - The glTF mesh primitive that contained * the extension object * @param meshIndex - The index of the mesh (only for details * in validation messages) * @param primitiveIndex - The index of the primitive (only for details * in validation messages) * @param schema - The metadata schema * @param gltfStructuralMetadata - The top-level glTF structural * metadata object * @param gltfData - The glTF data * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the values in the object have been valid */ static async validatePropertyTextureValues( path: string, propertyTextureIndex: number, meshPrimitive: any, meshIndex: number, primitiveIndex: number, schema: Schema, gltfStructuralMetadata: any, gltfData: GltfData, context: ValidationContext ): Promise { let result = true; // The presence of the 'propertyTextures', the validity of // the 'propertyTextureIndex', and the STRUCTURAL validity // of the property texture have already been checked const propertyTextures = defaultValue( gltfStructuralMetadata.propertyTextures, [] ); const propertyTexture = propertyTextures[propertyTextureIndex]; const propertyTextureProperties = defaultValue( propertyTexture.properties, {} ); const meshPrimitiveAttributes = defaultValue(meshPrimitive.attributes, {}); // Make sure that the `texCoord` values of the properties // refer to valid attributes of the mesh primitive const propertyTexturePropertyNames = Object.keys(propertyTextureProperties); for (const propertyName of propertyTexturePropertyNames) { const propertyTextureProperty = propertyTextureProperties[propertyName]; const propertyTexturePropertyPath = path + "/properties/" + propertyName; const texCoord = propertyTextureProperty.texCoord; if (defined(texCoord)) { const texCoordAttributeName = `TEXCOORD_${texCoord}`; const texCoordAttribute = meshPrimitiveAttributes[texCoordAttributeName]; if (!defined(texCoordAttribute)) { const message = `The property texture property defines the texCoord ${texCoord}, ` + `but the attribute ${texCoordAttributeName} was not ` + `found in the attributes of primitive ${primitiveIndex} ` + `of mesh ${meshIndex}`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( propertyTexturePropertyPath, message ); context.addIssue(issue); result = false; } } else { const texCoordAttributeName = `TEXCOORD_0`; const texCoordAttribute = meshPrimitiveAttributes[texCoordAttributeName]; if (!defined(texCoordAttribute)) { const message = `The property texture property does not define a texCoord value, ` + `defaulting to 0, but the attribute ${texCoordAttributeName} was not ` + `found in the attributes of primitive ${primitiveIndex} ` + `of mesh ${meshIndex}`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( propertyTexturePropertyPath, message ); context.addIssue(issue); result = false; } } } // If everything appeared to be valid until now, validate // the values of the property texture properties in view // of the glTF texture that they refer to if (result) { for (const propertyName of propertyTexturePropertyNames) { const propertyTextureProperty = propertyTextureProperties[propertyName]; const propertyTexturePropertyPath = path + "/properties/" + propertyName; const metadataClassName = propertyTexture.class; const propertyValuesValid = await PropertyTextureValuesValidator.validatePropertyTexturePropertyValues( propertyTexturePropertyPath, propertyName, propertyTextureProperty, schema, metadataClassName, gltfData, context ); if (!propertyValuesValid) { result = false; } } } return result; } /** * Validate the values of a single property of a property texture * * @param path - The path for `ValidationIssue` instances * @param propertyName - The property name * @param propertyTextureProperty - The property texture property * @param schema - The metadata schema * @param metadataClassName - Te class name that was given in the * surrounding property texture * @param gltfData - The glTF data * @param context - The `ValidationContext` * @returns Whether the property is valid */ private static async validatePropertyTexturePropertyValues( path: string, propertyName: string, propertyTextureProperty: any, schema: Schema, metadataClassName: string, gltfData: GltfData, context: ValidationContext ): Promise { let result = true; // The glTF structure is already assumed to be valid here const gltf = gltfData.gltf; const textureIndex = propertyTextureProperty.index; const textures = gltf.textures || []; const texture = textures[textureIndex]; const images = gltf.images || []; const imageIndex = texture.source; const image = images[imageIndex]; // The schema structure is already assumed to be valid here const classProperty = MetadataValidationUtilities.computeClassProperty( schema, metadataClassName, propertyName )!; // TODO: This will called multiple times, once for each property. // This will cause the image to be read multiple times. The image // should somehow be cached and associated with the glTF `image`. // Try to read the image data from the glTF image. // If this fails, then the appropriate issues will // be added to the given context, and `undefined` // will be returned. const imageData = await ImageDataReader.readFromImage( path, image, gltfData.binaryBufferData, context ); if (!defined(imageData)) { return false; } // Make sure that the `channels` contains only elements that // are smaller than the number of channels in the image const channelsInImage = imageData.channels; const channels = defaultValue(propertyTextureProperty.channels, [0]); const channelsValid = TextureValidator.validateChannelsForImage( path, "property texture property", channels, channelsInImage, context ); if (!channelsValid) { return false; } const keys = RangeIterables.range2D(imageData.sizeX, imageData.sizeY); // Perform the checks that only apply to ENUM types, if (classProperty.type === "ENUM") { const enumValueType = MetadataValidationUtilities.computeEnumValueType( schema, metadataClassName, propertyName )!; const enumValueValueNames = MetadataValidationUtilities.computeEnumValueValueNames( schema, metadataClassName, propertyName )!; const validEnumValueValues = MetadataValidationUtilities.computeValidEnumValueValues( schema, metadataClassName, propertyName )!; const metadataPropertyModel = PropertyTextureMetadataPropertyModels.createEnum( imageData, propertyTextureProperty, classProperty, enumValueType, enumValueValueNames ); if ( !MetadataPropertyValuesValidator.validateEnumValues( path, propertyName, keys, metadataPropertyModel, validEnumValueValues, context ) ) { result = false; } } // Perform the checks that only apply to numeric types if (ClassProperties.hasNumericType(classProperty)) { const metadataPropertyModel = PropertyTextureMetadataPropertyModels.createNumeric( imageData, propertyTextureProperty, classProperty ); if ( !MetadataPropertyValuesValidator.validateMinMax( path, propertyName, keys, metadataPropertyModel, propertyTextureProperty, "property texture", classProperty, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/gltf/structuralMetadata/PropertyTexturesDefinitionValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ValidationContext } from "../../ValidationContext"; import { ValidatedElement } from "../../ValidatedElement"; import { BasicValidator } from "../../BasicValidator"; import { PropertyTextureValidator } from "./PropertyTextureValidator"; import { StructureValidationIssues } from "../../../issues/StructureValidationIssues"; /** * A class for validating the definition of property textures. */ export class PropertyTexturesDefinitionValidator { /** * Validate the given definition of property textures. * * The returned object will contain two properties: * - `wasPresent`: Whether property textures have been given * - `validatedElement`: The validated `PropertyTexture[]` object * * When no property textures are given, then it will just return * `{false, undefined}`. * * If the given `schemaState` indicates that no schema was present, * or the property textures have not been valid according to the * schema, then an error will be added to the given context, * and `{true, undefined}` is returned. * * The method will return `{true, propertyTextures}` only if the * given property textures have been valid. * * @param path - The path for `ValidationIssue` instances * @param name - The name of the object containing the definition * (for example, 'metadata extension object') * @param propertyTextures - The actual property textures * @param gltf - The containing glTF object * @param schemaState - The state of the schema validation * @param context - The `ValidationContext` * @returns Information about the validity of the definition */ static validatePropertyTexturesDefinition( path: string, name: string, propertyTextures: any[] | undefined, gltf: any, schemaState: ValidatedElement, context: ValidationContext ): ValidatedElement { // Return immediately when there are no property textures const propertyTexturesState: ValidatedElement = { wasPresent: false, validatedElement: undefined, }; if (!defined(propertyTextures)) { return propertyTexturesState; } // There are property textures. propertyTexturesState.wasPresent = true; // Validate the propertyTextures, returning as soon as they // have been determined to be invalid const propertyTexturesPath = path + "/propertyTextures"; if (!schemaState.wasPresent) { // If there are property textures, then there MUST be a schema definition const message = `The ${name} defines 'propertyTextures' but ` + `there was no schema definition`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); return propertyTexturesState; } if (defined(schemaState.validatedElement)) { // The propertyTextures MUST be an array of at least 1 objects if ( !BasicValidator.validateArray( propertyTexturesPath, "propertyTextures", propertyTextures, 1, undefined, "object", context ) ) { return propertyTexturesState; } // Validate each propertyTexture for (let i = 0; i < propertyTextures.length; i++) { const propertyTexture = propertyTextures[i]; const propertyTexturePath = propertyTexturesPath + "/" + i; if ( !PropertyTextureValidator.validatePropertyTexture( propertyTexturePath, propertyTexture, gltf, schemaState.validatedElement, context ) ) { return propertyTexturesState; } } } // The property textures have been determined to be valid. // Return them as the validatedElement in the returned // state: propertyTexturesState.validatedElement = propertyTextures; return propertyTexturesState; } } ================================================ FILE: src/validation/legacy/BoundingVolumeChecks.ts ================================================ // Mostly taken from https://github.com/CesiumGS/3d-tiles-validator/tree/e84202480eb6572383008076150c8e52c99af3c3 import { BoundingSphere, Cartesian3, Intersect, Math, Matrix3, Matrix4, Plane, } from "cesium"; import { defined } from "3d-tiles-tools"; import { BoundingVolume } from "3d-tiles-tools"; /** * The checks for bounding volumes from the the original 3d-tiles-validator. */ export class BoundingVolumeChecks { /** * The only public method: * * Checks if the given inner bounding volume is contained in * the given outer bounding volume, taking the given transforms * into account. * * If the inner bounding volume is contained in the outer one, * then `undefined` is returned. * Otherwise, an error message is returned. * * @param innerBoundingVolume - The inner `BoundingVolume` * @param outerBoundingVolume - The outer `BoundingVolume` * @param innerTransformArray - The inner transform as an array of 16 elements * @param outerTransformArray - The outer transform as an array of 16 elements * @returns An error message, or `undefined` */ static checkBoundingVolume( innerBoundingVolume: BoundingVolume, outerBoundingVolume: BoundingVolume, innerTransformArray: number[] | undefined, outerTransformArray: number[] | undefined ): string | undefined { let innerTransform = Matrix4.IDENTITY; if (defined(innerTransformArray)) { innerTransform = Matrix4.fromArray(innerTransformArray); } let outerTransform = Matrix4.IDENTITY; if (defined(outerTransformArray)) { outerTransform = Matrix4.fromArray(outerTransformArray); } if (defined(innerBoundingVolume.box) && defined(outerBoundingVolume.box)) { // Box in Box check const transformedInnerTile = BoundingVolumeChecks.getTransformedBox( innerBoundingVolume.box, innerTransform ); const transformedOuterTile = BoundingVolumeChecks.getTransformedBox( outerBoundingVolume.box, outerTransform ); if ( !BoundingVolumeChecks.boxInsideBox( transformedInnerTile, transformedOuterTile ) ) { return `box [${innerBoundingVolume.box}] is not within box [${outerBoundingVolume.box}]`; } } else if ( defined(innerBoundingVolume.sphere) && defined(outerBoundingVolume.sphere) ) { // Sphere in Sphere const transformedInnerTile = BoundingVolumeChecks.getTransformedSphere( innerBoundingVolume.sphere, innerTransform ); const transformedOuterTile = BoundingVolumeChecks.getTransformedSphere( outerBoundingVolume.sphere, outerTransform ); if ( !BoundingVolumeChecks.sphereInsideSphere( transformedInnerTile, transformedOuterTile ) ) { return `sphere [${innerBoundingVolume.sphere}] is not within sphere [${outerBoundingVolume.sphere}]`; } } else if ( defined(innerBoundingVolume.region) && defined(outerBoundingVolume.region) ) { // Region in Region // Region does not update with transform const transformedInnerTile = innerBoundingVolume.region; const transformedOuterTile = outerBoundingVolume.region; if ( !BoundingVolumeChecks.regionInsideRegion( transformedInnerTile, transformedOuterTile ) ) { return `region [${innerBoundingVolume.region}] is not within region [${outerBoundingVolume.region}]`; } } else if ( defined(innerBoundingVolume.box) && defined(outerBoundingVolume.sphere) ) { // Box in Sphere const transformedInnerTile = BoundingVolumeChecks.getTransformedBox( innerBoundingVolume.box, innerTransform ); const transformedOuterTile = BoundingVolumeChecks.getTransformedSphere( outerBoundingVolume.sphere, outerTransform ); if ( !BoundingVolumeChecks.boxInsideSphere( transformedInnerTile, transformedOuterTile ) ) { return `box [${innerBoundingVolume.box}] is not within sphere [${outerBoundingVolume.sphere}]`; } } else if ( defined(innerBoundingVolume.sphere) && defined(outerBoundingVolume.box) ) { // Sphere in Box const transformedInnerTile = BoundingVolumeChecks.getTransformedSphere( innerBoundingVolume.sphere, innerTransform ); const transformedOuterTile = BoundingVolumeChecks.getTransformedBox( outerBoundingVolume.box, outerTransform ); if ( !BoundingVolumeChecks.sphereInsideBox( transformedInnerTile, transformedOuterTile ) ) { return `sphere [${innerBoundingVolume.sphere}] is not within box [${outerBoundingVolume.box}]`; } } } private static readonly scratchMatrix = new Matrix3(); private static readonly scratchHalfAxes = new Matrix3(); private static readonly scratchCenter = new Cartesian3(); private static readonly scratchScale = new Cartesian3(); private static getTransformedBox(box: number[], transform: Matrix4) { let center = Cartesian3.fromElements( box[0], box[1], box[2], BoundingVolumeChecks.scratchCenter ); let halfAxes = Matrix3.fromArray( box, 3, BoundingVolumeChecks.scratchHalfAxes ); // Find the transformed center and halfAxes center = Matrix4.multiplyByPoint(transform, center, center); const rotationScale = Matrix4.getMatrix3( transform, BoundingVolumeChecks.scratchMatrix ); halfAxes = Matrix3.multiply(rotationScale, halfAxes, halfAxes); // Return a Box array const returnBox = [ center.x, center.y, center.z, halfAxes[0], halfAxes[1], halfAxes[2], halfAxes[3], halfAxes[4], halfAxes[5], halfAxes[6], halfAxes[7], halfAxes[8], ]; return returnBox; } private static getTransformedSphere(sphere: number[], transform: Matrix4) { let center = Cartesian3.fromElements( sphere[0], sphere[1], sphere[2], BoundingVolumeChecks.scratchCenter ); let radius = sphere[3]; // Find the transformed center and radius center = Matrix4.multiplyByPoint(transform, center, center); const scale = Matrix4.getScale( transform, BoundingVolumeChecks.scratchScale ); const uniformScale = Cartesian3.maximumComponent(scale); radius *= uniformScale; // Return a Sphere array const returnSphere = [center.x, center.y, center.z, radius]; return returnSphere; } private static regionInsideRegion( regionInner: number[], regionOuter: number[] ) { return ( regionInner[0] >= regionOuter[0] && regionInner[1] >= regionOuter[1] && regionInner[2] <= regionOuter[2] && regionInner[3] <= regionOuter[3] && regionInner[4] >= regionOuter[4] && regionInner[5] <= regionOuter[5] ); } private static readonly scratchInnerCenter = new Cartesian3(); private static readonly scratchOuterCenter = new Cartesian3(); private static sphereInsideSphere( sphereInner: number[], sphereOuter: number[] ) { const radiusInner = sphereInner[3]; const radiusOuter = sphereOuter[3]; const centerInner = Cartesian3.unpack( sphereInner, 0, BoundingVolumeChecks.scratchInnerCenter ); const centerOuter = Cartesian3.unpack( sphereOuter, 0, BoundingVolumeChecks.scratchOuterCenter ); const distance = Cartesian3.distance(centerInner, centerOuter); return distance <= radiusOuter - radiusInner; } private static readonly scratchInnerHalfAxes = new Matrix3(); private static readonly scratchOuterHalfAxes = new Matrix3(); private static boxInsideBox(boxInner: number[], boxOuter: number[]) { const centerInner = Cartesian3.fromElements( boxInner[0], boxInner[1], boxInner[2], BoundingVolumeChecks.scratchInnerCenter ); const halfAxesInner = Matrix3.fromArray( boxInner, 3, BoundingVolumeChecks.scratchInnerHalfAxes ); const transformInner = Matrix4.fromRotationTranslation( halfAxesInner, centerInner ); const centerOuter = Cartesian3.fromElements( boxOuter[0], boxOuter[1], boxOuter[2], BoundingVolumeChecks.scratchOuterCenter ); const halfAxesOuter = Matrix3.fromArray( boxOuter, 3, BoundingVolumeChecks.scratchOuterHalfAxes ); const transformOuter = Matrix4.fromRotationTranslation( halfAxesOuter, centerOuter ); const cube = BoundingVolumeChecks.createUnitCube(); const transformInnerInverse = Matrix4.inverse( transformOuter, transformOuter ); for (let i = 0; i < 8; i++) { cube[i] = Matrix4.multiplyByPoint(transformInner, cube[i], cube[i]); cube[i] = Matrix4.multiplyByPoint( transformInnerInverse, cube[i], cube[i] ); const min = Cartesian3.minimumComponent(cube[i]); const max = Cartesian3.maximumComponent(cube[i]); if (min < -1.0 - Math.EPSILON8 || max > 1.0 + Math.EPSILON8) { return false; } } return true; } private static readonly scratchBoxCenter = new Cartesian3(); private static readonly scratchSphereCenter = new Cartesian3(); private static readonly scratchBoxHalfAxes = new Matrix3(); private static boxInsideSphere(box: number[], sphere: number[]) { const centerBox = Cartesian3.fromElements( box[0], box[1], box[2], BoundingVolumeChecks.scratchBoxCenter ); const halfAxesBox = Matrix3.fromArray( box, 3, BoundingVolumeChecks.scratchBoxHalfAxes ); const transformBox = Matrix4.fromRotationTranslation( halfAxesBox, centerBox ); const radiusSphere = sphere[3]; const centerSphere = Cartesian3.unpack( sphere, 0, BoundingVolumeChecks.scratchSphereCenter ); const cube = BoundingVolumeChecks.createUnitCube(); for (let i = 0; i < 8; i++) { cube[i] = Matrix4.multiplyByPoint(transformBox, cube[i], cube[i]); const distance = Cartesian3.distance(cube[i], centerSphere); if (distance > radiusSphere) { return false; } } return true; } private static sphereInsideBox(sphere: number[], box: number[]) { const centerBox = Cartesian3.fromElements( box[0], box[1], box[2], BoundingVolumeChecks.scratchBoxCenter ); const halfAxesBox = Matrix3.fromArray( box, 3, BoundingVolumeChecks.scratchBoxHalfAxes ); const transformBox = Matrix4.fromRotationTranslation( halfAxesBox, centerBox ); const radiusSphere = sphere[3]; const centerSphere = Cartesian3.unpack( sphere, 0, BoundingVolumeChecks.scratchSphereCenter ); const cube = BoundingVolumeChecks.createUnitCube(); for (let i = 0; i < 8; i++) { cube[i] = Matrix4.multiplyByPoint(transformBox, cube[i], cube[i]); } const face = new Array(6); face[0] = BoundingVolumeChecks.planeFromPoints(cube[0], cube[1], cube[2]); face[1] = BoundingVolumeChecks.planeFromPoints(cube[2], cube[6], cube[7]); face[2] = BoundingVolumeChecks.planeFromPoints(cube[6], cube[5], cube[4]); face[3] = BoundingVolumeChecks.planeFromPoints(cube[5], cube[1], cube[0]); face[4] = BoundingVolumeChecks.planeFromPoints(cube[6], cube[2], cube[1]); face[5] = BoundingVolumeChecks.planeFromPoints(cube[0], cube[3], cube[7]); const boundingSphere = new BoundingSphere(centerSphere, radiusSphere); for (let i = 0; i < 6; i++) { const intersection = BoundingSphere.intersectPlane( boundingSphere, face[i] ); if (intersection !== Intersect.INSIDE) { return false; } } return true; } private static planeFromPoints( point1: Cartesian3, point2: Cartesian3, point3: Cartesian3 ): Plane { const a = new Cartesian3(); const b = new Cartesian3(); const c = new Cartesian3(); const normal = new Cartesian3(); Cartesian3.subtract(point2, point1, a); Cartesian3.subtract(point3, point2, b); Cartesian3.cross(a, b, c); Cartesian3.normalize(c, normal); return Plane.fromPointNormal(point1, normal); } private static createUnitCube(): Array { const cube = new Array(8); cube[0] = new Cartesian3(-1, -1, -1); cube[1] = new Cartesian3(-1, -1, 1); cube[2] = new Cartesian3(1, -1, 1); cube[3] = new Cartesian3(1, -1, -1); cube[4] = new Cartesian3(-1, 1, -1); cube[5] = new Cartesian3(-1, 1, 1); cube[6] = new Cartesian3(1, 1, 1); cube[7] = new Cartesian3(1, 1, -1); return cube; } } ================================================ FILE: src/validation/metadata/BinaryPropertyTableDefaultMetadataPropertyModel.ts ================================================ import { PropertyModel } from "3d-tiles-tools"; import { MetadataValues } from "3d-tiles-tools"; import { BinaryPropertyModels } from "3d-tiles-tools"; import { BinaryPropertyTable } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { MetadataPropertyModel } from "./MetadataPropertyModel"; /** * Implementation of a `MetadataPropertyModel` for properties * that are stored in binary property tables, and that are not * ENUM properties. * * @internal */ export class BinaryPropertyTableDefaultMetadataPropertyModel implements MetadataPropertyModel { /** * The property table property that is represented by this model */ private readonly propertyTableProperty: any; /** * The class property that defines the structure of the property */ private readonly classProperty: ClassProperty; /** * The property model for the property */ private readonly propertyModel: PropertyModel; /** * Creates a new instance * * @param binaryPropertyTable - The binary property table * @param propertyName - The property name * @param propertyTableProperty - The property table property * @param classProperty - The class property */ constructor( binaryPropertyTable: BinaryPropertyTable, propertyName: string, propertyTableProperty: any, classProperty: ClassProperty ) { this.propertyTableProperty = propertyTableProperty; this.classProperty = classProperty; this.propertyModel = BinaryPropertyModels.createPropertyModel( binaryPropertyTable, propertyName ); } /** {@inheritDoc MetadataPropertyModel.getPropertyValue} */ getPropertyValue(key: number) { const propertyAttributeProperty = this.propertyTableProperty; const classProperty = this.classProperty; const offsetOverride = propertyAttributeProperty.offset; const scaleOverride = propertyAttributeProperty.scale; const value = this.getRawPropertyValue(key); const processedValue = MetadataValues.processValue( classProperty, offsetOverride, scaleOverride, value ); return processedValue; } /** {@inheritDoc MetadataPropertyModel.getRawPropertyValue} */ getRawPropertyValue(key: number) { return this.propertyModel.getPropertyValue(key); } } ================================================ FILE: src/validation/metadata/BinaryPropertyTableEnumMetadataPropertyModel.ts ================================================ import { PropertyModel } from "3d-tiles-tools"; import { MetadataValues } from "3d-tiles-tools"; import { BinaryPropertyModels } from "3d-tiles-tools"; import { BinaryPropertyTable } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { MetadataPropertyModel } from "./MetadataPropertyModel"; /** * Implementation of a `MetadataPropertyModel` for ENUM properties * in a binary property table * * @internal */ export class BinaryPropertyTableEnumMetadataPropertyModel implements MetadataPropertyModel { /** * The class property that defines the structure of the property */ private readonly classProperty: ClassProperty; /** * The mapping from enum value values to enum value names for * the enum type of the given class property */ private readonly enumValueValueNames: { [key: number]: string }; /** * The property model for the property */ private readonly propertyModel: PropertyModel; /** * Creates a new instance * * @param binaryPropertyTable - The binary property table * @param propertyName - The property name * @param propertyTableProperty - The property table property * @param classProperty - The class property * @param enumValueValueNames - The mapping from enum value values * to enum value names for the enum type of the given class * property */ constructor( binaryPropertyTable: BinaryPropertyTable, propertyName: string, classProperty: ClassProperty, enumValueValueNames: { [key: number]: string } ) { this.classProperty = classProperty; this.enumValueValueNames = enumValueValueNames; this.propertyModel = BinaryPropertyModels.createPropertyModel( binaryPropertyTable, propertyName ); } /** {@inheritDoc MetadataPropertyModel.getPropertyValue} */ getPropertyValue(key: number) { const classProperty = this.classProperty; const value = this.getRawPropertyValue(key); const processedValue = MetadataValues.processNumericEnumValue( classProperty, this.enumValueValueNames, value ); return processedValue; } /** {@inheritDoc MetadataPropertyModel.getRawPropertyValue} */ getRawPropertyValue(key: number) { return this.propertyModel.getPropertyValue(key); } } ================================================ FILE: src/validation/metadata/BinaryPropertyTableValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { BinaryPropertyTable } from "3d-tiles-tools"; import { NumericBuffers } from "3d-tiles-tools"; import { MetadataComponentTypes } from "3d-tiles-tools"; import { MetadataTypes } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; import { BinaryPropertyTableValuesValidator } from "./BinaryPropertyTableValuesValidator"; /** * A class for validations related to BinaryPropertyTable objects. * * @internal */ export class BinaryPropertyTableValidator { /** * Performs the validation to ensure that the given object is a * valid `BinaryPropertyTable`. * * @param path - The path for the `ValidationIssue` instances * @param binaryPropertyTable - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateBinaryPropertyTable( path: string, binaryPropertyTable: BinaryPropertyTable, context: ValidationContext ): boolean { let result = true; const binaryMetadata = binaryPropertyTable.binaryMetadata; const metadataClass = binaryMetadata.metadataClass; const classProperties = defaultValue(metadataClass.properties, {}); for (const propertyId of Object.keys(classProperties)) { const classProperty = classProperties[propertyId]; const propertyPath = path + "/properties/" + propertyId; // Obtain the property table property const propertyTable = binaryPropertyTable.propertyTable; const propertyTableProperties = defaultValue( propertyTable.properties, {} ); const propertyTableProperty = propertyTableProperties[propertyId]; // Validate that the property is actually present when it // is "required" if (!defined(propertyTableProperty)) { const required = classProperty.required ?? false; if (required) { const issue = MetadataValidationIssues.METADATA_VALUE_REQUIRED_BUT_MISSING( path, propertyId ); context.addIssue(issue); result = false; } } else { // Perform the structural validation of the property, checking // for the presence of the necessary buffer views (values, // arrayOffsets, and stringOffsets), depending on the type // of the property. This does not yet check the actual values // that are stored in the "values" buffer view. This is done // below, in validateBinaryPropertyTableValues if ( !BinaryPropertyTableValidator.validateBinaryPropertyTableProperty( propertyPath, propertyId, classProperty, binaryPropertyTable, context ) ) { result = false; } } } // Only if the basic validity checks passed, perform // the validation of the metadata VALUES if (result) { if ( !BinaryPropertyTableValuesValidator.validateBinaryPropertyTableValues( path, binaryPropertyTable, context ) ) { result = true; } } return result; } /** * Validate a single property of a `BinaryPropertyTable` * * @param path - The path of the `PropertyTableProperty`, for * `ValidationIssue` instances * @param propertyId - The property ID * @param classProperty - The `ClassProperty` * @param binaryPropertyTable - The `BinaryPropertyTable` * @param context - The `ValidationContext` * @returns Whether the property is valid */ private static validateBinaryPropertyTableProperty( path: string, propertyId: string, classProperty: ClassProperty, binaryPropertyTable: BinaryPropertyTable, context: ValidationContext ): boolean { let result = true; const propertyTable = binaryPropertyTable.propertyTable; const propertyTableCount = propertyTable.count; const type = classProperty.type; const count = classProperty.count; const isArray = classProperty.array === true; const isVariableLengthArray = isArray && !defined(count); // If the property is a variable-length array, validate // the 'arrayOffsets' buffer view. if (isVariableLengthArray) { if ( !BinaryPropertyTableValidator.validateArrayOffsetsBufferView( path, propertyId, binaryPropertyTable, context ) ) { result = false; // Bail out early when the arrayOffsets are not valid return result; } } // The following assumes that the arrayOffsets are valid: // If the property is a STRING property, validate // the 'stringOffsets' buffer view if (type === "STRING") { let numStrings = propertyTableCount; if (isVariableLengthArray) { numStrings = BinaryPropertyTableValidator.getValidatedArrayOffset( propertyId, propertyTableCount, binaryPropertyTable ); } else if (isArray) { numStrings = propertyTableCount * count!; } if ( !BinaryPropertyTableValidator.validateStringOffsetsBufferView( path, propertyId, binaryPropertyTable, numStrings, context ) ) { result = false; // Bail out early when the stringOffsets are not valid return result; } } // Validate the 'values' buffer view if ( !BinaryPropertyTableValidator.validateValuesBufferView( path, propertyId, classProperty, binaryPropertyTable, context ) ) { result = false; } return result; } /** * Validates the 'values' buffer view of the specified property, * to see whether it has the right byteOffset and byteLength. * * This is assumed to be called after the 'arrayOffsets' and * 'stringOffsets' have been validated for types that require * them. * * @param path - The path of the `PropertyTableProperty`, for * `ValidationIssue` instances * @param propertyId - The property ID * @param classProperty - The `ClassProperty` * @param binaryPropertyTable - The `BinaryPropertyTable` * @param context - The `ValidationContext` * @returns Whether the values are valid */ private static validateValuesBufferView( path: string, propertyId: string, classProperty: ClassProperty, binaryPropertyTable: BinaryPropertyTable, context: ValidationContext ): boolean { let result = true; const type = classProperty.type; // Determine the component type: By default, it is given by // the class property. For enum types, it is looked up in // the enumValueTypes dictionary. For other types (STRING // and BOOLEAN), it defaults to UINT8 (bytes) let componentType = classProperty.componentType; if (type === "ENUM") { const enumType = classProperty.enumType!; const binaryMetadata = binaryPropertyTable.binaryMetadata; const binaryEnumInfo = binaryMetadata.binaryEnumInfo; const enumValueTypes = binaryEnumInfo.enumValueTypes; componentType = enumValueTypes[enumType]; } else if (!defined(componentType)) { componentType = "UINT8"; } // Obtain the `PropertyTableProperty` const propertyTable = binaryPropertyTable.propertyTable; const propertyTableProperties = defaultValue(propertyTable.properties, {}); const propertyTableProperty = propertyTableProperties[propertyId]; // Obtain the `values` information const valuesBufferViewIndex = propertyTableProperty.values; // Validate the byte offset of the component type requires // a specific alignment const requiresAlignment = componentType != "UINT8" && componentType != "INT8"; if (requiresAlignment) { // Validate the `values` `byteOffset` if ( !BinaryPropertyTableValidator.validateBufferViewByteOffset( path, propertyId, "values", valuesBufferViewIndex, componentType, binaryPropertyTable, context ) ) { result = false; } } // Compute the number of values that are stored in // the 'values' buffer view, depending on the type // of the property and the property table count const numValues = BinaryPropertyTableValidator.computeNumberOfValues( propertyId, binaryPropertyTable ); let expectedByteLength; if (type === "BOOLEAN") { expectedByteLength = Math.ceil(numValues / 8); } else { const componentTypeByteSize = MetadataComponentTypes.byteSizeForComponentType(componentType); expectedByteLength = numValues * componentTypeByteSize; } // Validate that the length of the 'values' buffer // view is sufficient for storing the values. if ( !BinaryPropertyTableValidator.validateValuesBufferViewByteLength( path, propertyId, valuesBufferViewIndex, componentType, binaryPropertyTable, numValues, expectedByteLength, context ) ) { result = false; } return result; } /** * Validates the `arrayOffsets` of the specified property, * to see whether it has the right byteOffset, byteLength, * and contains ascending values. * * This assumes that the specified property is a variable-length * property. * * @param path - The path of the `PropertyTableProperty`, for * `ValidationIssue` instances * @param propertyId - The property ID * @param binaryPropertyTable - The `BinaryPropertyTable` * @param context - The `ValidationContext` * @returns Whether the property was valid */ private static validateArrayOffsetsBufferView( path: string, propertyId: string, binaryPropertyTable: BinaryPropertyTable, context: ValidationContext ): boolean { let result = true; // Obtain the `PropertyTableProperty` const propertyTable = binaryPropertyTable.propertyTable; const propertyTableProperties = defaultValue(propertyTable.properties, {}); const propertyTableProperty = propertyTableProperties[propertyId]; // Obtain the `arrayOffsets` information const arrayOffsetsBufferViewIndex = propertyTableProperty.arrayOffsets!; const arrayOffsetType = defaultValue( propertyTableProperty.arrayOffsetType, "UINT32" ); // Validate the `arrayOffsets` `byteOffset` if ( !BinaryPropertyTableValidator.validateBufferViewByteOffset( path, propertyId, "arrayOffsets", arrayOffsetsBufferViewIndex, arrayOffsetType, binaryPropertyTable, context ) ) { result = false; } // Validate the `arrayOffsets` `byteLength` const propertyTableCount = propertyTable.count; const numArrayOffsetValues = propertyTableCount + 1; if ( !BinaryPropertyTableValidator.validateOffsetBufferViewByteLength( path, propertyId, "arrayOffsets", arrayOffsetsBufferViewIndex, arrayOffsetType, binaryPropertyTable, numArrayOffsetValues, context ) ) { result = false; } // Only if the basic properties have been valid, // Validate that the offsets are ascending if (result) { if ( !BinaryPropertyTableValidator.validateOffsets( path, propertyId, "arrayOffsets", arrayOffsetsBufferViewIndex, arrayOffsetType, binaryPropertyTable, context ) ) { result = false; } } return result; } /** * Validates the `stringOffsets` of the specified property, * to see whether it has the right byteOffset, byteLength, * and contains ascending values. * * This assumes that the specified property is a STRING property * * @param path - The path of the `PropertyTableProperty`, for * `ValidationIssue` instances * @param propertyId - The property ID * @param binaryPropertyTable - The `BinaryPropertyTable` * @param numStrings - The number of strings. For non-array properties, * this is just the `propertyTable.count`. For fixed-length array * properties, this is `propertyTable.count * classProperty.count`. * For variable-length array properties, this is the last value * in the `arrayOffsets`. * @param context - The `ValidationContext` * @returns Whether the property was valid */ private static validateStringOffsetsBufferView( path: string, propertyId: string, binaryPropertyTable: BinaryPropertyTable, numStrings: number, context: ValidationContext ): boolean { let result = true; // Obtain the `PropertyTableProperty` const propertyTable = binaryPropertyTable.propertyTable; const propertyTableProperties = defaultValue(propertyTable.properties, {}); const propertyTableProperty = propertyTableProperties[propertyId]; // Obtain the `stringOffsets` information const stringOffsetsBufferViewIndex = propertyTableProperty.stringOffsets!; const stringOffsetType = defaultValue( propertyTableProperty.stringOffsetType, "UINT32" ); // Validate the `stringOffsets` `byteOffset` if ( !BinaryPropertyTableValidator.validateBufferViewByteOffset( path, propertyId, "stringOffsets", stringOffsetsBufferViewIndex, stringOffsetType, binaryPropertyTable, context ) ) { result = false; } // Validate the `stringOffsets` `byteLength` const numStringOffsetValues = numStrings + 1; if ( !BinaryPropertyTableValidator.validateOffsetBufferViewByteLength( path, propertyId, "stringOffsets", stringOffsetsBufferViewIndex, stringOffsetType, binaryPropertyTable, numStringOffsetValues, context ) ) { result = false; } // Only if the basic properties have been valid, // Validate that the offsets are ascending if (result) { if ( !BinaryPropertyTableValidator.validateOffsets( path, propertyId, "stringOffsets", stringOffsetsBufferViewIndex, stringOffsetType, binaryPropertyTable, context ) ) { result = false; } } return result; } /** * Validate that the offsets in the specified buffer view are ascending. * * This is used for `arrayOffsets` or `stringOffsets`, which are supposed * to contain ascending numbers (not necessarily strictly ascending). * * @param propertyPath - The base path for `ValidationIssue` instances * @param propertyId - The property ID * @param bufferViewName - The name of the buffer view ('arrayOffsets', * or 'stringOffsets') * @param bufferViewIndex - The index of the buffer view (i.e. the * actual value of 'arrayOffsets', or 'stringOffsets') * @param componentType - The component type. This is either the * `arrayOffsetsType` or `stringOffsetsType` * @param binaryPropertyTable - The `BinaryPropertyTable` * @param context - The `ValidationContext` * @returns Whether the offsets are valid */ private static validateOffsets( propertyPath: string, propertyId: string, bufferViewName: string, bufferViewIndex: number, componentType: string, binaryPropertyTable: BinaryPropertyTable, context: ValidationContext ): boolean { const path = propertyPath + "/" + bufferViewName; let result = true; const binaryMetadata = binaryPropertyTable.binaryMetadata; const binaryBufferData = binaryMetadata.binaryBufferData; const bufferViewsData = defaultValue(binaryBufferData.bufferViewsData, []); const bufferVieData = bufferViewsData[bufferViewIndex]; const array = NumericBuffers.getNumericBufferAsArray( bufferVieData, componentType ); for (let i = 0; i < array.length - 1; i++) { const value0 = array[i]; const value1 = array[i + 1]; if (value0 > value1) { const message = `The '${bufferViewName}' buffer view of property '${propertyId}' ` + `must contain ascending values, but for the buffer view with ` + `index ${bufferViewIndex} the value at index ${i} is ${value0} ` + `and the value at index ${i + 1} is ${value1}`; const issue = MetadataValidationIssues.METADATA_INVALID_OFFSETS( path, message ); context.addIssue(issue); result = false; } } return result; } /** * Validate the byte offset of the specified buffer view. * * The byte offset must be aligned to a multiple of the * size of the component type. * * @param propertyPath - The base path for `ValidationIssue` instances * @param propertyId - The property ID * @param bufferViewName - The name of the buffer view ('values', * 'arrayOffsets', or 'stringOffsets') * @param bufferViewIndex - The index of the buffer view (i.e. the * actual value of 'values', 'arrayOffsets', or 'stringOffsets') * @param componentType - The component type. This is either the * component type of the property, or the `arrayOffsetsType` * or `stringOffsetsType` * @param binaryPropertyTable - The `BinaryPropertyTable` * @param context - The `ValidationContext` * @returns Whether the byte offset was valid */ private static validateBufferViewByteOffset( propertyPath: string, propertyId: string, bufferViewName: string, bufferViewIndex: number, componentType: string, binaryPropertyTable: BinaryPropertyTable, context: ValidationContext ): boolean { const path = propertyPath + "/" + bufferViewName; let result = true; const binaryMetadata = binaryPropertyTable.binaryMetadata; const binaryBufferStructure = binaryMetadata.binaryBufferStructure; const bufferViews = defaultValue(binaryBufferStructure.bufferViews, []); const bufferView = bufferViews[bufferViewIndex]; const componentTypeByteSize = MetadataComponentTypes.byteSizeForComponentType(componentType); const byteOffset = bufferView.byteOffset; const misalignment = byteOffset % componentTypeByteSize; if (misalignment !== 0) { const message = `The '${bufferViewName}' buffer view of property '${propertyId}' ` + `has component type '${componentType}', which requires the ` + `buffer view to be aligned to ${componentTypeByteSize} bytes, ` + `but the buffer view with index ${bufferViewIndex} has a ` + `byteOffset of ${byteOffset}, causing a misalignment ` + `of ${misalignment} bytes`; const issue = MetadataValidationIssues.METADATA_INVALID_ALIGNMENT( path, message ); context.addIssue(issue); result = false; } return result; } /** * Validate the byte length of the specified buffer view. * * The byte length must be `numValues*sizeof(componentType)`. * * This is intended for buffer views that are `arrayOffsets` * or `stringOffsets`. * * @param propertyPath - The path for `ValidationIssue` instances * @param propertyId - The property ID * @param bufferViewName - The name of the buffer view * ('arrayOffsets', or 'stringOffsets') * @param bufferViewIndex - The index of the buffer view (i.e. the * actual value of 'values', 'arrayOffsets', or 'stringOffsets') * @param componentType - The component type. This is either the * `arrayOffsetsType` or `stringOffsetsType` * @param binaryPropertyTable - The `BinaryPropertyTable` * @param numValues - The number of values in the buffer view. * @param context - The `ValidationContext` * @returns Whether the byte length was valid */ private static validateOffsetBufferViewByteLength( propertyPath: string, propertyId: string, bufferViewName: string, bufferViewIndex: number, componentType: string, binaryPropertyTable: BinaryPropertyTable, numValues: number, context: ValidationContext ): boolean { const path = propertyPath + "/" + bufferViewName; let result = true; const propertyTable = binaryPropertyTable.propertyTable; const propertyTableCount = propertyTable.count; const binaryMetadata = binaryPropertyTable.binaryMetadata; const binaryBufferStructure = binaryMetadata.binaryBufferStructure; const bufferViews = defaultValue(binaryBufferStructure.bufferViews, []); const bufferView = bufferViews[bufferViewIndex]; // Compute the expected number of bytes. const componentTypeByteSize = MetadataComponentTypes.byteSizeForComponentType(componentType); const expectedByteLength = numValues * componentTypeByteSize; const actualByteLength = bufferView.byteLength; if (actualByteLength !== expectedByteLength) { const message = `The '${bufferViewName}' buffer view of property '${propertyId}' ` + `has component type '${componentType}', and is part of a ` + `property table with a 'count' of ${propertyTableCount}, so it must ` + `have a byteLength of ${numValues}*${componentTypeByteSize} = ` + `${expectedByteLength}. But the buffer view with index ` + `${bufferViewIndex} has a byteLength of ${actualByteLength}`; const issue = MetadataValidationIssues.METADATA_INVALID_LENGTH( path, message ); context.addIssue(issue); result = false; } return result; } /** * Validate the byte length of the specified buffer view. * * The byte length must be `numValues*sizeof(componentType)`. * * This is intended for buffer views that contain the values * of STRING typed properties. * * @param propertyPath - The path for `ValidationIssue` instances * @param propertyId - The property ID * @param bufferViewIndex - The index of the buffer view (i.e. the * actual value of the 'values') * @param componentType - The resolved component type (this is * assumed to already have possible default values, like * UINT8 for BOOLEAN and STRING types) * @param binaryPropertyTable - The `BinaryPropertyTable` * @param numValues - The number of values in the buffer view. * @param context - The `ValidationContext` * @returns Whether the byte length was valid */ private static validateValuesBufferViewByteLength( propertyPath: string, propertyId: string, bufferViewIndex: number, componentType: string, binaryPropertyTable: BinaryPropertyTable, numValues: number, expectedByteLength: number, context: ValidationContext ): boolean { const path = propertyPath + "/values"; let result = true; const binaryMetadata = binaryPropertyTable.binaryMetadata; const binaryBufferStructure = binaryMetadata.binaryBufferStructure; const bufferViews = defaultValue(binaryBufferStructure.bufferViews, []); const bufferView = bufferViews[bufferViewIndex]; const actualByteLength = bufferView.byteLength; if (actualByteLength !== expectedByteLength) { const message = BinaryPropertyTableValidator.createByteLengthMessage( propertyId, binaryPropertyTable, componentType, numValues, expectedByteLength ); const issue = MetadataValidationIssues.METADATA_INVALID_LENGTH( path, message ); context.addIssue(issue); result = false; } return result; } /** * Creates an elaborate error message explaining why a certain * buffer view byte length was expected, when the actual byte * length did not match the expected one. * * @param propertyId - The property ID * @param binaryPropertyTable - The `BinaryPropertyTable` * @param componentType - The component type. This is assumed * to already have default values (e.g. UINT8 for BOOLEAN) * @param numValues - The number of values, as computed with * `computeNumberOfValues` * @param expectedByteLength - The expected byte length * @returns The error message */ private static createByteLengthMessage( propertyId: string, binaryPropertyTable: BinaryPropertyTable, componentType: string, numValues: number, expectedByteLength: number ): string { const propertyTable = binaryPropertyTable.propertyTable; const propertyTableCount = propertyTable.count; const binaryMetadata = binaryPropertyTable.binaryMetadata; const metadataClass = binaryMetadata.metadataClass; const classProperties = defaultValue(metadataClass.properties, {}); const classProperty = classProperties[propertyId]; const propertyTableProperties = defaultValue(propertyTable.properties, {}); const propertyTableProperty = propertyTableProperties[propertyId]; const valuesBufferViewIndex = propertyTableProperty.values; const binaryBufferStructure = binaryMetadata.binaryBufferStructure; const bufferViews = defaultValue(binaryBufferStructure.bufferViews, []); const valuesBufferView = bufferViews[valuesBufferViewIndex]; const type = classProperty.type; const count = classProperty.count; const isArray = classProperty.array === true; const isVariableLengthArray = isArray && !defined(count); const componentCount = MetadataTypes.componentCountForType(type); const componentTypeByteSize = MetadataComponentTypes.byteSizeForComponentType(componentType); const actualByteLength = valuesBufferView.byteLength; if (isVariableLengthArray) { // For variable-length string arrays, the number of bytes // is just the number of values (as obtained from the // last string offset) if (type === "STRING") { const message = `The 'values' buffer view of property '${propertyId}' ` + `stores the values of variable-length string arrays. ` + `The last 'stringOffsets' value indicates that there ` + `should be ${numValues} bytes in these strings. ` + `But the buffer view with index ${valuesBufferViewIndex} ` + `has a byteLength of ${actualByteLength}.`; return message; } // For variable-length boolean arrays, the number of values // is given by the last array offset, and the number of // bytes is ceil(numValues/8). if (type === "BOOLEAN") { const message = `The 'values' buffer view of property '${propertyId}' ` + `stores the values of variable-length boolean arrays. ` + `The last 'arrayOffsets' value indicates that there ` + `should be ${numValues} values. ` + `The buffer view should have a byteLength of ` + `ceil(${numValues}/8) = ${expectedByteLength}. ` + `But the buffer view with index ${valuesBufferViewIndex} ` + `has a byteLength of ${actualByteLength}.`; return message; } // For non-STRING, non-BOOLEAN variable length arrays, the // number of values is given by the last array offset. // The number of bytes is the number of values, multiplied // the the component size. const message = `The 'values' buffer view of property '${propertyId}' ` + `stores the values of variable-length arrays with ` + `type ${type} and component type ${componentType}. ` + `The last 'arrayOffsets' value indicates that there ` + `should be ${numValues} values, so the buffer view should have ` + `a byteLength of ${numValues}*${componentTypeByteSize} = ` + `${expectedByteLength}. ` + `But the buffer view with index ${valuesBufferViewIndex} ` + `has a byteLength of ${actualByteLength}.`; return message; } // Handling fixed-length arrays if (isArray) { // For fixed-length STRING arrays, the number of // bytes is just the number of values, as obtained // from the last string offset if (type === "STRING") { const message = `The 'values' buffer view of property '${propertyId}' ` + `stores the values of fixed-length string arrays ` + `with length ${count}. ` + `The last 'stringOffsets' value indicates that there ` + `should be ${numValues} bytes in these strings. ` + `But the buffer view with index ${valuesBufferViewIndex} ` + `has a byteLength of ${actualByteLength}.`; return message; } // For fixed-length boolean arrays, the number of bytes // is given by ceil(numValues/8). if (type === "BOOLEAN") { const message = `The 'values' buffer view of property '${propertyId}' ` + `stores the values of fixed-length boolean arrays ` + `with length ${count}. ` + `It is part of a property table with a 'count' of ` + `${propertyTableCount}. ` + `So there are ${count}*${propertyTableCount} = ${numValues} ` + `values, and the buffer view should have a byteLength ` + `of ceil(${numValues}/8) = ${expectedByteLength}. ` + `But the buffer view with index ${valuesBufferViewIndex} ` + `has a byteLength of ${actualByteLength}.`; return message; } // For non-STRING, non-BOOLEAN fixed length arrays, the // number of bytes is given by the number of values, // multiplied by the component size. const message = `The 'values' buffer view of property '${propertyId}' ` + `stores the values of fixed-length arrays with ` + `type ${type}, component type ${componentType}, and ` + `array length ${count}. ` + `It is part of a property table with a 'count' of ` + `${propertyTableCount}. ` + `So there are ${count}*${propertyTableCount} = ${numValues} ` + `values, and the buffer view should have a byteLength ` + `of ${numValues}*${componentTypeByteSize} = ` + `${expectedByteLength}. ` + `But the buffer view with index ${valuesBufferViewIndex} ` + `has a byteLength of ${actualByteLength}.`; return message; } // Handling non-arrays // For STRING properties, the number of bytes is the // same as the number of values (given by the last // string offset) if (type === "STRING") { const message = `The 'values' buffer view of property '${propertyId}' ` + `stores the values of strings. ` + `The last 'stringOffsets' value indicates that there ` + `should be ${numValues} bytes in these strings. ` + `But the buffer view with index ${valuesBufferViewIndex} ` + `has a byteLength of ${actualByteLength}.`; return message; } // For BOOLEAN properties, the number of bytes is given // by ceil(numValues/8). if (type === "BOOLEAN") { const message = `The 'values' buffer view of property '${propertyId}' ` + `stores boolean values. ` + `It is part of a property table with a 'count' of ` + `${propertyTableCount}. ` + `So the buffer view should have a byteLength ` + `of ceil(${numValues}/8) = ${expectedByteLength}. ` + `But the buffer view with index ${valuesBufferViewIndex} ` + `has a byteLength of ${actualByteLength}.`; return message; } // For non-STRING, non-BOOLEAN properties, the number of bytes // is given by the number of values, multiplied with the // component size const message = `The 'values' buffer view of property '${propertyId}' ` + `stores values with type ${type} and component type ` + `${componentType}. ` + `It is part of a property table with a 'count' of ` + `${propertyTableCount}. ` + `So there are ${propertyTableCount}*${componentCount} ` + `= ${numValues} values, and the buffer view should ` + `have a byteLength of ${numValues}*${componentTypeByteSize} = ` + `${expectedByteLength}. ` + `But the buffer view with index ${valuesBufferViewIndex} ` + `has a byteLength of ${actualByteLength}.`; return message; } /** * Computes the number of 'values' for the specified property. * * This computes the number of values that should be in the * 'values' buffer view, depending on the type of the property * and the `count` (number of rows) of the property table. * * This refers to the components of the property type, i.e. * - it will be 3 for a single VEC3 property * - it will be the string length (in bytes) for a single STRING * - it will be the number of bits for a BOOLEAN property * * @param propertyId - The property ID * @param binaryPropertyTable - The `BinaryPropertyTable` * @returns The number of values */ private static computeNumberOfValues( propertyId: string, binaryPropertyTable: BinaryPropertyTable ): number { const binaryMetadata = binaryPropertyTable.binaryMetadata; const metadataClass = binaryMetadata.metadataClass; const classProperties = defaultValue(metadataClass.properties, {}); const classProperty = classProperties[propertyId]; const propertyTable = binaryPropertyTable.propertyTable; const propertyTableCount = propertyTable.count; const type = classProperty.type; const count = classProperty.count; const isArray = classProperty.array === true; const isVariableLengthArray = isArray && !defined(count); const componentCount = MetadataTypes.componentCountForType(type); if (isVariableLengthArray) { // For variable-length string arrays, the number of values // is given by the last string offset, which is found // at the index of the last array offset if (type === "STRING") { const lastArrayOffset = BinaryPropertyTableValidator.getValidatedArrayOffset( propertyId, propertyTableCount, binaryPropertyTable ); const lastStringOffset = BinaryPropertyTableValidator.getValidatedStringOffset( propertyId, lastArrayOffset, binaryPropertyTable ); return lastStringOffset; } // For non-STRING variable length arrays, the number // of values is given by the last array offset, times // the component count const lastArrayOffset = BinaryPropertyTableValidator.getValidatedArrayOffset( propertyId, propertyTableCount, binaryPropertyTable ); return lastArrayOffset * componentCount; } // Handling fixed-length arrays if (isArray) { // For fixed-length STRING arrays, the number of // values is given by the last string offset if (type === "STRING") { const lastStringOffset = BinaryPropertyTableValidator.getValidatedStringOffset( propertyId, propertyTableCount * count!, binaryPropertyTable ); return lastStringOffset; } // For non-STRING fixed length arrays, the number of values // is given by the property table count (number of rows) // times the property count (array length), times the // component count return propertyTableCount * count! * componentCount; } // Handling non-arrays // For STRING properties, the number of values is given // by the last string offset if (type === "STRING") { const lastStringOffset = BinaryPropertyTableValidator.getValidatedStringOffset( propertyId, propertyTableCount, binaryPropertyTable ); return lastStringOffset; } // For non-STRING properties, the number of values // is given by the property table count (number of rows) // times the component count return propertyTableCount * componentCount; } // Note: The getValidatedArrayOffset and getValidatedStringOffset methods // are not very elegant (or efficient). They are only used to dive into // the part of the binary data that contains the desired value, without // introducing additional validation- or abstraction layers. /** * Returns the array offset of the given property at the specified * index. * * This assumes that the property is a variable-length array property * and the required structures for accessing that data have already * been validated. * * @param propertyId - The property ID * @param index - The index * @param binaryPropertyTable - The `BinaryPropertyTable` * @returns The array offset */ private static getValidatedArrayOffset( propertyId: string, index: number, binaryPropertyTable: BinaryPropertyTable ): number { const propertyTable = binaryPropertyTable.propertyTable; const propertyTableProperties = defaultValue(propertyTable.properties, {}); const propertyTableProperty = propertyTableProperties[propertyId]; const arrayOffsetsBufferViewIndex = propertyTableProperty.arrayOffsets!; const arrayOffsetType = defaultValue( propertyTableProperty.arrayOffsetType, "UINT32" ); const binaryMetadata = binaryPropertyTable.binaryMetadata; const binaryBufferData = binaryMetadata.binaryBufferData; const bufferViewsData = defaultValue(binaryBufferData.bufferViewsData, []); const arrayOffsetsBufferView = bufferViewsData[arrayOffsetsBufferViewIndex]; const arrayOffset = NumericBuffers.getNumericFromBuffer( arrayOffsetsBufferView, index, arrayOffsetType ); return Number(arrayOffset); } /** * Returns the string offset of the given property at the specified * index. * * This assumes that the property is a STRING property and the * required structures for accessing that data have already * been validated. * * @param propertyId - The property ID * @param index - The index * @param binaryPropertyTable - The `BinaryPropertyTable` * @returns The string offset */ private static getValidatedStringOffset( propertyId: string, index: number, binaryPropertyTable: BinaryPropertyTable ): number { const propertyTable = binaryPropertyTable.propertyTable; const propertyTableProperties = defaultValue(propertyTable.properties, {}); const propertyTableProperty = propertyTableProperties[propertyId]; const stringOffsetsBufferViewIndex = propertyTableProperty.stringOffsets!; const stringOffsetType = defaultValue( propertyTableProperty.stringOffsetType, "UINT32" ); const binaryMetadata = binaryPropertyTable.binaryMetadata; const binaryBufferData = binaryMetadata.binaryBufferData; const bufferViewsData = defaultValue(binaryBufferData.bufferViewsData, []); const stringOffsetsBufferView = bufferViewsData[stringOffsetsBufferViewIndex]; const stringOffset = NumericBuffers.getNumericFromBuffer( stringOffsetsBufferView, index, stringOffsetType ); return Number(stringOffset); } } ================================================ FILE: src/validation/metadata/BinaryPropertyTableValuesValidator.ts ================================================ import { defaultValue } from "3d-tiles-tools"; import { BinaryPropertyTable } from "3d-tiles-tools"; import { ClassProperties } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { RangeIterables } from "./RangeIterables"; import { BinaryPropertyTableEnumMetadataPropertyModel } from "./BinaryPropertyTableEnumMetadataPropertyModel"; import { MetadataPropertyValuesValidator } from "./MetadataPropertyValuesValidator"; import { BinaryPropertyTableDefaultMetadataPropertyModel } from "./BinaryPropertyTableDefaultMetadataPropertyModel"; /** * A class for the validation of values that are stored * in binary property tables. * * The methods in this class assume that the structural * validity of the input objects has already been checked * by a `PropertyTableValidator` and a * `BinaryPropertyTableValidator`. * * @internal */ export class BinaryPropertyTableValuesValidator { /** * Performs the validation to ensure that the given * `BinaryPropertyTable` contains valid values. * * @param path - The path for the `ValidationIssue` instances * @param binaryPropertyTable - The object to validate * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the values in the object have been valid */ static validateBinaryPropertyTableValues( path: string, binaryPropertyTable: BinaryPropertyTable, context: ValidationContext ): boolean { let result = true; const binaryMetadata = binaryPropertyTable.binaryMetadata; const metadataClass = binaryMetadata.metadataClass; const classProperties = defaultValue(metadataClass.properties, {}); for (const propertyName of Object.keys(classProperties)) { const classProperty = classProperties[propertyName]; const propertyPath = path + "/properties/" + propertyName; if ( !BinaryPropertyTableValuesValidator.validateBinaryPropertyTablePropertyValues( propertyPath, propertyName, classProperty, binaryPropertyTable, context ) ) { result = false; } } return result; } /** * Validate the values of a single property of a `BinaryPropertyTable` * * @param path - The path of the `PropertyTableProperty`, for * `ValidationIssue` instances * @param propertyName - The property name * @param classProperty - The `ClassProperty` * @param binaryPropertyTable - The `BinaryPropertyTable` * @param context - The `ValidationContext` * @returns Whether the property is valid */ private static validateBinaryPropertyTablePropertyValues( path: string, propertyName: string, classProperty: ClassProperty, binaryPropertyTable: BinaryPropertyTable, context: ValidationContext ): boolean { let result = true; const propertyTable = binaryPropertyTable.propertyTable; const propertyTableProperties = defaultValue(propertyTable.properties, {}); const propertyTableProperty = propertyTableProperties[propertyName]; const keys = RangeIterables.range1D(propertyTable.count); // Perform the checks that only apply to ENUM types, if (classProperty.type === "ENUM") { const binaryMetadata = binaryPropertyTable.binaryMetadata; const binaryEnumInfo = binaryMetadata.binaryEnumInfo; const enumType = classProperty.enumType!; const enumValueValueNames = binaryEnumInfo.enumValueValueNames[enumType]; const enumValueNameValues = binaryEnumInfo.enumValueNameValues[enumType]; const validEnumValueValues = Object.values(enumValueNameValues); const metadataPropertyModel = new BinaryPropertyTableEnumMetadataPropertyModel( binaryPropertyTable, propertyName, classProperty, enumValueValueNames ); if ( !MetadataPropertyValuesValidator.validateEnumValues( path, propertyName, keys, metadataPropertyModel, validEnumValueValues, context ) ) { result = false; } } // Perform the checks that only apply to numeric types if (ClassProperties.hasNumericType(classProperty)) { const metadataPropertyModel = new BinaryPropertyTableDefaultMetadataPropertyModel( binaryPropertyTable, propertyName, propertyTableProperty, classProperty ); if ( !MetadataPropertyValuesValidator.validateMinMax( path, propertyName, keys, metadataPropertyModel, propertyTableProperty, "property table", classProperty, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/metadata/ClassPropertySemanticsValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { ClassProperty } from "3d-tiles-tools"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; /** * A class for validations of the `semantic` values of * `ClassProperty` objects. * * @internal */ export class ClassPropertySemanticsValidator { /** * Validate the `semantic` values of the given properties. * * This assumes that the properties have already been validated * with the `ClassPropertyValidator`, ensuring that the `semantic` * values are valid strings. * * @param metadataClassPath - The path for `ValidationIssue` instances * @param properties - The properties of the schema class * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateSemantics( metadataClassPath: string, properties: { [key: string]: ClassProperty }, context: ValidationContext ): boolean { let result = true; // Validate that the 'semantic' of all properties // are unique const semanticsToPropertyNames: any = {}; for (const propertyName of Object.keys(properties)) { const property = properties[propertyName]; if (defined(property)) { const semantic = property.semantic; if (defined(semantic)) { const otherPropertyName = semanticsToPropertyNames[semantic]; if (defined(otherPropertyName)) { const issue = MetadataValidationIssues.CLASS_PROPERTIES_DUPLICATE_SEMANTIC( metadataClassPath, propertyName, otherPropertyName, semantic ); context.addIssue(issue); result = false; } semanticsToPropertyNames[semantic] = propertyName; } } } // Validate that the type of the property matches // the type that is required via the semantic const semanticMatchingSchemas = context.getSemanticMatchingSchemas(); for (const propertyName of Object.keys(properties)) { const property = properties[propertyName]; if (!defined(property)) { continue; } const semantic = property.semantic; if (!defined(semantic)) { continue; } const propertyPath = metadataClassPath + "/properties/" + propertyName; // Find the "matcher" for the given semantic. This is just // the "property" in the `matchingSchema` whose name is // the same as the `semantic`. If no matcher is found for // the given semantic, a warning will be created const semanticMatcher = ClassPropertySemanticsValidator.findSemanticMatcher( semanticMatchingSchemas, semantic ); if (!defined(semanticMatcher)) { const issue = MetadataValidationIssues.METADATA_SEMANTIC_UNKNOWN( propertyPath, propertyName, semantic ); context.addIssue(issue); } else { // Check whether the structure of the property // matches the one required by the matcher if ( !ClassPropertySemanticsValidator.validateSemantic( propertyPath, propertyName, property, semantic, semanticMatcher, context ) ) { result = false; } } } // TODO The constraints for the values that are imposed // by the semantics are not validated yet. For example, // this should apply the `BoundingVolumeValidator` to // properties with the TILE_BOUNDING_REGION, or check // that TILE_REFINE only has a value of 0 or 1. return result; } /** * Validate that the type of the given property matches the * requirements that are defined by the given matcher. * * For information about the 'semanticMatcher', see createMatchingSchema. * * @param propertyPath - The path for `ValidationIssue` instances * @param propertyName - The name of the property * @param property - The `ClassProperty` * @param semantic - The `semantic` * @param semanticMatcher - The semantic matcher * @param context - The `ValidationContext` * @returns Whether the property type matched the structure * that is defined by the given matcher */ private static validateSemantic( propertyPath: string, propertyName: string, property: ClassProperty, semantic: string, semanticMatcher: any, context: ValidationContext ): boolean { let result = true; if (property.type !== semanticMatcher.type) { const message = `Property '${propertyName}' has semantic '${semantic}', ` + `which requires type '${semanticMatcher.type}', but the ` + `property has type '${property.type}'`; const issue = MetadataValidationIssues.METADATA_SEMANTIC_INVALID( propertyPath, message ); context.addIssue(issue); result = false; } if (defined(semanticMatcher.componentType)) { const componentType = defaultValue(property.componentType, "undefined"); const regex = new RegExp("^" + semanticMatcher.componentType + "$"); if (!regex.test(componentType)) { const message = `Property '${propertyName}' has semantic '${semantic}', ` + `which requires the component type to match ` + `'${semanticMatcher.componentType}', but the ` + `property has component type '${componentType}'`; const issue = MetadataValidationIssues.METADATA_SEMANTIC_INVALID( propertyPath, message ); context.addIssue(issue); result = false; } } const matcherArray = defaultValue(semanticMatcher.array, false); const propertyArray = defaultValue(property.array, false); if (propertyArray !== matcherArray) { const message = `Property '${propertyName}' has semantic '${semantic}', ` + `which requires the 'array' property to be '${matcherArray}' ` + `but the 'array' property is '${property.array}'`; const issue = MetadataValidationIssues.METADATA_SEMANTIC_INVALID( propertyPath, message ); context.addIssue(issue); result = false; } if (property.array === true) { if (property.count !== semanticMatcher.count) { const message = `Property '${propertyName}' has semantic '${semantic}', which ` + `requires the 'count' property to be '${semanticMatcher.count}' ` + `but the 'count' property is '${property.count}'`; const issue = MetadataValidationIssues.METADATA_SEMANTIC_INVALID( propertyPath, message ); context.addIssue(issue); result = false; } } const matcherNormalized = defaultValue(semanticMatcher.normalized, false); const propertyNormalized = defaultValue(property.normalized, false); if (propertyNormalized !== matcherNormalized) { const message = `Property '${propertyName}' has semantic '${semantic}', which ` + `requires the 'normalized' property to be '${matcherNormalized}' ` + `but the 'normalized' property is '${property.normalized}'`; const issue = MetadataValidationIssues.METADATA_SEMANTIC_INVALID( propertyPath, message ); context.addIssue(issue); result = false; } // There currently are no semantics that involve an `enumType`, // but the check is done here for completeness if (property.enumType !== semanticMatcher.enumType) { const message = `Property '${propertyName}' has semantic '${semantic}', ` + `which requires enumType '${semanticMatcher.enumType}', but the ` + `property has enumType '${property.enumType}'`; const issue = MetadataValidationIssues.METADATA_SEMANTIC_INVALID( propertyPath, message ); context.addIssue(issue); result = false; } return result; } /** * Finds a "matcher" for the specified semantic in the given matching schemas. * * The given semantic is just the name of the semantic. This is used as a * property name in the matching schema. The classes in the given schemas are * searched for a property that has this (semantic) name. If such a * "matching property" is found, it is returned, and used for checking if * the property that contained the given semantic matches the "matching property". * * Ideally, comparing this "matching property" and the actual property should * check whether the `type`, `component`, and `array` of the matching property * are equal to these in the actual property. But given that semantics may * have different `componentType` values, the returned property may define * the `componentType` to be a RegEx that the actual component type must * match against. * * @param matchingSchema - The matching metadata schema to search for semantics * @param semantic - The name of the semantic * @returns The matcher, or `undefined` */ private static findSemanticMatcher( matchingSchemas: any, semantic: string ): any { for (const matchingSchema of matchingSchemas) { const matchingClasses = defaultValue(matchingSchema.classes, {}); for (const className of Object.keys(matchingClasses)) { const matchingClass = matchingClasses[className]; const matchingProperties = defaultValue(matchingClass.properties, {}); for (const semanticName of Object.keys(matchingProperties)) { if (semanticName === semantic) { return matchingProperties[semanticName]; } } } } return undefined; } } ================================================ FILE: src/validation/metadata/ClassPropertyValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { MetadataValueValidator } from "./MetadataValueValidator"; import { ClassPropertyValueValidator } from "./ClassPropertyValueValidator"; import { Schema } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { MetadataTypes } from "3d-tiles-tools"; import { MetadataComponentTypes } from "3d-tiles-tools"; import { JsonValidationIssues } from "../../issues/JsonValidationIssues"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; /** * A class for validations related to `class.property` objects. * * @internal */ export class ClassPropertyValidator { /** * Validates that the given object is a valid `class.property` object. * * @param schema - The `Schema` * @param propertyPath - The path for the `ValidationIssue` instances * @param propertyName - The name of the property * @param property - The property * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateClassProperty( schema: Schema, propertyPath: string, propertyName: string, property: ClassProperty | undefined, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( propertyPath, propertyName, property, context ) ) { return false; } return ClassPropertyValidator.validateClassPropertyInternal( schema, propertyPath, propertyName, property, context ); } /** * Internal method for `validateClassProperty` that just * assumes that the property is defined and an `"object"`. * * @param schema - The `Schema` * @param propertyPath - The path for the `ValidationIssue` instances * @param propertyName - The name of the property * @param property - The property * @param context - The `ValidationContext` * @returns Whether the object was valid */ private static validateClassPropertyInternal( schema: Schema, propertyPath: string, propertyName: string, property: ClassProperty, context: ValidationContext ): boolean { let result = true; // Validate the name. // If the name is defined, it MUST be a string. if ( !BasicValidator.validateOptionalString( propertyPath, property, "name", context ) ) { result = false; } // Validate the description. // If the description is defined, it MUST be a string. if ( !BasicValidator.validateOptionalString( propertyPath, property, "description", context ) ) { result = false; } // Validate the type // The type MUST be defined // The type MUST be a string const type = property.type; const typePath = propertyPath + "/type"; if (!BasicValidator.validateString(typePath, "type", type, context)) { result = false; } else { // The type MUST be one of the allowed types if ( !BasicValidator.validateEnum( typePath, "type", type, MetadataTypes.allTypes, context ) ) { result = false; } } // Validate the componentType const componentType = property.componentType; const componentTypePath = propertyPath + "/componentType"; const isNumericType = MetadataTypes.isNumericType(type); if (isNumericType && !defined(componentType)) { // For numeric types (SCALAR, VECn, or MATn) the // componentType MUST be defined if (isNumericType) { const issue = MetadataValidationIssues.CLASS_PROPERTY_COMPONENT_TYPE_MISSING( componentTypePath, type ); context.addIssue(issue); result = false; } } if (!isNumericType && defined(componentType)) { // For non-numeric types the componentType MUST NOT be defined const issue = MetadataValidationIssues.CLASS_PROPERTY_COMPONENT_TYPE_FOR_NON_NUMERIC_TYPE( componentTypePath, componentType, type ); context.addIssue(issue); result = false; } else if (defined(componentType)) { // The componentType MUST be a string if ( !BasicValidator.validateString( componentTypePath, "componentType", componentType, context ) ) { result = false; } else { // The componentType MUST be one of the allowed types if ( !BasicValidator.validateEnum( componentTypePath, "componentType", componentType, MetadataComponentTypes.allComponentTypes, context ) ) { result = false; } } } // Validate the enumType const enumType = property.enumType; const enumTypePath = propertyPath + "/enumType"; // When the type is "ENUM", then the enumType MUST be defined if (type === "ENUM" && !defined(enumType)) { const issue = MetadataValidationIssues.CLASS_PROPERTY_ENUM_TYPE_WITHOUT_ENUMTYPE( propertyPath ); context.addIssue(issue); result = false; } else if (type !== "ENUM" && defined(enumType)) { // When the type is not "ENUM", then the enumType MUST NOT be defined const issue = MetadataValidationIssues.CLASS_PROPERTY_ENUMTYPE_WITH_NON_ENUM_TYPE( enumTypePath, enumType, type ); context.addIssue(issue); result = false; } else if (defined(enumType)) { // The enumType MUST be a string if ( !BasicValidator.validateString( enumTypePath, "enumType", enumType, context ) ) { result = false; } else { // When the enumType is defined, then the schema MUST // define an enum with this name const enums = defaultValue(schema.enums, {}); if (!Object.keys(enums).includes(enumType)) { const issue = MetadataValidationIssues.CLASS_PROPERTY_ENUMTYPE_NOT_FOUND( propertyPath, enumType ); context.addIssue(issue); result = false; } } } // Validate the 'array' property const array = property.array; const arrayPath = propertyPath + "/array"; if (defined(array)) { // The array MUST be a boolean if (!BasicValidator.validateBoolean(arrayPath, "array", array, context)) { result = false; } } // Validate the count const count = property.count; const countPath = propertyPath + "/count"; if (defined(count)) { // The count MUST be an integer // The count MUST be at least 2 if ( !BasicValidator.validateIntegerRange( countPath, "count", count, 2, true, undefined, false, context ) ) { result = false; } // When the count is defined, then the property MUST be an array if (!array) { const issue = MetadataValidationIssues.CLASS_PROPERTY_COUNT_FOR_NON_ARRAY( propertyPath, propertyName ); context.addIssue(issue); result = false; } } // Validate the 'normalized' property const normalized = property.normalized; const normalizedPath = propertyPath + "/normalized"; if (defined(normalized)) { // The normalized MUST be a boolean if ( !BasicValidator.validateBoolean( normalizedPath, "normalized", normalized, context ) ) { result = false; } if (normalized) { // If normalized is 'true', then the type MUST be one // of the numeric types (SCALAR, VECn, MATn) if (!MetadataTypes.isNumericType(type)) { const issue = MetadataValidationIssues.CLASS_PROPERTY_NORMALIZED_FOR_NON_NORMALIZABLE_TYPE( propertyPath, propertyName, type ); context.addIssue(issue); result = false; } if (defined(componentType)) { // If normalized is 'true', then the componentType (if present) // MUST be an integer type if (!MetadataComponentTypes.isIntegerComponentType(componentType)) { const issue = MetadataValidationIssues.CLASS_PROPERTY_NORMALIZED_FOR_NON_INTEGER_COMPONENT_TYPE( propertyPath, propertyName, componentType ); context.addIssue(issue); result = false; } } } } // Validate the 'required' property const required = property.required; const requiredPath = propertyPath + "/required"; if (defined(required)) { // The required MUST be a boolean if ( !BasicValidator.validateBoolean( requiredPath, "required", required, context ) ) { result = false; } } // Validate the 'noData' property const noData = property.noData; const noDataPath = propertyPath + "/noData"; if (defined(noData)) { if (required) { // The noData value MUST not be given for 'required' properties const message = `The property '${propertyName}' defines a 'noData' ` + `value, but is 'required'`; const issue = MetadataValidationIssues.CLASS_PROPERTY_INCONSISTENT( noDataPath, message ); context.addIssue(issue); result = false; } else if (type === "BOOLEAN") { // The noData value MUST not be given for BOOLEAN types const message = `The property '${propertyName}' defines a 'noData' ` + `value, but has the type 'BOOLEAN'`; const issue = MetadataValidationIssues.CLASS_PROPERTY_INCONSISTENT( noDataPath, message ); context.addIssue(issue); result = false; } } // Validate the 'default' property const theDefault = property.default; const defaultPath = propertyPath + "/default"; if (defined(theDefault)) { if (required) { // The default value MUST not be given for 'required' properties const message = `The property '${propertyName}' defines a 'default' ` + `value, but is 'required'`; const issue = MetadataValidationIssues.CLASS_PROPERTY_INCONSISTENT( defaultPath, message ); context.addIssue(issue); result = false; } } // Validate the semantic const semantic = property.semantic; const semanticPath = propertyPath + "/semantic"; if (defined(semantic)) { // The semantic MUST be a string if ( !BasicValidator.validateString( semanticPath, "semantic", semantic, context ) ) { result = false; } else { // The semantic string MUST have a length of at least 1 const minLength = 1; if (semantic.length < minLength) { const message = `The 'semantic' must have a length of least ${minLength}, ` + `but has a length of ${semantic.length}`; const issue = JsonValidationIssues.STRING_LENGTH_MISMATCH( semanticPath, message ); context.addIssue(issue); result = false; } } } if (result) { if ( !ClassPropertyValidator.validateClassPropertyValues( schema, propertyPath, propertyName, property, context ) ) { result = false; } } return result; } /** * Validate the values that are given for certain properties of * the `ClassProperty`. * * This validates the `offset/scale/max/min/default/noData` values * of the given `ClassProperty`. This is supposed to be called * after (i.e. at the end of) `validateClassProperty`, when the * basic structure of the class property has already been * determined to be valid. * * @param schema - The `Schema` * @param propertyPath - The path for the `ValidationIssue` instances * @param propertyName - The name of the property * @param property - The property * @param context - The `ValidationContext` * @returns Whether the object was valid */ private static validateClassPropertyValues( schema: Schema, propertyPath: string, propertyName: string, property: ClassProperty, context: ValidationContext ): boolean { let result = true; // Validate the offset const offset = property.offset; if (defined(offset)) { if ( !ClassPropertyValueValidator.validateOffsetScale( propertyPath, propertyName, property, "offset", offset, context ) ) { result = false; } } // Validate the scale const scale = property.scale; if (defined(scale)) { if ( !ClassPropertyValueValidator.validateOffsetScale( propertyPath, propertyName, property, "scale", scale, context ) ) { result = false; } } // Validate the max const max = property.max; if (defined(max)) { if ( !ClassPropertyValueValidator.validateMaxMin( propertyPath, propertyName, property, "max", max, context ) ) { result = false; } } // Validate the min const min = property.min; if (defined(min)) { if ( !ClassPropertyValueValidator.validateMaxMin( propertyPath, propertyName, property, "min", min, context ) ) { result = false; } } const theDefault = property.default; if (defined(theDefault)) { // Validate the structure of the default value if ( !MetadataValueValidator.validateValueStructure( propertyPath, propertyName, property, "default", theDefault, true, schema, context ) ) { result = false; } } const noData = property.noData; if (defined(noData)) { // Validate the structure of the noData value if ( !MetadataValueValidator.validateValueStructure( propertyPath, propertyName, property, "noData", noData, true, schema, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/metadata/ClassPropertyValueValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { ClassProperties } from "3d-tiles-tools"; import { MetadataValueValidator } from "./MetadataValueValidator"; import { ClassProperty } from "3d-tiles-tools"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; /** * A class for validations of metadata values against the definitions * from a `ClassProperty` from a metadata schema. * * The methods in this class assume that the class property definitions * have already been validated with the `ClassPropertyValidator`. * * @internal */ export class ClassPropertyValueValidator { /** * Validates that the given value is a proper `max` or `min` value * for the given property. * * If the property does not have a numeric type, then a * `METADATA_MIN_MAX_FOR_NON_NUMERIC_TYPE` validation * issue will be added to the given context. * * If the structure of the given value does not match the * structure that is defined by the property type, then an * appropriate issue will be added to the given context. * * @param propertyPath - The path for the `ValidationIssue` instances * @param propertyName - The name for the `ValidationIssue` instances * @param classProperty - The `ClassProperty` * @param maxOrMin - The name, "max" or "min" * @param value - The actual value * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateMaxMin( propertyPath: string, propertyName: string, classProperty: ClassProperty, maxOrMin: string, value: any, context: ValidationContext ): boolean { let result = true; const path = propertyPath + "/" + maxOrMin; const type = classProperty.type; // When the max/min is given, the property MUST have a numeric type if (!ClassProperties.hasNumericType(classProperty)) { const issue = MetadataValidationIssues.METADATA_MIN_MAX_FOR_NON_NUMERIC_TYPE( path, propertyName, maxOrMin, type ); context.addIssue(issue); result = false; } else { // The offset/scale property MUST NOT be given // for variable-length arrays if (classProperty.array === true && !defined(classProperty.count)) { const issue = MetadataValidationIssues.METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY( path, propertyName, maxOrMin ); context.addIssue(issue); result = false; } else { // The max/min MUST match the structure of the defined type if ( !MetadataValueValidator.validateNumericValueStructure( classProperty, path, maxOrMin, value, false, context ) ) { result = false; } } } return result; } /** * Validates that the given value is a proper `offset` or `scale` value * for the given property. * * If the property does not have a numeric type, then a * `METADATA_OFFSET_SCALE_FOR_NON_FLOATING_POINT_TYPE` validation * issue will be added to the given context. * * If the structure of the given value does not match the * structure that is defined by the property type, then an * appropriate issue will be added to the given context. * * @param propertyPath - The path for the `ValidationIssue` instances * @param propertyName - The name for the `ValidationIssue` instances * @param classProperty - The `ClassProperty` * @param offsetOrScale - The name, "offset" or "scale" * @param value - The actual value * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateOffsetScale( propertyPath: string, propertyName: string, classProperty: ClassProperty, offsetOrScale: string, value: any, context: ValidationContext ): boolean { let result = true; const path = propertyPath + "/" + offsetOrScale; const type = classProperty.type; const componentType = classProperty.componentType; const normalized = classProperty.normalized; // When the offset/scale is given, the property MUST have a 'floating point type' if (!ClassProperties.hasEffectivelyFloatingPointType(classProperty)) { const issue = MetadataValidationIssues.METADATA_OFFSET_SCALE_FOR_NON_FLOATING_POINT_TYPE( path, propertyName, offsetOrScale, type, componentType, normalized ); context.addIssue(issue); result = false; } else { // The offset/scale property MUST NOT be given // for variable-length arrays if (classProperty.array === true && !defined(classProperty.count)) { const issue = MetadataValidationIssues.METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY( path, propertyName, offsetOrScale ); context.addIssue(issue); result = false; } else { // The offset/scale MUST match the structure of the defined type if ( !MetadataValueValidator.validateNumericValueStructure( classProperty, path, offsetOrScale, value, false, context ) ) { result = false; } } } return result; } } ================================================ FILE: src/validation/metadata/MetadataClassValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { StringValidator } from "../StringValidator"; import { RootPropertyValidator } from "../RootPropertyValidator"; import { ExtendedObjectsValidators } from "../ExtendedObjectsValidators"; import { ClassPropertyValidator } from "./ClassPropertyValidator"; import { ClassPropertySemanticsValidator } from "./ClassPropertySemanticsValidator"; import { Schema } from "3d-tiles-tools"; import { MetadataClass } from "3d-tiles-tools"; /** * A class for validations related to `MetadataClass` objects. * * @internal */ export class MetadataClassValidator { /** * Validate the given `MetadataClass` object * * @param metadataClassPath - The path for `ValidationIssue` instances * @param name - The name of the class * @param metadataClass - The actual `MetadataClass` * @param schema - The `Schema` * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateMetadataClass( metadataClassPath: string, name: string, metadataClass: MetadataClass, schema: Schema, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( metadataClassPath, name, metadataClass, context ) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( metadataClassPath, name, metadataClass, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( metadataClassPath, metadataClass, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(metadataClass)) { return result; } // Validate the name. // If the name is defined, it MUST be a string. if ( !BasicValidator.validateOptionalString( metadataClassPath, metadataClass, "name", context ) ) { result = false; } // Validate the description. // If the description is defined, it MUST be a string. if ( !BasicValidator.validateOptionalString( metadataClassPath, metadataClass, "description", context ) ) { result = false; } // Validate the properties const properties = metadataClass.properties; const propertiesPath = metadataClassPath + "/properties"; if (defined(properties)) { // The properties MUST have at least 1 property if ( !BasicValidator.validateNumberOfProperties( propertiesPath, "properties", properties, 1, undefined, context ) ) { result = false; } // Validate each property let allPropertiesValid = true; for (const propertyName of Object.keys(properties)) { const property = properties[propertyName]; const propertyPath = propertiesPath + "/" + propertyName; // Each property name MUST match the ID regex if ( !StringValidator.validateIdentifierString( propertyPath, propertyName, propertyName, context ) ) { allPropertiesValid = false; result = false; } if ( !ClassPropertyValidator.validateClassProperty( schema, propertyPath, propertyName, property as any, context ) ) { allPropertiesValid = false; result = false; } } // If all properties are valid, validate the semantics of all // properties, i.e. their uniqueness, and compliance to the // semantic definitions if (allPropertiesValid) { if ( !ClassPropertySemanticsValidator.validateSemantics( metadataClassPath, properties, context ) ) { result = false; } } } return result; } } ================================================ FILE: src/validation/metadata/MetadataEntityValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ArrayValues } from "3d-tiles-tools"; import { ClassProperties } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { MetadataValues } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { MetadataEntity } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { RootPropertyValidator } from "../RootPropertyValidator"; import { ExtendedObjectsValidators } from "../ExtendedObjectsValidators"; import { MetadataStructureValidator } from "./MetadataStructureValidator"; import { MetadataValueValidator } from "./MetadataValueValidator"; import { MetadataValuesValidationMessages } from "./MetadataValueValidationMessages"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; /** * A class for validations related to `metadataEntity` objects. * * @internal */ export class MetadataEntityValidator { /** * Performs the validation to ensure that the given object is a * valid `metadataEntity` object. * * @param path - The path for the `ValidationIssue` instances * @param name - A name for the object * @param metadataEntity - The object to validate * @param schema - The `Schema` object. This is either the `tileset.schema`, * or the `Schema` object that was read from the `schemaUri`. * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the given object is a valid metadataEntity object */ static validateMetadataEntity( path: string, name: string, metadataEntity: MetadataEntity, schema: Schema, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, name, metadataEntity, context)) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, name, metadataEntity, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( path, metadataEntity, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(metadataEntity)) { return result; } // Validate that the class and properties are structurally // valid and comply to the metadata schema const className = metadataEntity.class; const entityProperties = metadataEntity.properties; if ( !MetadataStructureValidator.validateMetadataStructure( path, name, className, entityProperties, schema, context ) ) { result = false; // Bail out early if the structure is not valid! return result; } // Here, the basic structure of the class and properties // have been determined to be valid. Continue to validate // the values of the properties. const metadataClasses = defaultValue(schema.classes, {}); const metadataClass = metadataClasses[className]; const classProperties = defaultValue(metadataClass.properties, {}); const validProperties = defaultValue(entityProperties, {}); const validPropertyNames = Object.keys(validProperties); // Validate each property for (const propertyName of validPropertyNames) { const propertyPath = path + "/" + propertyName; const classProperty = classProperties[propertyName]; // Note: The check whether 'required' properties are // present and have values was already done by the // MetadataStructureValidator const propertyValue = validProperties[propertyName]; if (defined(propertyValue)) { // The property value MUST match the structure // of the property definition if ( !MetadataValueValidator.validateValueStructure( propertyPath, propertyName, classProperty, propertyName, propertyValue, true, schema, context ) ) { result = false; } } } // If everything seemed to be valid until now, validate // the metadata entity values if (result) { // Validate each property for (const propertyName of validPropertyNames) { const propertyPath = path + "/" + propertyName; const classProperty = classProperties[propertyName]; const rawPropertyValue = validProperties[propertyName]; if (defined(rawPropertyValue)) { if ( !MetadataEntityValidator.validateMetadataEntityPropertyValue( propertyPath, propertyName, rawPropertyValue, classProperty, context ) ) { result = false; } } } } return result; } /** * Ensure that the given value is valid for the given class property. * * This checks whether the value obeys the min/max that have been * defined in the class property. * * @param path - The path for the `ValidationIssue` instances * @param propertyName - The property name * @param rawPropertyValue - The raw property value from the JSON, * without normalization, offset, or scale * @param classProperty - The class property that describes the * structure of the property * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the given value was valid */ private static validateMetadataEntityPropertyValue( path: string, propertyName: string, rawPropertyValue: any, classProperty: ClassProperty, context: ValidationContext ): boolean { let result = true; if (ClassProperties.hasNumericType(classProperty)) { const propertyValue = MetadataValues.processValue( classProperty, undefined, undefined, rawPropertyValue ); // When the ClassProperty defines a minimum, then the metadata // values MUST not be smaller than this minimum if (defined(classProperty.min)) { const definedMin = classProperty.min; if (ArrayValues.anyDeepLessThan(propertyValue, definedMin)) { const valueMessagePart = MetadataValuesValidationMessages.createValueMessagePart( rawPropertyValue, classProperty, {}, propertyValue ); const message = `For property '${propertyName}', the class property ` + `defines a minimum of ${definedMin}, but the value ` + `in the metadata entity is ${valueMessagePart}`; const issue = MetadataValidationIssues.METADATA_VALUE_NOT_IN_RANGE( path, message ); context.addIssue(issue); result = false; } } // When the ClassProperty defines a maximum, then the metadata // values MUST not be greater than this maximum if (defined(classProperty.max)) { const definedMax = classProperty.max; if (ArrayValues.anyDeepGreaterThan(propertyValue, definedMax)) { const valueMessagePart = MetadataValuesValidationMessages.createValueMessagePart( rawPropertyValue, classProperty, {}, propertyValue ); const message = `For property '${propertyName}', the class property ` + `defines a maximum of ${definedMax}, but the value ` + `in the metadata entity is ${valueMessagePart}`; const issue = MetadataValidationIssues.METADATA_VALUE_NOT_IN_RANGE( path, message ); context.addIssue(issue); result = false; } } } return result; } } ================================================ FILE: src/validation/metadata/MetadataEnumValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { RootPropertyValidator } from "../RootPropertyValidator"; import { ExtendedObjectsValidators } from "../ExtendedObjectsValidators"; import { NumberValidator } from "../NumberValidator"; import { MetadataComponentTypes } from "3d-tiles-tools"; import { MetadataEnum } from "3d-tiles-tools"; import { EnumValue } from "3d-tiles-tools"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; /** * A class for validations related to `MetadataEnum` objects. * * @internal */ export class MetadataEnumValidator { /** * Validate the given `MetadataEnum` object * * @param metadataEnumPath - The path for `ValidationIssue` instances * @param enumName - The name of the enum * @param metadataEnum - The actual `MetadataEnum` * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateMetadataEnum( metadataEnumPath: string, enumName: string, metadataEnum: MetadataEnum, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( metadataEnumPath, enumName, metadataEnum, context ) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( metadataEnumPath, enumName, metadataEnum, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( metadataEnumPath, metadataEnum, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(metadataEnum)) { return result; } // Validate the name. // If the name is defined, it MUST be a string. if ( !BasicValidator.validateOptionalString( metadataEnumPath, metadataEnum, "name", context ) ) { result = false; } // Validate the description. // If the description is defined, it MUST be a string. if ( !BasicValidator.validateOptionalString( metadataEnumPath, metadataEnum, "description", context ) ) { result = false; } // Validate the valueType let validatedValueType = undefined; const valueType = metadataEnum.valueType; const valueTypePath = metadataEnumPath + "/valueType"; if (!defined(valueType)) { validatedValueType = "UINT16"; } else { // The valueType MUST be a string if ( !BasicValidator.validateString( valueTypePath, "valueType", valueType, context ) ) { result = false; } else { // The valueType MUST be one of the allowed types if ( !BasicValidator.validateEnum( valueTypePath, "valueType", valueType, MetadataComponentTypes.integerComponentTypes, context ) ) { result = false; } else { validatedValueType = valueType; } } } // Validate the values const values = metadataEnum.values; if ( !MetadataEnumValidator.validateMetadataEnumValues( metadataEnumPath, values, validatedValueType, context ) ) { result = false; } return result; } /** * Validates the given `enum.values` array * * @param metadataEnumPath - The path of the enum for `ValidationIssue` instances * @param values - The actual values array * @param validatedValueType - The valueType from the enum definition. * If there was no valueType definition, then this is the default * ("UINT16"). If the valueType was not valid, this is `undefined`. * @param context - The `ValidationContext` * @returns Whether the enum values are valid */ private static validateMetadataEnumValues( metadataEnumPath: string, values: EnumValue[], validatedValueType: string | undefined, context: ValidationContext ): boolean { const valuesPath = metadataEnumPath + "/values"; // The values MUST be defined // The values MUST be an array of "object" // The values MUST have at least 1 item const minItems = 1; if ( !BasicValidator.validateArray( valuesPath, "values", values, minItems, undefined, "object", context ) ) { return false; } // Validate each value let result = true; for (let i = 0; i < values.length; i++) { const value = values[i]; const valuePath = valuesPath + "/" + i; if ( !MetadataEnumValidator.validateMetadataEnumValue( valuePath, value, validatedValueType, context ) ) { result = false; } } // If all values are valid, ensure that there are no // duplicates for `values[i].name` or `values[i].value` if (result) { if ( !MetadataEnumValidator.validateUniqueNames( metadataEnumPath, values, context ) ) { result = false; } if ( !MetadataEnumValidator.validateUniqueValues( metadataEnumPath, values, context ) ) { result = false; } } return result; } /** * Validate that the names of the given enum values, as referred to * by `enum.values[i].name`, are unique. * * @param path - The path for `ValidationIssue` instances * @param enumValues - The actual `enum.values` array * @param context - The `ValidationContext` * @returns Whether the names are unique */ private static validateUniqueNames( path: string, enumValues: EnumValue[], context: ValidationContext ): boolean { let result = true; const array = enumValues.map((v) => v.name); for (let i = 0; i < array.length; i++) { const value = array[i]; const index = array.indexOf(value); if (index != i) { const issue = MetadataValidationIssues.ENUM_VALUE_DUPLICATE_NAME( path, value ); context.addIssue(issue); result = false; } } return result; } /** * Validate that the values of the given enum values, as referred to * by `enum.values[i].value`, are unique. * * @param path - The path for `ValidationIssue` instances * @param enumValues - The actual `enum.values` array * @param context - The `ValidationContext` * @returns Whether the values are unique */ private static validateUniqueValues( path: string, enumValues: EnumValue[], context: ValidationContext ): boolean { let result = true; const array = enumValues.map((v) => v.value); for (let i = 0; i < array.length; i++) { const value = array[i]; const index = array.indexOf(value); if (index != i) { const issue = MetadataValidationIssues.ENUM_VALUE_DUPLICATE_VALUE( path, value ); context.addIssue(issue); result = false; } } return result; } /** * Validates a single `enum.values[i]` value * * @param enumValuePath - The path for the `ValidationIssue` instances * @param enumValue - The actual `EnumValue` * @param validatedValueType - The valueType from the enum definition. * If there was no valueType definition, then this is the default * ("UINT16"). If the valueType was not valid, this is `undefined`. * @param context - The `ValidationContext` * @returns Whether the `EnumValue` is valid */ private static validateMetadataEnumValue( enumValuePath: string, enumValue: EnumValue, validatedValueType: string | undefined, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject(enumValuePath, "value", enumValue, context) ) { return false; } let result = true; // Validate the name const name = enumValue.name; const namePath = enumValuePath + "/name"; // The name MUST be defined // The name MUST be a string if (!BasicValidator.validateString(namePath, "name", name, context)) { result = false; } // Validate the description // If the description is defined, it MUST be a string if ( !BasicValidator.validateOptionalString( enumValuePath, enumValue, "description", context ) ) { result = false; } // Validate the value const value = enumValue.value; const valuePath = enumValuePath + "/value"; // The value MUST be defined // The value MUST be an integer if (!BasicValidator.validateInteger(valuePath, "value", value, context)) { result = false; } if (defined(validatedValueType)) { if ( !NumberValidator.validateRange( valuePath, "value", value, validatedValueType, context ) ) { result = false; } } return result; } } ================================================ FILE: src/validation/metadata/MetadataPropertyModel.ts ================================================ /** * A basic model for a single metadata property. * * Implementations of this class can represent... * - a metadata entity property (as it was given in the metadata JSON) * - a column in a binary property table * - a property attribute property in `EXT_structural_metadata` * - a property texture property in `EXT_structural_metadata` * * Usually, the "key" type `K` will be an integer, namely the * index for accessing the row of a table. For property texture * properties, the key type is `[number,number]`, representing * the pixel coordinates. * * @internal */ export interface MetadataPropertyModel { /** * Returns the property value for the given key. * * The returned value will include possible offsets, scales, or * normalization that are defined by the class property, or that * are overridden via the actual metadata property. * * The type of the returned object depends on the type of * the property: * - For `ENUM` properties, it will be a `string` containing * the name of the respective enum value (or `undefined` * if the value was not one of the `enum.values[i].value` * values) * - For `BOOLEAN` properties, it will be a `boolean` * - For `STRING` properties, it will be a `string` * - For `SCALAR` properties, it will be a `number` or `bigint` * - For `VECn`- or `MATn` properties, it will be an array * of `number`- or `bigint` elements * - For array properties, it will be an array of the * respective elements * * @param key - The key * @returns The property value */ getPropertyValue(key: K): any; /** * Returns the RAW property value for the given key. * * This value will NOT include possible offsets, scales, or * normalization. * * The type of the returned object depends on the type of * the property: * - For `ENUM` properties, it will be a the numeric enum * values, which had been given as `enum.values[i].value` * - For `BOOLEAN` properties, it will be a `boolean` * - For `STRING` properties, it will be a `string` * - For `SCALAR` properties, it will be a `number` or `bigint` * - For `VECn`- or `MATn` properties, it will be an array * of `number`- or `bigint` elements * - For array properties, it will be an array of the * respective elements * * @param key - The key * @returns The raw property value */ getRawPropertyValue(key: K): any; } ================================================ FILE: src/validation/metadata/MetadataPropertyValidator.ts ================================================ import { ClassProperty, defined } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { ClassPropertyValueValidator } from "./ClassPropertyValueValidator"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; /** * Methods for common validation tasks of metadata properties. * * The methods in this class assume that the class property definitions * have already been validated with the `ClassPropertyValidator`. * * @internal */ export class MetadataPropertyValidator { /** * Validates the given property object against the given class property * definition. * * The given object may be any object that defines the common elements * of a metadata property, namely `offset/scale/max/min`. * * This method will ensure that these elements are NOT given if the * given class property indicates a variable-length array. If they * are given, it will ensure that their structure matches the * structure that is defined by the class property definition. * * @param path - The path for the `ValidationIssue` instances * @param property - The object to validate * @param propertyName - The name of the property * @param classProperty - The `ClassProperty` definition from the schema * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validateOffsetScaleMaxMin( path: string, property: { offset?: any; scale?: any; max?: any; min?: any; }, propertyName: string, classProperty: ClassProperty, context: ValidationContext ): boolean { const isVariableLengthArray = classProperty.array && !defined(classProperty.count); let result = true; // Validate the offset const offset = property.offset; if (defined(offset)) { // The 'offset' MUST not be given for variable-length arrays if (isVariableLengthArray) { const issue = MetadataValidationIssues.METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY( path, propertyName, "offset" ); context.addIssue(issue); result = false; } else { if ( !ClassPropertyValueValidator.validateOffsetScale( path, propertyName, classProperty, "offset", offset, context ) ) { result = false; } } } // Validate the scale const scale = property.scale; if (defined(scale)) { // The 'scale' MUST not be given for variable-length arrays if (isVariableLengthArray) { const issue = MetadataValidationIssues.METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY( path, propertyName, "scale" ); context.addIssue(issue); result = false; } else { if ( !ClassPropertyValueValidator.validateOffsetScale( path, propertyName, classProperty, "scale", scale, context ) ) { result = false; } } } // Validate the max const max = property.max; if (defined(max)) { // The 'max' MUST not be given for variable-length arrays if (isVariableLengthArray) { const issue = MetadataValidationIssues.METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY( path, propertyName, "max" ); context.addIssue(issue); result = false; } else { if ( !ClassPropertyValueValidator.validateMaxMin( path, propertyName, classProperty, "max", max, context ) ) { result = false; } } } // Validate the min const min = property.min; if (defined(min)) { // The 'min' MUST not be given for variable-length arrays if (isVariableLengthArray) { const issue = MetadataValidationIssues.METADATA_PROPERTY_INVALID_FOR_VARIABLE_LENGTH_ARRAY( path, propertyName, "min" ); context.addIssue(issue); result = false; } else { if ( !ClassPropertyValueValidator.validateMaxMin( path, propertyName, classProperty, "min", min, context ) ) { result = false; } } } return result; } } ================================================ FILE: src/validation/metadata/MetadataPropertyValuesValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { ArrayValues } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { MetadataValuesValidationMessages } from "./MetadataValueValidationMessages"; import { MetadataPropertyModel } from "./MetadataPropertyModel"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; /** * A class for the validation of values that are stored * as metadata properties. * * The methods in this class assume that the structural * validity of the input objects has already been checked. * * @internal */ export class MetadataPropertyValuesValidator { /** * Validate that the values of the specified ENUM property are valid. * * This will iterate over the given keys, obtain the RAW (numeric) * value for the respective key from the given model, and check * whether this value is contained in the given set of valid values. * * @param path - The path for `ValidationIssue` instances * @param propertyName - The property name * @param keys - The iterable of the keys that will be used for * accessing the metadata property model * @param metadataPropertyModel - The `MetadataPropertyModel` * @param validEnumValueValues - The values that appeared as * `enum.values[i].value` in the enum definition * @param context - The `ValidationContext` * @returns Whether the enum values have been valid */ static validateEnumValues( path: string, propertyName: string, keys: Iterable, metadataPropertyModel: MetadataPropertyModel, validEnumValueValues: number[], context: ValidationContext ): boolean { let result = true; for (const key of keys) { // The validation happens based on the RAW property // values for enums, i.e. the `enum.value[i].value` // values (which are not translated into strings) const rawPropertyValue = metadataPropertyModel.getRawPropertyValue(key); // For arrays, simply validate each element individually if (Array.isArray(rawPropertyValue)) { for (let i = 0; i < rawPropertyValue.length; i++) { const rawPropertyValueElement = rawPropertyValue[i]; if ( !BasicValidator.validateEnum( path, propertyName + `[${key}][${i}]`, rawPropertyValueElement, validEnumValueValues, context ) ) { result = false; } } } else { if ( !BasicValidator.validateEnum( path, propertyName + `[${key}]`, rawPropertyValue, validEnumValueValues, context ) ) { result = false; } } } return result; } /** * Validate the that the values of the given property model * are in the range that is defined by the `min`/`max` * values of the class property, or the property itself. * * @param path - The path for `ValidationIssue` instances * @param propertyName - The property name * definition, for example, 'class property' or 'property texture property'. * @param keys - The iterable of the keys that will be used for * accessing the metadata property model * @param metadataPropertyModel - The `MetadataPropertyModel` * @param property - The property, which may contain `min` and * `max` properties, and `scale` or `offset` properties that * override the respective value from the class property * @param propertySourceInfo - A string indicating the source of * the property value, e.g. 'property table', or 'property texture' * @param classProperty - The class property * @param context - The `ValidationContext` * @returns Whether the values obeyed the limit */ public static validateMinMax( path: string, propertyName: string, keys: Iterable, metadataPropertyModel: MetadataPropertyModel, property: { max?: any; min?: any; scale?: any; offset?: any }, propertySourceInfo: string, classProperty: ClassProperty, context: ValidationContext ) { let result = true; // When the ClassProperty defines a minimum, then the metadata // values MUST not be smaller than this minimum if (defined(classProperty.min)) { if ( !MetadataPropertyValuesValidator.validateMin( path, propertyName, classProperty.min, "class property", keys, metadataPropertyModel, property, propertySourceInfo, classProperty, context ) ) { result = false; } } // When the property defines a minimum, then the metadata // values MUST not be smaller than this minimum if (defined(property.min)) { const definedMin = property.min; if ( !MetadataPropertyValuesValidator.validateMin( path, propertyName, definedMin, "property", keys, metadataPropertyModel, property, propertySourceInfo, classProperty, context ) ) { result = false; } else { // When none of the values is smaller than the minimum from // the property, make sure that this minimum matches the // computed minimum of all metadata values const computedMin = MetadataPropertyValuesValidator.computeMin( keys, metadataPropertyModel ); if (!ArrayValues.deepEquals(computedMin, definedMin)) { const message = `For property '${propertyName}', the property ` + `defines a minimum of ${definedMin}, but the computed ` + `minimum value is ${computedMin}`; const issue = MetadataValidationIssues.METADATA_VALUE_MISMATCH( path, message ); context.addIssue(issue); result = false; } } } // When the ClassProperty defines a maximum, then the metadata // values MUST not be greater than this maximum if (defined(classProperty.max)) { if ( !MetadataPropertyValuesValidator.validateMax( path, propertyName, classProperty.max, "class property", keys, metadataPropertyModel, property, propertySourceInfo, classProperty, context ) ) { result = false; } } // When the property defines a maximum, then the metadata // values MUST not be greater than this maximum if (defined(property.max)) { const definedMax = property.max; if ( !MetadataPropertyValuesValidator.validateMax( path, propertyName, definedMax, "property texture property", keys, metadataPropertyModel, property, propertySourceInfo, classProperty, context ) ) { result = false; } else { // When none of the values is greater than the maximum from // the property, make sure that this maximum matches the // computed maximum of all metadata values const computedMax = MetadataPropertyValuesValidator.computeMax( keys, metadataPropertyModel ); if (!ArrayValues.deepEquals(computedMax, definedMax)) { const message = `For property '${propertyName}', the property ` + `defines a maximum of ${definedMax}, but the computed ` + `maximum value is ${computedMax}`; const issue = MetadataValidationIssues.METADATA_VALUE_MISMATCH( path, message ); context.addIssue(issue); result = false; } } } return result; } /** * Validate the that none of the values of the given * property model is smaller than the given defined * minimum. * * @param path - The path for `ValidationIssue` instances * @param propertyName - The property name * @param definedMin - The defined minimum * @param definedMinInfo - A string indicating the source of the minimum * definition, for example, 'class property' or 'property texture property'. * @param keys - The iterable of the keys that will be used for * accessing the metadata property model * @param metadataPropertyModel - The `MetadataPropertyModel` * @param property - The property, which may contain `scale` or * `offset` properties that override the respective value from * the class property * @param propertySourceInfo - A string indicating the source of * the property value, e.g. 'property table', or 'property texture' * @param classProperty - The class property * @param context - The `ValidationContext` * @returns Whether the values obeyed the limit */ private static validateMin( path: string, propertyName: string, definedMin: any, definedMinInfo: string, keys: Iterable, metadataPropertyModel: MetadataPropertyModel, property: { scale?: any; offset?: any }, propertySourceInfo: string, classProperty: ClassProperty, context: ValidationContext ): boolean { let result = true; for (const key of keys) { const rawPropertyValue = metadataPropertyModel.getRawPropertyValue(key); const propertyValue = metadataPropertyModel.getPropertyValue(key); if (ArrayValues.anyDeepLessThan(propertyValue, definedMin)) { const valueMessagePart = MetadataValuesValidationMessages.createValueMessagePart( rawPropertyValue, classProperty, property, propertyValue ); const message = `For property '${propertyName}', the ${definedMinInfo} ` + `defines a minimum of ${definedMin}, but the value at ` + `${key} of the ${propertySourceInfo} is ${valueMessagePart}`; const issue = MetadataValidationIssues.METADATA_VALUE_NOT_IN_RANGE( path, message ); context.addIssue(issue); result = false; } } return result; } /** * Compute the minimum value that appears in the given * metadata property model. * * This assumes that the property has a numeric type, * as indicated by `ClassProperties.hasNumericType`. * * @param keys - The iterable of the keys that will be used for * accessing the metadata property model * @param metadataPropertyModel - The `MetadataPropertyModel` * @returns The minimum */ private static computeMin( keys: Iterable, metadataPropertyModel: MetadataPropertyModel ): any { let computedMin = undefined; for (const key of keys) { const propertyValue = metadataPropertyModel.getPropertyValue(key); if (!defined(computedMin)) { computedMin = ArrayValues.deepClone(propertyValue); } else { computedMin = ArrayValues.deepMin(computedMin, propertyValue); } } return computedMin; } /** * Validate the that none of the values of the given * property model is greater than the given defined * maximum. * * @param path - The path for `ValidationIssue` instances * @param propertyName - The property name * @param definedMax - The defined maximum * @param definedMaxInfo - A string indicating the source of the maximum * definition, for example, 'class property' or 'property texture property'. * @param keys - The iterable of the keys that will be used for * accessing the metadata property model * @param metadataPropertyModel - The `MetadataPropertyModel` * @param property - The property, which may contain `scale` or * `offset` properties that override the respective value from * the class property * @param propertySourceInfo - A string indicating the source of * the property value, e.g. 'property table', or 'property texture' * @param classProperty - The class property * @param context - The `ValidationContext` * @returns Whether the values obeyed the limit */ private static validateMax( path: string, propertyName: string, definedMax: any, definedMaxInfo: string, keys: Iterable, metadataPropertyModel: MetadataPropertyModel, property: { scale?: any; offset?: any }, propertySourceInfo: string, classProperty: ClassProperty, context: ValidationContext ): boolean { let result = true; for (const key of keys) { const rawPropertyValue = metadataPropertyModel.getRawPropertyValue(key); const propertyValue = metadataPropertyModel.getPropertyValue(key); if (ArrayValues.anyDeepGreaterThan(propertyValue, definedMax)) { const valueMessagePart = MetadataValuesValidationMessages.createValueMessagePart( rawPropertyValue, classProperty, property, propertyValue ); const message = `For property '${propertyName}', the ${definedMaxInfo} ` + `defines a maximum of ${definedMax}, but the value at ` + `${key} of the ${propertySourceInfo} is ${valueMessagePart}`; const issue = MetadataValidationIssues.METADATA_VALUE_NOT_IN_RANGE( path, message ); context.addIssue(issue); result = false; } } return result; } /** * Compute the maximum value that appears in the given * metadata property model. * * This assumes that the property has a numeric type, * as indicated by `ClassProperties.hasNumericType`. * * @param keys - The iterable of the keys that will be used for * accessing the metadata property model * @param metadataPropertyModel - The `MetadataPropertyModel` * @returns The maximum */ private static computeMax( keys: Iterable, metadataPropertyModel: MetadataPropertyModel ): any { let computedMax = undefined; for (const key of keys) { const propertyValue = metadataPropertyModel.getPropertyValue(key); if (!defined(computedMax)) { computedMax = ArrayValues.deepClone(propertyValue); } else { computedMax = ArrayValues.deepMax(computedMax, propertyValue); } } return computedMax; } } ================================================ FILE: src/validation/metadata/MetadataStructureValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { Schema } from "3d-tiles-tools"; import { StructureValidationIssues } from "../../issues/StructureValidationIssues"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; /** * A class for validations related to instance definitions of * metadata classes. This refers to `metadataEntity` and * `propertyTable` definitions. It offers a method to check * whether the respective `class` name is a valid class name, * and whether the `properties` match the properties of the * respective class. * * @internal */ export class MetadataStructureValidator { /** * Performs the validation to ensure that the given properties have * the proper structure according to the given metadata schema. * * This will check whether * - the given `class` name is a valid class name in the schema * - each of the `properties` appears as a property name in the class * - each property that is marked as `required` in the class also * has a value in the given `properties` dictionary * * This will **NOT** validate the property values themself. The * exact type of the property values will either be `anyValue` * objects (in a `metadataEntity`), or `propertyTable.property` * values (in a `propertyTable`), and therefore be validated * in the `MetadataEntityValidator` or `PropertyTableValidator`. * * @param path - The path for the `ValidationIssue` instances * @param name - A name for the object * @param className - The `class` * @param properties - The `properties` * @param schema - The `Schema` object. This is either the `tileset.schema`, * or the `Schema` object that was read from the `schemaUri`. * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the given class name and properties have the proper * structure according to the given metadata schema. */ static validateMetadataStructure( path: string, name: string, className: string, properties: { [key: string]: any } | undefined, schema: Schema, context: ValidationContext ) { // Validate the class const classPath = path + "/class"; // The class MUST be defined // The class MUST be a string if ( !BasicValidator.validateString(classPath, "class", className, context) ) { return false; } // The class MUST appear in the schema.classes dictionary const metadataClasses: any = defaultValue(schema.classes, {}); const metadataClass = metadataClasses[className]; if (!defined(metadataClass)) { const message = `The ${name} has a class name '${className}', ` + `but the schema does not define this class`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( classPath, message ); context.addIssue(issue); return false; } // Here, the metadataClass is defined let result = true; const classProperties = defaultValue(metadataClass.properties, {}); const classPropertyNames = Object.keys(classProperties); // Validate the properties const propertiesPath = path + "/properties"; if (defined(properties)) { // The properties MUST be an object with at least 1 property if ( !BasicValidator.validateNumberOfProperties( propertiesPath, "properties", properties, 1, undefined, context ) ) { result = false; } else { // Validate whether each property was defined in the class const propertyNames = Object.keys(properties); for (const propertyName of propertyNames) { // The property name MUST appear as a key in // the properties of the schema class if (!classPropertyNames.includes(propertyName)) { const message = `The properties of ${name} include a name '${propertyName}', ` + `but the class ${className} does not define this property`; const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } } } } // Check that all required properties are present and have a value for (const classPropertyName of classPropertyNames) { const classProperty = classProperties[classPropertyName]; if (classProperty.required) { let propertyValue = undefined; if (defined(properties)) { propertyValue = properties[classPropertyName]; } // The property value MUST be present if the property is 'required' if (!defined(propertyValue)) { if (classProperty.required) { const issue = MetadataValidationIssues.METADATA_VALUE_REQUIRED_BUT_MISSING( path, classPropertyName ); context.addIssue(issue); result = false; } } } } return result; } } ================================================ FILE: src/validation/metadata/MetadataValidationUtilities.ts ================================================ import { ClassProperty } from "3d-tiles-tools"; import { MetadataEnum } from "3d-tiles-tools"; import { MetadataUtilities } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; /** * Internal utilities related to the validation of ENUM values. * * These methods assume that the structural validity of their * inputs has already been checked. They are only utility * methods for the subsequent validation steps. * * @internal */ export class MetadataValidationUtilities { /** * Computes the enum 'valueType' of the specified ENUM property. * * If any required element of the input is `undefined`, then * `undefined` is returned. * * @param schema - The schema * @param className - The class name * @param propertyName - The property name * @returns The value type */ static computeEnumValueType( schema: Schema, className: string, propertyName: string ) { const classProperty = MetadataValidationUtilities.computeClassProperty( schema, className, propertyName ); if (!classProperty) { return undefined; } const enumValueType = MetadataUtilities.computeEnumValueType( schema, classProperty ); return enumValueType; } /** * Computes the mapping from enum value values to enum value * names for the specified property. * * If any required element of the input is `undefined`, then * `undefined` is returned. * * @param schema - The schema * @param className - The class name * @param propertyName - The property name * @returns The value value names */ static computeEnumValueValueNames( schema: Schema, className: string, propertyName: string ): { [key: number]: string } | undefined { const classProperty = MetadataValidationUtilities.computeClassProperty( schema, className, propertyName ); if (!classProperty) { return undefined; } const metadataEnum = MetadataValidationUtilities.computeMetadataEnum( schema, classProperty.enumType ); if (!metadataEnum) { return undefined; } const enumValueValueNames = MetadataUtilities.computeMetadataEnumValueValueNames(metadataEnum); return enumValueValueNames; } /** * Computes the `ClassProperty` that describes the specified * property. * * This will find the `class` for `schema.classes[className]`, * and the `property` for `class[propertyName]`. * * This assumes that the given structures are valid. If any * element in this process is `undefined`, then `undefined` * is returned. * * @param schema - The metadata schema * @param className - The class name * @param propertyName - The property name * @returns The valid enum value values */ static computeClassProperty( schema: Schema, className: string, propertyName: string ): ClassProperty | undefined { const classes = schema.classes; if (!classes) { return undefined; } const metadataClass = classes[className]; if (!metadataClass) { return undefined; } const classProperties = metadataClass.properties; if (!classProperties) { return undefined; } const classProperty = classProperties[propertyName]; return classProperty; } /** * Computes the set of (numeric) enum values that are valid * for the specified property. * * This will find... * - the `class` for `schema.classes[className]` * - the `property` for `class[propertyName]` * - the `enum` for `schema.enums[property.enumType]` * - all values that appear as `enum.values[i].value` * * This assumes that the given structures are valid. If any * element in this process is `undefined`, then `undefined` * is returned. * * @param schema - The metadata schema * @param className - The class name * @param propertyName - The property name * @returns The valid enum value values */ static computeValidEnumValueValues( schema: Schema, className: string, propertyName: string ): number[] | undefined { const classProperty = MetadataValidationUtilities.computeClassProperty( schema, className, propertyName ); if (!classProperty) { return undefined; } const metadataEnum = MetadataValidationUtilities.computeMetadataEnum( schema, classProperty.enumType ); if (!metadataEnum) { return undefined; } const enumValues = metadataEnum.values; if (!enumValues) { return undefined; } const enumValueValues = []; for (let i = 0; i < enumValues.length; i++) { const enumValue = enumValues[i]; if (!enumValue) { return undefined; } const value = enumValue.value; if (value === undefined) { return undefined; } enumValueValues.push(value); } return enumValueValues; } /** * Returns the metadata enum with the given name from the * given schema, or `undefined` if any required element * is `undefined` * * @param schema - The schema * @param enumType - The enum type * @returns The metadata enum */ private static computeMetadataEnum( schema: Schema, enumType: string | undefined ): MetadataEnum | undefined { if (enumType === undefined) { return undefined; } const enums = schema.enums; if (!enums) { return undefined; } const metadataEnum = enums[enumType]; return metadataEnum; } } ================================================ FILE: src/validation/metadata/MetadataValueValidationMessages.ts ================================================ import { ClassProperty, defined } from "3d-tiles-tools"; /** * Utility methods related to the messages that are part of * validation issues in the metadata validation. */ export class MetadataValuesValidationMessages { /** * Creates a message that describes how a metadata value was computed. * * The intention is to insert this as `The value is ${valueMessagePart}` * in a message that explains how the `value` was computed from the * raw value, normalization, offset and scale. * * @param rawValue - The raw value (e.g. from the `PropertyModel`), * without normalization, offset, or scale * @param classProperty - The class property * @param property - The property, which may contain `scale` or * `offset` properties that override the respective value from * the class property * @param value - The final value * @returns The message part */ static createValueMessagePart( rawValue: any, classProperty: ClassProperty, property: { scale?: any; offset?: any }, value: any ) { // Determine the scale and its source (i.e whether it // is defined in the class property, or overridden // in the actual property) let scale = undefined; let scaleSource = undefined; if (defined(property.scale)) { scale = property.scale; scaleSource = "property.scale"; } else if (defined(classProperty.scale)) { scale = classProperty.scale; scaleSource = "classProperty.scale"; } // Determine the offset and its source (i.e whether it // is defined in the class property, or overridden // in the actual property) let offset = undefined; let offsetSource = undefined; if (defined(property.offset)) { offset = property.offset; offsetSource = "property.offset"; } else if (defined(classProperty.offset)) { offset = classProperty.offset; offsetSource = "classProperty.offset"; } const normalized = classProperty.normalized; const componentType = classProperty.componentType; if (defined(offset) && defined(scale)) { if (normalized === true) { const messagePart = `computed as normalize${componentType}(rawValue)*${scaleSource}+${offsetSource} ` + `= normalize${componentType}(${rawValue})*${scale}+${offset} = ${value}`; return messagePart; } const messagePart = `computed as rawValue*${scaleSource}+${offsetSource} ` + `= ${rawValue}*${scale}+${offset} = ${value}`; return messagePart; } if (defined(offset)) { if (normalized === true) { const messagePart = `computed as normalize${componentType}(rawValue)+${offsetSource} ` + `= normalize${componentType}(${rawValue})+${offset} = ${value}`; return messagePart; } const messagePart = `computed as rawValue+${offsetSource} ` + `= ${rawValue}+${offset} = ${value}`; return messagePart; } if (defined(scale)) { if (normalized === true) { const messagePart = `computed as normalize${componentType}(rawValue)*${scaleSource} ` + `= normalize${componentType}(${rawValue})*${scale} = ${value}`; return messagePart; } const messagePart = `computed as rawValue*${scaleSource} ` + `= ${rawValue}*${scale} = ${value}`; return messagePart; } if (normalized === true) { const messagePart = `computed as normalize${componentType}(rawValue) ` + `= normalize${componentType}(${rawValue}) = ${value}`; return messagePart; } const messagePart = `${value}`; return messagePart; } } ================================================ FILE: src/validation/metadata/MetadataValueValidator.ts ================================================ import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { NumberValidator } from "../NumberValidator"; import { MetadataUtilities } from "3d-tiles-tools"; import { defined } from "3d-tiles-tools"; import { MetadataTypes } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { MetadataValidationIssues } from "../../issues/MetadataValidationIssues"; /** * A class for validations of metadata values against the definitions * from a `ClassProperty` from a metadata schema. * * The methods in this class assume that the property definitions * have already been validated with the `ClassPropertyValidator`. * * @internal */ export class MetadataValueValidator { /** * Validate the structure of the given value against the given * property definition. * * If will check the structure of the values based on the * type of the property: * - For STRING properties, they must be strings * - For ENUM properties, they must be strings that are the * names of enum values * - For BOOLEAN properties, they must be booleans * - For arrays, they must be arrays accordingly * - For numeric types, they must be numbers or numeric arrays, * as checked with `validateNumericValueStructure` * * @param propertyPath - The path for the property * @param propertyName - The name of the property * @param property - The actual property * @param valueName - The name of the value, to be used for the * validation issue message. For example, this may be "noData" * or "default". * @param value - The value * @param validateValueRange - Whether the function should also * validate whether the value is in the range that is defined by * the class property component type (if it is a numeric value). * For example, whether the components are in [0,255] when the * component type is `UINT8`. * @param schema - The metadata schema * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateValueStructure( propertyPath: string, propertyName: string, property: ClassProperty, valueName: string, value: any, validateValueRange: boolean, schema: Schema, context: ValidationContext ): boolean { const path = propertyPath; const type = property.type; if (type === "STRING") { return MetadataValueValidator.validateStringValueStructure( propertyPath, property, valueName, value, context ); } if (type === "ENUM") { return MetadataValueValidator.validateEnumValueStructure( propertyPath, propertyName, property, valueName, value, schema, context ); } if (type === "BOOLEAN") { return MetadataValueValidator.validateBooleanValueStructure( propertyPath, property, valueName, value, context ); } // Here, the type must be a numeric type. Check the value // to have the proper structure. return MetadataValueValidator.validateNumericValueStructure( property, path, valueName, value, validateValueRange, context ); } /** * Validates that the given value is a value that matches the * given class property, which has type `"STRING"`. * * The general validity of the class property has already * been validated with the `ClassPropertyValidator`. * * @param propertyPath - The path for `ValidationIssue` instances * @param property - The `ClassProperty` * @param valueName - The name of the value * @param value - The value * @param context - The `ValidationContext` * @returns Whether the value was valid */ private static validateStringValueStructure( propertyPath: string, property: ClassProperty, valueName: string, value: any, context: ValidationContext ): boolean { const path = propertyPath; const array = property.array; const count = property.count; if (!array) { // For non-array STRING types, the value MUST be a string if (!BasicValidator.validateString(path, valueName, value, context)) { return false; } return true; } // For STRING array types, the value MUST be a string array const expectedLength = count; if ( !BasicValidator.validateArray( path, valueName, value, expectedLength, expectedLength, "string", context ) ) { return false; } return true; } /** * Validates that the given value is a value that matches the * given class property, which has type `"ENUM"`. * * The general validity of the class property has already * been validated with the `ClassPropertyValidator`. * * @param propertyPath - The path for `ValidationIssue` instances * @param property - The `ClassProperty` * @param valueName - The name of the value * @param value - The value * @param context - The `ValidationContext` * @returns Whether the value was valid */ private static validateEnumValueStructure( propertyPath: string, propertyName: string, property: ClassProperty, valueName: string, value: any, schema: Schema, context: ValidationContext ): boolean { const path = propertyPath; const array = property.array; const count = property.count; const enumType = property.enumType; if (!array) { // For non-array ENUM types, the enum value MUST be a string // that appears in the names of the enum values const enumValueNames = MetadataUtilities.obtainEnumValueNames( property, schema ); if ( !MetadataValueValidator.validateEnumValueName( path, valueName, propertyName, enumType, value, enumValueNames, context ) ) { return false; } return true; } // For array ENUM types, the value must be an array of strings if ( !BasicValidator.validateArray( path, valueName, value, count, count, "string", context ) ) { return false; } let result = true; // Each element of the array MUST appear in the // names of the enum values const enumValueNames = MetadataUtilities.obtainEnumValueNames( property, schema ); for (let i = 0; i < value.length; i++) { const enumValueName = value[i]; if ( !MetadataValueValidator.validateEnumValueName( path + "/" + i, valueName + "/" + i, propertyName, enumType, enumValueName, enumValueNames, context ) ) { result = false; } } return result; } /** * Make sure that the given `enumValueName` is valid. * * This is used for the validation of the names that appear in * the actual values that are supposed to represent enums. For * example, a `noData` value for an enum type may have the * value `"EXAMPLE_ENUM_VALUE`". This must be a string that * appears as the `enums[enumType].values[i].name` of the * corresponding enum type in the schema. * * @param path - The path for `ValidationIssue` instances * @param name - The name of the enum value to be used in the * `ValidationIssue` message. * @param propertyName - The name of the property * @param enumType - The `enumType` of the property * @param enumValueName - The name of the enum value * @param enumValueNames - The valid enum value names * @param context - The `ValidationContext` * @returns Whether the name is valid */ private static validateEnumValueName( path: string, name: string, propertyName: string, enumType: string | undefined, enumValueName: any, enumValueNames: any[], context: ValidationContext ): boolean { // The enum value name MUST be a string if (!BasicValidator.validateString(path, name, enumValueName, context)) { return false; } // Each enum value MUST appear as the name of the // values from the enum definition if (!enumValueNames.includes(enumValueName)) { const issue = MetadataValidationIssues.CLASS_PROPERTY_ENUM_VALUE_NAME_NOT_FOUND( path, name, propertyName, enumType, enumValueName ); context.addIssue(issue); return false; } return true; } /** * Validates that the given value is a value that matches the * given class property, which has type `"BOOLEAN"`. * * The general validity of the class property has already * been validated with the `ClassPropertyValidator`. * * @param propertyPath - The path for `ValidationIssue` instances * @param property - The `ClassProperty` * @param valueName - The name of the value * @param value - The value * @param context - The `ValidationContext` * @returns Whether the value was valid */ private static validateBooleanValueStructure( propertyPath: string, property: ClassProperty, valueName: string, value: any, context: ValidationContext ): boolean { const path = propertyPath; const array = property.array; const count = property.count; if (!array) { // For non-array BOOLEAN types, the value MUST be a boolean if (!BasicValidator.validateBoolean(path, valueName, value, context)) { return false; } return true; } // For BOOLEAN array types, the value MUST be a boolean array const expectedLength = count; if ( !BasicValidator.validateArray( path, valueName, value, expectedLength, expectedLength, "boolean", context ) ) { return false; } return true; } /** * Validates that a value that appears in a property is a proper * numeric value that matches the type of the property. * * When `validateValueRange` is `false`, then this will only * check the structure of the values (e.g. whether a `VEC2` * property is represented with 2 numeric values). It will * not check whether these values are in the range that is * defined by the component type. This is intended for the * values that can be given as `offset`, `scale`, `max`, * and `min`. For example, for a `normalized` `SCALAR` `UINT8` * property, the value may be `1000.0` (which is out of * the range of `UINT8`), because such a value can be used * in the `offset`, `scale`, `max`, and `min` properties) * * @param property - The ClassProperty * @param valueName - The name of the value (e.g. 'min' or 'offset') * @param value - The actual value * @param validateValueRange - Whether the function should also * validate whether the value is in the range that is defined by * the class property component type - for example, whether the * given value is in [0,255] when the component type is `UINT8`. * @param context - The `ValidationContext` * @returns Whether the value was valid */ static validateNumericValueStructure( property: ClassProperty, valuePath: string, valueName: string, value: any, validateValueRange: boolean, context: ValidationContext ): boolean { // This assumes that the validity of the given property has // already been validated by the `ClassPropertyValidator` const type = property.type; const array = property.array; const componentType = property.componentType; if (!defined(componentType)) { return false; } // Check non-array types if (!array) { // For SCALAR types, the value MUST be a number if (type === "SCALAR") { if ( !BasicValidator.validateNumber(valuePath, valueName, value, context) ) { return false; } if (validateValueRange) { // The value MUST be in the range that is // determined by the componentType if ( !NumberValidator.validateRange( valuePath, "value", value, componentType, context ) ) { return false; } } return true; } // For non-SCALAR types, the value must be an // array of numbers, with the length matching // the componentCount of the type const componentCount = MetadataTypes.componentCountForType(type); if ( !BasicValidator.validateArray( valuePath, valueName, value, componentCount, componentCount, "number", context ) ) { return false; } if (validateValueRange) { // Each element MUST be in the range that is // determined by the componentType return NumberValidator.validateRanges( valuePath, value, componentType, context ); } return true; } // Here, the value must be an array. // The expected length is only defined when a count was given. // (If it is undefined, it will be ignored in `validateArray`) const count = property.count; // For SCALAR arrays, the value must be an array of numbers if (type === "SCALAR") { // The value MUST be an array of numbers if ( !BasicValidator.validateArray( valuePath, valueName, value, count, count, "number", context ) ) { return false; } if (validateValueRange) { // Each element MUST be in the range that is // determined by the componentType return NumberValidator.validateRanges( valuePath, value, componentType, context ); } } // For non-SCALAR arrays, the value MUST be an array of objects if ( !BasicValidator.validateArray( valuePath, valueName, value, count, count, "object", context ) ) { return false; } // Each element MUST be an array of numbers, with a length // that matches the componentCount of the type let allElementsValid = true; const componentCount = MetadataTypes.componentCountForType(type); for (let i = 0; i < value.length; i++) { const valueElement = value[i]; const valueElementPath = valuePath + "/" + i; if ( !BasicValidator.validateArray( valueElementPath, valueName, valueElement, componentCount, componentCount, "number", context ) ) { allElementsValid = false; } else { if (validateValueRange) { // Each element of the array MUST be in the range that is // determined by the componentType if ( !NumberValidator.validateRanges( valueElementPath, valueElement, componentType, context ) ) { allElementsValid = false; } } } } return allElementsValid; } } ================================================ FILE: src/validation/metadata/PropertyTablePropertyValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { PropertyTableProperty } from "3d-tiles-tools"; import { ClassProperty } from "3d-tiles-tools"; import { MetadataComponentTypes } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { StructureValidationIssues } from "../../issues/StructureValidationIssues"; import { MetadataPropertyValidator } from "./MetadataPropertyValidator"; /** * A class for validations related to `propertyTable.property` objects. * * @internal */ export class PropertyTablePropertyValidator { /** * Performs the validation to ensure that the given object is a * valid `propertyTable.property` object. * * @param path - The path for the `ValidationIssue` instances * @param propertyName - The name of the property * @param propertyTableProperty - The object to validate * @param numBufferViews - The number of buffer views that are available * @param classProperty - The `ClassProperty` definition from the schema * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validatePropertyTableProperty( path: string, propertyName: string, propertyTableProperty: PropertyTableProperty, numBufferViews: number, classProperty: ClassProperty, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, propertyName, propertyTableProperty, context ) ) { return false; } let result = true; // The basic structure of the class property was already // validated by the `MetadataStructureValidator` const isVariableLengthArray = classProperty.array && !defined(classProperty.count); const isString = classProperty.type === "STRING"; // Validate the values // The values MUST be defined // The values MUST be an integer in [0, numBufferViews) const values = propertyTableProperty.values; const valuesPath = path + "/values"; if ( !BasicValidator.validateIntegerRange( valuesPath, "values", values, 0, true, numBufferViews, false, context ) ) { result = false; } // Validate the arrayOffsets const arrayOffsets = propertyTableProperty.arrayOffsets; const arrayOffsetsPath = path + "/arrayOffsets"; if (isVariableLengthArray) { // For variable-length arrays, the arrayOffsets MUST be defined if (!defined(arrayOffsets)) { const message = `The property '${propertyName}' is a variable-length array, ` + `but the property table property does not define 'arrayOffsets'`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else { // The arrayOffsets MUST be an integer in [0, numBufferViews) if ( !BasicValidator.validateIntegerRange( arrayOffsetsPath, "arrayOffsets", arrayOffsets, 0, true, numBufferViews, false, context ) ) { result = false; } } } // Validate the stringOffsets const stringOffsets = propertyTableProperty.stringOffsets; const stringOffsetsPath = path + "/stringOffsets"; if (isString) { // For the STRING type, the stringOffsets MUST be defined if (!defined(stringOffsets)) { const message = `The property '${propertyName}' has the type 'STRING', ` + `but the property table property does not define 'stringOffsets'`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); result = false; } else { // The stringOffsets MUST be an integer in [0, numBufferViews) if ( !BasicValidator.validateIntegerRange( stringOffsetsPath, "stringOffsets", stringOffsets, 0, true, numBufferViews, false, context ) ) { result = false; } } } // TODO The arrayOffsetType and stringOffsetType should // probably only be allowed when the type is a dynamic // length array or string types // Validate the arrayOffsetType const arrayOffsetType = propertyTableProperty.arrayOffsetType; const arrayOffsetTypePath = path + "/arrayOffsetType"; if (defined(arrayOffsetType)) { // The arrayOffsetType MUST be one of the allowed types, // namely UINT8, UINT16, UINT32 or UINT64 if ( !BasicValidator.validateEnum( arrayOffsetTypePath, "arrayOffsetType", arrayOffsetType, MetadataComponentTypes.unsignedComponentTypes, context ) ) { result = false; } } // Validate the stringOffsetType const stringOffsetType = propertyTableProperty.stringOffsetType; const stringOffsetTypePath = path + "/stringOffsetType"; if (defined(stringOffsetType)) { // The stringOffsetType MUST be one of the allowed types, // namely UINT8, UINT16, UINT32 or UINT64 if ( !BasicValidator.validateEnum( stringOffsetTypePath, "stringOffsetType", stringOffsetType, MetadataComponentTypes.unsignedComponentTypes, context ) ) { result = false; } } // Validate the offset/scale/max/min properties const elementsAreValid = MetadataPropertyValidator.validateOffsetScaleMaxMin( path, propertyTableProperty, propertyName, classProperty, context ); if (!elementsAreValid) { result = false; } return result; } } ================================================ FILE: src/validation/metadata/PropertyTableValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { defaultValue } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { PropertyTable } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { RootPropertyValidator } from "../RootPropertyValidator"; import { ExtendedObjectsValidators } from "../ExtendedObjectsValidators"; import { MetadataStructureValidator } from "./MetadataStructureValidator"; import { PropertyTablePropertyValidator } from "./PropertyTablePropertyValidator"; /** * A class for validations related to `propertyTable` objects. * * This class performs the basic JSON-level validation of the * property table. The validation of binary data is done with * the BinaryPropertyTableValidator. * * @internal */ export class PropertyTableValidator { /** * Performs the validation to ensure that the given object is a * valid `propertyTable` object. * * @param path - The path for the `ValidationIssue` instances * @param propertyTable - The object to validate * @param numBufferViews - The number of buffer views that are available * @param schema - The `Schema` object * @param context - The `ValidationContext` that any issues will be added to * @returns Whether the object was valid */ static validatePropertyTable( path: string, propertyTable: PropertyTable, numBufferViews: number, schema: Schema, context: ValidationContext ): boolean { // Make sure that the given value is an object if ( !BasicValidator.validateObject( path, "propertyTable", propertyTable, context ) ) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, "propertyTable", propertyTable, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject( path, propertyTable, context ) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(propertyTable)) { return result; } // Validate that the class and properties are structurally // valid and comply to the metadata schema const className = propertyTable.class; const tableProperties = propertyTable.properties; if ( !MetadataStructureValidator.validateMetadataStructure( path, "property table", className, tableProperties, schema, context ) ) { // Bail out early if the structure is not valid! return false; } // Validate the name. // If the name is defined, it MUST be a string. if ( !BasicValidator.validateOptionalString( path, propertyTable, "name", context ) ) { result = false; } // Validate the count // The count MUST be an integer // The count MUST be at least 1 const count = propertyTable.count; const countPath = path + "/count"; if ( !BasicValidator.validateIntegerRange( countPath, "count", count, 0, true, undefined, false, context ) ) { result = false; } // Here, the basic structure of the class and properties // have been determined to be valid. Continue to validate // the values of the properties. const validProperties = defaultValue(tableProperties, {}); const validPropertyNames = Object.keys(validProperties); const classes = defaultValue(schema.classes, {}); const metadataClass = classes[className]; const classProperties = defaultValue(metadataClass.properties, {}); // Validate each property for (const propertyName of validPropertyNames) { const propertyPath = path + "/properties/" + propertyName; const classProperty = classProperties[propertyName]; // Note: The check whether 'required' properties are // present and have values was already done by the // MetadataStructureValidator const propertyValue = validProperties[propertyName]; if (defined(propertyValue)) { if ( !PropertyTablePropertyValidator.validatePropertyTableProperty( propertyPath, propertyName, propertyValue, numBufferViews, classProperty, context ) ) { result = false; } } } return result; } } ================================================ FILE: src/validation/metadata/PropertyTablesDefinitionValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { PropertyTable } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { ValidatedElement } from "../ValidatedElement"; import { BasicValidator } from "../BasicValidator"; import { PropertyTableValidator } from "./PropertyTableValidator"; import { StructureValidationIssues } from "../../issues/StructureValidationIssues"; /** * A class for validating the definition of property tables. */ export class PropertyTablesDefinitionValidator { /** * Validate the given definition of property tables. * * The returned object will contain two properties: * - `wasPresent`: Whether property tables have been given * - `validatedElement`: The validated `PropertyTables[]` object * * When no property tables are given, then it will just return * `{false, undefined}`. * * If the given `schemaState` indicates that no schema was present, * or the property tables have not been valid according to the * schema, then an error will be added to the given context, * and `{true, undefined}` is returned. * * The method will return `{true, propertyTables}` only if the * given property tables have been valid. * * @param path - The path for `ValidationIssue` instances * @param name - The name of the object containing the definition * (for example, 'subtree') * @param propertyTables - The actual property tables * @param numBufferViews - The number of buffer views in the * containing object * @param schemaState - The state of the schema validation * @param context - The `ValidationContext` * @returns Information about the validity of the definition */ static validatePropertyTablesDefinition( path: string, name: string, propertyTables: PropertyTable[] | undefined, numBufferViews: number, schemaState: ValidatedElement, context: ValidationContext ): ValidatedElement { // Return immediately when there are no property tables const propertyTablesState: ValidatedElement = { wasPresent: false, validatedElement: undefined, }; if (!defined(propertyTables)) { return propertyTablesState; } // There are property tables. propertyTablesState.wasPresent = true; // Validate the propertyTables, returning as soon as they // have been determined to be invalid const propertyTablesPath = path + "/propertyTables"; if (!schemaState.wasPresent) { // If there are property tables, then there MUST be a schema definition const message = `The ${name} defines 'propertyTables' but ` + `there was no schema definition`; const issue = StructureValidationIssues.REQUIRED_VALUE_NOT_FOUND( path, message ); context.addIssue(issue); return propertyTablesState; } if (defined(schemaState.validatedElement)) { // The propertyTables MUST be an array of at least 1 objects if ( !BasicValidator.validateArray( propertyTablesPath, "propertyTables", propertyTables, 1, undefined, "object", context ) ) { return propertyTablesState; } // Validate each propertyTable for (let i = 0; i < propertyTables.length; i++) { const propertyTable = propertyTables[i]; const propertyTablePath = propertyTablesPath + "/" + i; if ( !PropertyTableValidator.validatePropertyTable( propertyTablePath, propertyTable, numBufferViews, schemaState.validatedElement, context ) ) { return propertyTablesState; } } } // The property tables have been determined to be valid. // Return them as the validatedElement in the returned // state: propertyTablesState.validatedElement = propertyTables; return propertyTablesState; } } ================================================ FILE: src/validation/metadata/RangeIterables.ts ================================================ import { DeveloperError } from "3d-tiles-tools"; /** * Methods to create iterables over ranges */ export class RangeIterables { /** * Creates an iterable over the given 1D range * * @param size - The size * @returns The iterable * @throws DeveloperError if the size is negative */ static range1D(size: number): Iterable { if (size < 0) { throw new DeveloperError(`The size may not be negative, but is ${size}`); } const resultIterable = { [Symbol.iterator]: function* (): Iterator { for (let x = 0; x < size; x++) { yield x; } }, }; return resultIterable; } /** * Creates an iterable over the given 2D range * * @param sizeX - The size in x-direction * @param sizeY - The size in y-direction * @returns The iterable * @throws DeveloperError if any size is negative */ static range2D(sizeX: number, sizeY: number): Iterable<[number, number]> { if (sizeX < 0) { throw new DeveloperError( `The sizeX may not be negative, but is ${sizeX}` ); } if (sizeY < 0) { throw new DeveloperError( `The sizeY may not be negative, but is ${sizeX}` ); } const resultIterable = { [Symbol.iterator]: function* (): Iterator<[number, number]> { for (let y = 0; y < sizeY; y++) { for (let x = 0; x < sizeX; x++) { yield [x, y]; } } }, }; return resultIterable; } } ================================================ FILE: src/validation/metadata/SchemaDefinitionValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Buffers } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { BasicValidator } from "../BasicValidator"; import { SchemaValidator } from "./SchemaValidator"; import { ValidatedElement } from "../ValidatedElement"; import { IoValidationIssues } from "../../issues/IoValidationIssue"; import { JsonValidationIssues } from "../../issues/JsonValidationIssues"; /** * Utility class for validating the definition of a metadata schema. * * The metadata schema can either be defined as an inlined `schema` * object in the JSON, or via a `schemaUri` (but not both!). * This class resolves and validates the schema from either of * these sources, and returns information about that validation * result. */ export class SchemaDefinitionValidator { /** * Validates the given schema definition. * * The returned object will contain two properties: * - `wasPresent`: Whether any schema definition was given * - `validatedElement`: The validated `Schema` object * * If neither `schema` nor `schemaUri` are given, then the result * will be `{false, undefined}`. * * If the `schema` and `schemaUri` are both given, then an error will be * added to the given context, and `{ true, undefined }` will be returned. * * If the `schemaUri` is given but invalid, then an error will be * added to the given context, and `{ true, undefined }` will be returned. * * If the `schema` was given, or the schema could be resolved from * the `schemaUri`, and the schema turned out to be valid, then * `{ true, validatedSchema }` will be returned. * * @param path - The path for `ValidationIssue` instances * @param name - A name for the containing object (usually 'tileset') * @param schema - The `schema` object from the JSON * @param schemaUri - The `schemaUri` from the JSON * @param context - The `ValidationContext` * @returns The schema definition validation result */ static async validateSchemaDefinition( path: string, name: string, schema: any, schemaUri: any, context: ValidationContext ): Promise> { // The schema and schemaUri MUST NOT be present at the same time if (defined(schema) && defined(schemaUri)) { const issue = JsonValidationIssues.ONE_OF_ERROR( path, name, "schema", "schemaUri" ); context.addIssue(issue); return { wasPresent: true, validatedElement: undefined, }; } // Validate the schemaUri const schemaUriPath = path + "/schemaUri"; if (defined(schemaUri)) { // The schemaUri MUST be a string if ( !BasicValidator.validateString( schemaUriPath, "schemaUri", schemaUri, context ) ) { return { wasPresent: true, validatedElement: undefined, }; } } // The schema to validate is either the given one, // or the one that is resolved from the schemaUri let schemaToValidate = undefined; if (defined(schema)) { schemaToValidate = schema; } else if (defined(schemaUri)) { const resolvedSchema = await SchemaDefinitionValidator.resolveSchema( path, schemaUri, context ); if (!defined(resolvedSchema)) { return { wasPresent: true, validatedElement: undefined, }; } schemaToValidate = resolvedSchema; } else { // Neither the schema nor the schemaUri have been given return { wasPresent: false, validatedElement: undefined, }; } // Validate the schema let validatedSchema = undefined; const schemaPath = path + "/schema"; if (defined(schemaToValidate)) { if ( SchemaValidator.validateSchema(schemaPath, schemaToValidate, context) ) { validatedSchema = schemaToValidate; } } return { wasPresent: true, validatedElement: validatedSchema, }; } /** * Resolves the schema from the given URI * * @param path - The path for validation issues * @param schemaUri - The schema URI * @param context - The `ValidationContext` * @returns A promise that resolves with the result object, * or `undefined` if the schema could not be resolved */ private static async resolveSchema( path: string, schemaUri: any, context: ValidationContext ): Promise { if (defined(schemaUri) && typeof schemaUri === "string") { const resourceResolver = context.getResourceResolver(); const schemaBuffer = await resourceResolver.resolveData(schemaUri); if (!defined(schemaBuffer)) { const schemaUriPath = path + "/schemaUri"; const message = `The 'schemaUri' is '${schemaUri}' and could not be resolved`; const issue = IoValidationIssues.IO_ERROR(schemaUriPath, message); context.addIssue(issue); return undefined; } const bom = Buffers.getUnicodeBOMDescription(schemaBuffer); if (defined(bom)) { const message = `Unexpected BOM in schema JSON buffer: ${bom}`; const issue = IoValidationIssues.IO_ERROR(schemaUri, message); context.addIssue(issue); return undefined; } const schemaString = schemaBuffer.toString(); try { const resolvedSchema = JSON.parse(schemaString); return resolvedSchema; } catch (error) { //console.log(error); const issue = IoValidationIssues.JSON_PARSE_ERROR(path, `${error}`); context.addIssue(issue); return undefined; } } return undefined; } } ================================================ FILE: src/validation/metadata/SchemaValidator.ts ================================================ import { defined } from "3d-tiles-tools"; import { Schema } from "3d-tiles-tools"; import { ValidationContext } from "../ValidationContext"; import { Validator } from "../Validator"; import { BasicValidator } from "../BasicValidator"; import { StringValidator } from "../StringValidator"; import { RootPropertyValidator } from "../RootPropertyValidator"; import { ExtendedObjectsValidators } from "../ExtendedObjectsValidators"; import { MetadataClassValidator } from "./MetadataClassValidator"; import { MetadataEnumValidator } from "./MetadataEnumValidator"; import { IoValidationIssues } from "../../issues/IoValidationIssue"; /** * A class for validations related to `schema` objects. * * @internal */ export class SchemaValidator implements Validator { /** * Performs the validation of the schema that is parsed from the * given input string. * * @param input - The string that was read from a schema JSON file * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished * and indicates whether the object was valid or not. */ async validateJsonString( input: string, context: ValidationContext ): Promise { try { const object: Schema = JSON.parse(input); const result = await this.validateObject("", object, context); return result; } catch (error) { //console.log(error); const issue = IoValidationIssues.JSON_PARSE_ERROR("", "" + error); context.addIssue(issue); return false; } } /** * Implementation of the `Validator` interface that just passes the * input to `validateSchema`. * * @param input - The `Schema` object * @param context - The `ValidationContext` * @returns A promise that resolves when the validation is finished * and indicates whether the object was valid or not. */ async validateObject( path: string, input: Schema, context: ValidationContext ): Promise { return SchemaValidator.validateSchema(path, input, context); } /** * Performs the validation of the given `Schema` object that was parsed * from a schema JSON input. * * Issues that are encountered during the validation will be added * as `ValidationIssue` instances to the given `ValidationContext`. * * @param path - The path for the given object. This may either * be `"/schema"` (for a `tileset.schema`), or the empty string * (for a schema that was read from a standalone schema file). * @param schema - The `Schema` object * @param context - The `ValidationContext` */ static validateSchema( path: string, schema: Schema, context: ValidationContext ): boolean { // Make sure that the given value is an object if (!BasicValidator.validateObject(path, "schema", schema, context)) { return false; } let result = true; // Validate the object as a RootProperty if ( !RootPropertyValidator.validateRootProperty( path, "schema", schema, context ) ) { result = false; } // Perform the validation of the object in view of the // extensions that it may contain if ( !ExtendedObjectsValidators.validateExtendedObject(path, schema, context) ) { result = false; } // If there was an extension validator that overrides the // default validation, then skip the remaining validation. if (ExtendedObjectsValidators.hasOverride(schema)) { return result; } // Validate the id const id = schema.id; const idPath = path + "/id"; // The id MUST be defined // The id MUST be a string // The id MUST be a valid identifier if (!StringValidator.validateIdentifierString(idPath, "id", id, context)) { result = false; } // Validate the name // If the name is defined, it MUST be a string if (!BasicValidator.validateOptionalString(path, schema, "name", context)) { result = false; } // Validate the description // If the description is defined, it MUST be a string if ( !BasicValidator.validateOptionalString( path, schema, "description", context ) ) { result = false; } // Validate the version // If the version is defined, it MUST be a string if ( !BasicValidator.validateOptionalString(path, schema, "version", context) ) { result = false; } // Validate the classes const classes = schema.classes; const classesPath = path + "/classes"; if (defined(classes)) { // The classes MUST be an object if ( !BasicValidator.validateObject(classesPath, "classes", classes, context) ) { result = false; } else { for (const [className, metadataClass] of Object.entries(classes)) { const metadataClassPath = classesPath + "/" + className; // Each class name MUST match the ID regex if ( !StringValidator.validateIdentifierString( metadataClassPath, className, className, context ) ) { result = false; } if ( !MetadataClassValidator.validateMetadataClass( metadataClassPath, className, metadataClass, schema, context ) ) { result = false; } } } } // Validate the enums const enums = schema.enums; const enumsPath = path + "/enums"; if (defined(enums)) { // The enums MUST be an object if (!BasicValidator.validateObject(enumsPath, "enums", enums, context)) { result = false; } else { for (const [enumName, metadataEnum] of Object.entries(enums)) { const metadataEnumPath = enumsPath + "/" + enumName; // Each enum name MUST match the ID regex if ( !StringValidator.validateIdentifierString( metadataEnumPath, enumName, enumName, context ) ) { result = false; } if ( !MetadataEnumValidator.validateMetadataEnum( metadataEnumPath, enumName, metadataEnum, context ) ) { result = false; } } } } return result; } } ================================================ FILE: tools/README.md ================================================ ### 3D Tiles Tools The `3d-tiles-tools` library has been moved to [https://github.com/CesiumGS/3d-tiles-tools](https://github.com/CesiumGS/3d-tiles-tools). ================================================ FILE: tsconfig.json ================================================ { "compilerOptions": { "module": "commonjs", "target": "es2021", "outDir": "build", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "moduleResolution": "node", "resolveJsonModule": true, "strictNullChecks": true, "noImplicitOverride": true, "declaration": true, "declarationMap": true, "lib": [ "es2021", "dom" ] }, "include": ["src"], "exclude": ["node_modules"] }