@cognite/reveal 2.2.2 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/cad.d.ts +4 -4
- package/core/index.d.ts +7 -7
- package/core/src/datamodels/base/SupportedModelTypes.d.ts +4 -4
- package/core/src/datamodels/base/index.d.ts +6 -6
- package/core/src/datamodels/base/types.d.ts +14 -14
- package/core/src/datamodels/cad/CadManager.d.ts +45 -45
- package/core/src/datamodels/cad/CadModelFactory.d.ts +7 -7
- package/core/src/datamodels/cad/CadModelSectorLoadStatistics.d.ts +38 -38
- package/core/src/datamodels/cad/createCadManager.d.ts +9 -9
- package/core/src/datamodels/cad/picking.d.ts +28 -28
- package/core/src/datamodels/cad/rendering/RenderAlreadyLoadedGeometryProvider.d.ts +10 -10
- package/core/src/datamodels/cad/sector/CadModelClipper.d.ts +10 -10
- package/core/src/datamodels/cad/styling/AssetNodeCollection.d.ts +38 -38
- package/core/src/datamodels/cad/styling/InvertedNodeCollection.d.ts +24 -24
- package/core/src/datamodels/cad/styling/NodeCollectionDeserializer.d.ts +26 -26
- package/core/src/datamodels/cad/styling/PopulateIndexSetFromPagedResponseHelper.d.ts +24 -24
- package/core/src/datamodels/cad/styling/PropertyFilterNodeCollection.d.ts +54 -54
- package/core/src/datamodels/cad/styling/SinglePropertyFilterNodeCollection.d.ts +50 -50
- package/core/src/datamodels/cad/styling/index.d.ts +8 -8
- package/core/src/datamodels/pointcloud/PointCloudFactory.d.ts +9 -9
- package/core/src/datamodels/pointcloud/PointCloudManager.d.ts +26 -26
- package/core/src/datamodels/pointcloud/PointCloudMetadata.d.ts +11 -11
- package/core/src/datamodels/pointcloud/PointCloudMetadataRepository.d.ts +13 -13
- package/core/src/datamodels/pointcloud/PointCloudNode.d.ts +62 -62
- package/core/src/datamodels/pointcloud/PotreeGroupWrapper.d.ts +39 -39
- package/core/src/datamodels/pointcloud/PotreeNodeWrapper.d.ts +38 -38
- package/core/src/datamodels/pointcloud/createPointCloudManager.d.ts +6 -6
- package/core/src/datamodels/pointcloud/index.d.ts +5 -5
- package/core/src/datamodels/pointcloud/picking.d.ts +29 -29
- package/core/src/datamodels/pointcloud/types.d.ts +114 -114
- package/core/src/index.d.ts +19 -19
- package/core/src/internals.d.ts +15 -15
- package/core/src/migration.d.ts +8 -8
- package/core/src/public/RevealManager.d.ts +64 -64
- package/core/src/public/createRevealManager.d.ts +23 -23
- package/core/src/public/migration/Cognite3DModel.d.ts +339 -339
- package/core/src/public/migration/Cognite3DViewer.d.ts +566 -611
- package/core/src/public/migration/CogniteModelBase.d.ts +17 -17
- package/core/src/public/migration/CognitePointCloudModel.d.ts +121 -121
- package/core/src/public/migration/NodeIdAndTreeIndexMaps.d.ts +4 -4
- package/core/src/public/migration/NotSupportedInMigrationWrapperError.d.ts +11 -11
- package/core/src/public/migration/RenderController.d.ts +4 -4
- package/core/src/public/migration/types.d.ts +290 -290
- package/core/src/public/types.d.ts +46 -46
- package/core/src/storage/RevealManagerHelper.d.ts +58 -58
- package/core/src/utilities/BoundingBoxClipper.d.ts +23 -23
- package/core/src/utilities/Spinner.d.ts +27 -27
- package/core/src/utilities/ViewStateHelper.d.ts +37 -33
- package/core/src/utilities/callActionWithIndicesAsync.d.ts +4 -4
- package/core/src/utilities/index.d.ts +8 -8
- package/core/src/utilities/reflection.d.ts +7 -7
- package/core/src/utilities/worldToViewport.d.ts +30 -30
- package/core/utilities.d.ts +4 -4
- package/extensions/datasource.d.ts +9 -9
- package/extensions/datasource.js +6 -6
- package/extensions/datasource.map +1 -1
- package/index.d.ts +9 -8
- package/index.js +101 -91
- package/index.map +1 -1
- package/package.json +2 -2
- package/packages/cad-geometry-loaders/index.d.ts +14 -14
- package/packages/cad-geometry-loaders/src/CadLoadingHints.d.ts +11 -11
- package/packages/cad-geometry-loaders/src/CadModelSectorBudget.d.ts +26 -26
- package/packages/cad-geometry-loaders/src/CadModelUpdateHandler.d.ts +44 -44
- package/packages/cad-geometry-loaders/src/sector/CachedRepository.d.ts +25 -25
- package/packages/cad-geometry-loaders/src/sector/ModelStateHandler.d.ts +12 -12
- package/packages/cad-geometry-loaders/src/sector/Repository.d.ts +9 -9
- package/packages/cad-geometry-loaders/src/sector/SectorLoader.d.ts +28 -28
- package/packages/cad-geometry-loaders/src/sector/SimpleAndDetailedToSector3D.d.ts +20 -20
- package/packages/cad-geometry-loaders/src/sector/culling/ByVisibilityGpuSectorCuller.d.ts +53 -53
- package/packages/cad-geometry-loaders/src/sector/culling/OccludingGeometryProvider.d.ts +6 -6
- package/packages/cad-geometry-loaders/src/sector/culling/OrderSectorsByVisibilityCoverage.d.ts +107 -107
- package/packages/cad-geometry-loaders/src/sector/culling/SectorCuller.d.ts +33 -33
- package/packages/cad-geometry-loaders/src/sector/culling/TakenSectorTree.d.ts +24 -24
- package/packages/cad-geometry-loaders/src/sector/culling/types.d.ts +71 -71
- package/packages/cad-geometry-loaders/src/sector/rxSectorUtilities.d.ts +12 -12
- package/packages/cad-geometry-loaders/src/sector/sectorUtilities.d.ts +20 -20
- package/packages/cad-geometry-loaders/src/utilities/PromiseUtils.d.ts +18 -18
- package/packages/cad-geometry-loaders/src/utilities/arrays.d.ts +5 -5
- package/packages/cad-geometry-loaders/src/utilities/groupMeshesByNumber.d.ts +8 -8
- package/packages/cad-geometry-loaders/src/utilities/rxOperations.d.ts +6 -6
- package/packages/cad-geometry-loaders/src/utilities/types.d.ts +25 -25
- package/packages/cad-parsers/index.d.ts +21 -21
- package/packages/cad-parsers/src/cad/CadSectorParser.d.ts +15 -15
- package/packages/cad-parsers/src/cad/LevelOfDetail.d.ts +8 -8
- package/packages/cad-parsers/src/cad/filterInstanceMesh.d.ts +6 -6
- package/packages/cad-parsers/src/cad/filterPrimitives.d.ts +9 -9
- package/packages/cad-parsers/src/cad/primitiveGeometries.d.ts +31 -31
- package/packages/cad-parsers/src/cad/triangleMeshes.d.ts +6 -6
- package/packages/cad-parsers/src/cad/types.d.ts +56 -56
- package/packages/cad-parsers/src/metadata/CadMetadataParser.d.ts +7 -7
- package/packages/cad-parsers/src/metadata/CadModelMetadata.d.ts +44 -44
- package/packages/cad-parsers/src/metadata/CadModelMetadataRepository.d.ts +16 -16
- package/packages/cad-parsers/src/metadata/MetadataRepository.d.ts +7 -7
- package/packages/cad-parsers/src/metadata/parsers/CadMetadataParserV8.d.ts +51 -51
- package/packages/cad-parsers/src/metadata/types.d.ts +41 -41
- package/packages/cad-parsers/src/sector/RootSectorNode.d.ts +12 -12
- package/packages/cad-parsers/src/sector/SectorNode.d.ts +21 -21
- package/packages/cad-parsers/src/utilities/SectorScene.d.ts +21 -21
- package/packages/cad-parsers/src/utilities/SectorSceneFactory.d.ts +9 -9
- package/packages/cad-parsers/src/utilities/computeBoundingBoxFromAttributes.d.ts +9 -9
- package/packages/cad-parsers/src/utilities/float32BufferToMatrix.d.ts +12 -12
- package/packages/cad-parsers/src/utilities/types.d.ts +48 -48
- package/packages/cad-styling/index.d.ts +9 -9
- package/packages/cad-styling/src/CombineNodeCollectionBase.d.ts +31 -31
- package/packages/cad-styling/src/IntersectionNodeCollection.d.ts +15 -15
- package/packages/cad-styling/src/NodeAppearance.d.ts +62 -62
- package/packages/cad-styling/src/NodeAppearanceProvider.d.ts +33 -33
- package/packages/cad-styling/src/NodeCollectionBase.d.ts +47 -47
- package/packages/cad-styling/src/TreeIndexNodeCollection.d.ts +23 -23
- package/packages/cad-styling/src/UnionNodeCollection.d.ts +15 -15
- package/packages/camera-manager/index.d.ts +6 -4
- package/packages/camera-manager/src/CameraManager.d.ts +85 -0
- package/packages/camera-manager/src/ComboControls.d.ts +102 -100
- package/packages/camera-manager/src/Keyboard.d.ts +17 -17
- package/packages/camera-manager/src/types.d.ts +64 -0
- package/packages/data-source/index.d.ts +6 -6
- package/packages/data-source/src/CdfDataSource.d.ts +19 -19
- package/packages/data-source/src/DataSource.d.ts +26 -26
- package/packages/data-source/src/LocalDataSource.d.ts +15 -15
- package/packages/logger/index.d.ts +5 -5
- package/packages/logger/src/Log.d.ts +5 -5
- package/packages/metrics/index.d.ts +5 -5
- package/packages/metrics/src/MetricsLogger.d.ts +21 -21
- package/packages/metrics/src/types.d.ts +7 -7
- package/packages/modeldata-api/index.d.ts +13 -13
- package/packages/modeldata-api/src/CdfModelDataProvider.d.ts +17 -15
- package/packages/modeldata-api/src/CdfModelIdentifier.d.ts +17 -17
- package/packages/modeldata-api/src/CdfModelMetadataProvider.d.ts +19 -19
- package/packages/modeldata-api/src/CdfModelOutputsProvider.d.ts +15 -15
- package/packages/modeldata-api/src/LocalModelDataProvider.d.ts +10 -10
- package/packages/modeldata-api/src/LocalModelIdentifier.d.ts +14 -14
- package/packages/modeldata-api/src/LocalModelMetadataProvider.d.ts +14 -14
- package/packages/modeldata-api/src/Model3DOutputList.d.ts +17 -17
- package/packages/modeldata-api/src/ModelIdentifier.d.ts +12 -12
- package/packages/modeldata-api/src/ModelMetadataProvider.d.ts +17 -17
- package/packages/modeldata-api/src/applyDefaultModelTransformation.d.ts +6 -6
- package/packages/modeldata-api/src/types.d.ts +41 -41
- package/packages/modeldata-api/src/utilities.d.ts +7 -7
- package/packages/nodes-api/index.d.ts +6 -6
- package/packages/nodes-api/src/NodesApiClient.d.ts +52 -52
- package/packages/nodes-api/src/NodesCdfClient.d.ts +24 -24
- package/packages/nodes-api/src/NodesLocalClient.d.ts +30 -30
- package/packages/nodes-api/src/types.d.ts +10 -10
- package/packages/rendering/index.d.ts +17 -17
- package/packages/rendering/src/CadMaterialManager.d.ts +37 -37
- package/packages/rendering/src/InstancedMeshManager.d.ts +20 -20
- package/packages/rendering/src/cameraconfig.d.ts +12 -12
- package/packages/rendering/src/rendering/EffectRenderManager.d.ts +99 -99
- package/packages/rendering/src/rendering/NodeAppearanceTextureBuilder.d.ts +51 -51
- package/packages/rendering/src/rendering/RenderMode.d.ts +15 -15
- package/packages/rendering/src/rendering/createSimpleGeometryMesh.d.ts +6 -6
- package/packages/rendering/src/rendering/matCapTextureData.d.ts +5 -5
- package/packages/rendering/src/rendering/materials.d.ts +23 -23
- package/packages/rendering/src/rendering/primitives.d.ts +12 -12
- package/packages/rendering/src/rendering/shaders.d.ts +101 -101
- package/packages/rendering/src/rendering/types.d.ts +76 -76
- package/packages/rendering/src/sector/CadNode.d.ts +54 -54
- package/packages/rendering/src/transform/NodeTransformProvider.d.ts +13 -13
- package/packages/rendering/src/transform/NodeTransformTextureBuilder.d.ts +23 -23
- package/packages/rendering/src/transform/TransformOverrideBuffer.d.ts +21 -21
- package/packages/rendering/src/utilities/types.d.ts +26 -26
- package/packages/tools/index.d.ts +15 -15
- package/packages/tools/src/AxisView/AxisViewTool.d.ts +32 -32
- package/packages/tools/src/AxisView/types.d.ts +98 -98
- package/packages/tools/src/Cognite3DViewerToolBase.d.ts +25 -25
- package/packages/tools/src/DebugCameraTool.d.ts +20 -20
- package/packages/tools/src/DebugLoadedSectorsTool.d.ts +23 -23
- package/packages/tools/src/ExplodedViewTool.d.ts +12 -12
- package/packages/tools/src/Geomap/Geomap.d.ts +17 -17
- package/packages/tools/src/Geomap/GeomapTool.d.ts +24 -24
- package/packages/tools/src/Geomap/MapConfig.d.ts +195 -195
- package/packages/tools/src/HtmlOverlay/BucketGrid2D.d.ts +28 -28
- package/packages/tools/src/HtmlOverlay/HtmlOverlayTool.d.ts +159 -159
- package/packages/tools/src/Timeline/Keyframe.d.ts +38 -38
- package/packages/tools/src/Timeline/TimelineTool.d.ts +79 -79
- package/packages/tools/src/Timeline/types.d.ts +13 -13
- package/packages/tools/src/types.d.ts +4 -4
- package/packages/utilities/index.d.ts +24 -24
- package/packages/utilities/src/CameraConfiguration.d.ts +10 -10
- package/packages/utilities/src/IndexSet.d.ts +1 -1
- package/packages/utilities/src/NumericRange.d.ts +22 -22
- package/packages/utilities/src/RandomColors.d.ts +34 -34
- package/packages/utilities/src/WebGLRendererStateHelper.d.ts +15 -15
- package/packages/utilities/src/assertNever.d.ts +7 -7
- package/packages/utilities/src/cache/MemoryRequestCache.d.ts +22 -22
- package/packages/utilities/src/cache/MostFrequentlyUsedCache.d.ts +19 -19
- package/packages/utilities/src/cache/RequestCache.d.ts +13 -13
- package/packages/utilities/src/datastructures/DynamicDefragmentedBuffer.d.ts +22 -22
- package/packages/utilities/src/determinePowerOfTwoDimensions.d.ts +11 -11
- package/packages/utilities/src/disposeAttributeArrayOnUpload.d.ts +17 -17
- package/packages/utilities/src/events/EventTrigger.d.ts +13 -13
- package/packages/utilities/src/events/InputHandler.d.ts +34 -0
- package/packages/utilities/src/events/clickOrTouchEventOffset.d.ts +13 -13
- package/packages/utilities/src/events/index.d.ts +6 -5
- package/packages/utilities/src/indexset/IndexSet.d.ts +26 -26
- package/packages/utilities/src/indexset/IntermediateIndexNode.d.ts +26 -26
- package/packages/utilities/src/indexset/LeafIndexNode.d.ts +16 -16
- package/packages/utilities/src/isMobileOrTablet.d.ts +4 -4
- package/packages/utilities/src/networking/isTheSameDomain.d.ts +11 -11
- package/packages/utilities/src/objectTraversal.d.ts +8 -8
- package/packages/utilities/src/packFloat.d.ts +6 -6
- package/packages/utilities/src/revealEnv.d.ts +10 -10
- package/packages/utilities/src/three/AutoDisposeGroup.d.ts +17 -17
- package/packages/utilities/src/three/BoundingBoxLOD.d.ts +27 -27
- package/packages/utilities/src/three/getBox3CornerPoints.d.ts +5 -5
- package/packages/utilities/src/transformCameraConfiguration.d.ts +6 -6
- package/packages/utilities/src/types.d.ts +10 -10
- package/packages/utilities/src/workers/WorkerPool.d.ts +14 -14
- package/tools.d.ts +7 -7
- package/tools.js +62 -58
- package/tools.map +1 -1
package/tools.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap","webpack:///external \"three\"","webpack:///./packages/utilities/src/objectTraversal.ts","webpack:///./packages/utilities/src/transformCameraConfiguration.ts","webpack:///./packages/utilities/src/RandomColors.ts","webpack:///./packages/utilities/src/events/clickOrTouchEventOffset.ts","webpack:///./packages/utilities/src/events/EventTrigger.ts","webpack:///./packages/utilities/src/assertNever.ts","webpack:///./packages/utilities/src/NumericRange.ts","webpack:///./packages/utilities/src/determinePowerOfTwoDimensions.ts","webpack:///./packages/utilities/src/indexset/IntermediateIndexNode.ts","webpack:///./packages/utilities/src/indexset/LeafIndexNode.ts","webpack:///./packages/utilities/src/indexset/IndexSet.ts","webpack:///./packages/utilities/src/packFloat.ts","webpack:///./packages/utilities/src/datastructures/DynamicDefragmentedBuffer.ts","webpack:///./packages/utilities/src/three/AutoDisposeGroup.ts","webpack:///./packages/utilities/src/three/BoundingBoxLOD.ts","webpack:///./packages/utilities/src/three/getBox3CornerPoints.ts","webpack:///./packages/utilities/src/isMobileOrTablet.ts","webpack:///./packages/utilities/src/WebGLRendererStateHelper.ts","webpack:///./packages/utilities/src/revealEnv.ts","webpack:///./packages/utilities/src/workers/WorkerPool.ts","webpack:///./packages/utilities/src/networking/isTheSameDomain.ts","webpack:///./packages/utilities/src/cache/MemoryRequestCache.ts","webpack:///./packages/utilities/src/cache/MostFrequentlyUsedCache.ts","webpack:///./packages/utilities/src/disposeAttributeArrayOnUpload.ts","webpack:///./packages/cad-parsers/src/utilities/SectorScene.ts","webpack:///./packages/cad-parsers/src/metadata/parsers/CadMetadataParserV8.ts","webpack:///./packages/cad-parsers/src/metadata/CadMetadataParser.ts","webpack:///./packages/cad-parsers/src/utilities/types.ts","webpack:///./packages/cad-parsers/src/metadata/CadModelMetadataRepository.ts","webpack:///./packages/cad-parsers/src/cad/LevelOfDetail.ts","webpack:///./packages/cad-parsers/src/utilities/SectorSceneFactory.ts","webpack:///./packages/cad-parsers/src/sector/SectorNode.ts","webpack:///./packages/cad-parsers/src/sector/RootSectorNode.ts","webpack:///./packages/cad-parsers/src/cad/CadSectorParser.ts","webpack:///./packages/cad-parsers/src/utilities/computeBoundingBoxFromAttributes.ts","webpack:///./packages/cad-parsers/src/cad/filterPrimitives.ts","webpack:///./packages/cad-parsers/src/cad/filterInstanceMesh.ts","webpack:///./packages/cad-parsers/src/utilities/float32BufferToMatrix.ts","webpack:///./packages/cad-parsers/src/cad/primitiveGeometries.ts","webpack:///./packages/cad-parsers/src/cad/triangleMeshes.ts","webpack:///./packages/modeldata-api/src/CdfModelDataProvider.ts","webpack:///./packages/modeldata-api/src/CdfModelIdentifier.ts","webpack:///./packages/modeldata-api/src/types.ts","webpack:///./packages/modeldata-api/src/applyDefaultModelTransformation.ts","webpack:///./packages/modeldata-api/src/Model3DOutputList.ts","webpack:///./packages/modeldata-api/src/CdfModelMetadataProvider.ts","webpack:///./packages/modeldata-api/src/CdfModelOutputsProvider.ts","webpack:///./packages/modeldata-api/src/utilities.ts","webpack:///./packages/modeldata-api/src/LocalModelDataProvider.ts","webpack:///./packages/modeldata-api/src/LocalModelIdentifier.ts","webpack:///./packages/modeldata-api/src/LocalModelMetadataProvider.ts","webpack:///external \"assert\"","webpack:///./packages/metrics/src/MetricsLogger.ts","webpack:///./packages/logger/src/Log.ts","webpack:///./packages/logger/index.ts","webpack:///external \"@tweenjs/tween.js\"","webpack:///external \"mixpanel-browser\"","webpack:///./core/src/utilities/worldToViewport.ts","webpack:///external \"lodash/cloneDeep\"","webpack:///external \"geo-three\"","webpack:///external \"@cognite/sdk-core\"","webpack:///./core/src/utilities/index.ts","webpack:///./core/src/utilities/BoundingBoxClipper.ts","webpack:///external \"lodash/debounce\"","webpack:///external \"lodash/range\"","webpack:///external \"comlink\"","webpack:///external \"loglevel\"","webpack:///external \"skmeans\"","webpack:///external \"lodash/merge\"","webpack:///./packages/tools/src/Cognite3DViewerToolBase.ts","webpack:///./packages/tools/src/HtmlOverlay/BucketGrid2D.ts","webpack:///./packages/tools/src/HtmlOverlay/HtmlOverlayTool.ts","webpack:///./packages/tools/src/ExplodedViewTool.ts","webpack:///./packages/tools/src/DebugCameraTool.ts","webpack:///./packages/tools/src/AxisView/types.ts","webpack:///./packages/tools/src/AxisView/AxisViewTool.ts","webpack:///./packages/tools/src/Geomap/MapConfig.ts","webpack:///./packages/tools/src/Geomap/Geomap.ts","webpack:///./packages/tools/src/Geomap/GeomapTool.ts","webpack:///./packages/tools/src/Timeline/Keyframe.ts","webpack:///./packages/tools/src/Timeline/TimelineTool.ts","webpack:///./packages/tools/src/DebugLoadedSectorsTool.ts"],"names":["root","factory","exports","module","define","amd","a","i","self","this","installedModules","__webpack_require__","moduleId","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","require","traverseDepthFirst","visitor","children","length","transformCameraConfiguration","cameraConfiguration","modelMatrix","undefined","position","target","applyMatrix4","colorIndex","color","_colors","newColor","generateRandomColor","set","Math","floor","g","b","colorRGB","hue","random","saturation","lightness","setHSL","clickOrTouchEventOffset","ev","rect","getBoundingClientRect","MouseEvent","offsetX","clientX","left","offsetY","clientY","top","changedTouches","touch","Map","EventTrigger","_listeners","listener","push","index","indexOf","splice","args","forEach","assertNever","x","message","Error","NumericRange","from","count","toInclusive","Array","values","other","range","intersects","createFromInterval","max","min","action","determinePowerOfTwoDimensions","elementCount","width","ceilToPowerOfTwo","sqrt","height","log2","log","v","pow","ceil","right","maxSubtreeDepth","r0","r1","balance","traverse","contains","intersectsOrCoinciding","newNode","addRange","fromIndexNodesAndBalance","canUnionLeft","canUnionRight","newLeft","leftRange","soak","newRight","rightRange","unioned","union","newThis","soakedRange","nodeToReturn","leftSubTreeSize","rightSubTreeSize","rotateSmallerRight","rotateRight","rotateSmallerLeft","rotateLeft","clone","node","isInside","hasIntersectionWith","leftRes","rightRes","unionRange","nextRoot","begin","endInclusive","rootNode","isNumericRange","add","removeRange","ranges","forEachRange","result","num","arr","toIndexArray","Set","originalRanges","toRangeArray","newRanges","otherSet","leftBoundRange","rightBoundRange","invertedRanges","st","packFloatInto","f","targetBuffer","offset","F","abs","Sign","step","Exponent","Mantissa","exp2","mod","edge","y","DynamicDefragmentedBuffer","initialSize","type","_numFilled","_batchIdCounter","_batchMap","_type","minimalPowerOfTwo","_buffer","array","isReallocated","newSize","allocateNewBuffer","batchId","createBatch","bufferIsReallocated","batch","copyWithin","buffer","_currentTail","prev","next","currentBatch","delete","newBuffer","emptyGeometry","_isDisposed","_referenceCount","ensureNotDisposed","dispose","meshes","filter","map","mesh","geometry","updateVars","camPos","bounds","boundingBox","super","_activeLevel","_levels","isLOD","autoUpdate","_boundingBox","copy","distance","sort","visible","camera","updateCurrentLevel","levels","matrixWorld","cameraZoom","zoom","setFromMatrixPosition","distanceToCamera","distanceToPoint","findIndex","getBox3CornerPoints","box","z","isMobileOrTablet","check","navigator","userAgent","vendor","window","opera","test","substr","renderer","_originalState","_renderer","alpha","clearColor","getClearColor","clearAlpha","getClearAlpha","setClearColor","size","getSize","setSize","enabled","localClippingEnabled","autoClear","renderTarget","getRenderTarget","setRenderTarget","revealEnv","publicPath","workerList","numberOfWorkers","determineNumberOfWorkers","newWorker","worker","createWorker","activeJobCount","messageIdCounter","async","actualWorkerVersion","getVersion","e","minWorkerVersion","majorMin","minorMin","patchMin","split","parseInt","majorWorker","minorWorker","patchWorker","errorMessage","checkWorkerVersion","catch","error","workerObjUrl","URL","revokeObjectURL","_defaultPool","workerUrl","options","url1","url2","location","origin","isRelative","url","match","constructedURLs","startsWith","host","console","isTheSameDomain","Worker","blob","Blob","JSON","stringify","createObjectURL","work","targetWorker","reduce","bestWorker","candidate","hardwareConcurrency","TimestampedContainer","_value","_lastAccessTime","Date","now","MemoryRequestCache","maxElementsInCache","removeCallback","defaultCleanupCount","_data","_maxElementsInCache","_defaultCleanupCount","_removeCallback","id","has","data","isFull","cleanCache","insert","allResults","entries","lastAccessTime","entry","pop","remove","clear","MostFrequentlyUsedCache","capacity","disposeCallback","_cache","_retrieves","_capacity","_disposeCallback","retrieveCount","ensureWithinCapacity","keysForRemoval","keys","retrivalCount","slice","disposeAttributeArrayOnUpload","version","maxTreeIndex","unit","sectorsById","sectors","sectorId","accepted","containsPoint","intersectsBox","allBounds","corners","toArray","numClusters","clusters","clusterCounts","idxs","fill","clusterBounds","_","biggestCluster","idx","cluster","expandByPoint","intersectingBounds","merged","projectionMatrix","inverseCameraModelMatrix","frustumMatrix","multiplyMatrices","frustum","setFromProjectionMatrix","parseCadMetadataV8","metadata","parentIds","sector","facesFile","quadSize","coverageFactors","xy","yz","xz","recursiveCoverageFactors","fileName","downloadSize","indexFile","determineFacesFile","bb","min_x","min_y","min_z","max_x","max_y","max_z","path","depth","estimatedDrawCallCount","estimatedRenderCost","estimatedTriangleCount","createSectorMetadata","parentId","rootSector","populateCoverageFactorsFromAnchestors","validFacesFileSection","hasDummyFacesFileSection","child","parsedJson","WellKnownDistanceToMeterConversionFactors","modelMetadataProvider","modelDataProvider","cadMetadataParser","blobFileName","_currentModelIdentifier","_modelMetadataProvider","_modelDataProvider","_cadSceneParser","_blobFileName","modelIdentifier","blobBaseUrlPromise","getModelUri","modelMatrixPromise","getModelMatrix","modelCameraPromise","getModelCamera","blobBaseUrl","json","getJsonFile","scene","parse","conversionFactor","makeScale","multiply","createScaleToMetersModelMatrix","inverseModelMatrix","invert","modelBaseUrl","geometryClipBox","LevelOfDetail","sectorPath","_lod","Discarded","_updatedTimestamp","determineSectorDepth","_group","geomtryGroup","levelOfDetail","resetGeometry","reference","updateMatrixWorld","dereference","modelMetadata","modelBounds","sectorNodeMap","buildScene","parent","sectorGroup","matrixAutoUpdate","setModelTransformation","matrix","out","workerPool","defaultPool","parseDetailed","parseSimple","parseCtm","quadsArrayBuffer","postWorkToAvailable","parseQuads","sectorArrayBuffer","parseSector","ctmArrayBuffer","computeBoundingBoxFromCenterAndRadiusAttributesVars","centerA","centerB","sphere","computeBoundingBoxFromVertexAttributesVars","vertex1","vertex2","vertex3","vertex4","computeBoundingBoxFromInstanceMatrixAttributesVars","instanceMatrix","computeBoundingBoxFromEllipseAttributesVars","center","filterPrimitivesOutsideClipBox","attributesByteValues","attributes","clipBox","getBoundsOfElementsCallback","elementSize","attributeFloatValues","Float32Array","instanceBbox","filteredByteValues","Uint8Array","filteredCount","elementValues","subarray","filterPrimitivesOutsideClipBoxByBaseBoundsAndInstanceMatrix","baseBox","instanceMatrixAttribute","outBox","elementIndex","baseBoundingBox","BYTES_PER_ELEMENT","computeBoundingBoxFromInstanceMatrixAttributes","filterPrimitivesOutsideClipBoxByCenterAndRadius","radiusAattributeName","radiusBattributeName","centerAattribute","centerBattribute","radiusAattribute","radiusBattribute","readAttribute","attribute","radiusA","radiusB","getBoundingBox","computeBoundingBoxFromCenterAndRadiusAttributes","filterPrimitivesOutsideClipBoxByVertices","vertex1attribute","vertex2attribute","vertex3attribute","vertex4attribute","vertex1Attribute","vertex2Attribute","vertex3Attribute","vertex4Attribute","setFromPoints","computeBoundingBoxFromVertexAttributes","filterPrimitivesOutsideClipBoxByEllipse","radius1AttributeName","radius2AttributeName","centerAttribute","horizontalRadiusAttribute","verticalRadiusAttribute","heightAttribute","radius1Attribute","radius2Attribute","radius1","radius2","extent","setFromCenterAndSize","computeBoundingBoxFromEllipseAttributes","filterInstanceMeshVars","baseBounds","instanceBounds","filterInstanceMesh","vertices","indices","instanceMesh","makeEmpty","j","triangleOffset","triangleCount","v0","v1","v2","filteredOffset","instanceCount","treeIndices","filteredInstanceMatrices","instanceMatrices","filteredTreeIndices","filteredColors","indexOffset","elementInstanceMatrix","elementColor","colors","elementTreeIndex","boxGeometry","boxGeometryBoundingBox","getIndex","getAttribute","normal","computeBoundingBox","quadGeometry","quadGeometryBoundingBox","trapeziumGeometry","trapeziumGeometryBoundingBox","Uint16Array","setFromArray","coneGeometry","coneGeometryBoundingBox","positions","torusLodGeometries","torusGeometryBoundingBox","transformFunc","u","PI","tubularSegments","radialSegments","segmentsX","segmentsY","segmentsXInv","segmentsYInv","generatePlane3D","nutGeometry","nutGeometryBoundingBox","makeRotationX","createTriangleMeshes","triangleMeshes","material","filteredTriangleMeshes","isTriangleMeshWithinArgs","isTriangleMeshWithin","onUpload","setIndex","setAttribute","boundingSphere","getBoundingSphere","obj","fileId","userData","CdfModelDataProvider","client","getDefaultRequestHeaders","baseUrl","headers","Accept","input","retries","fetch","err","fetchWithRetry","method","arrayBuffer","CdfModelIdentifier","modelId","revisionId","modelFormat","revealInternalId","String","File3dFormat","cadFromCdfToThreeMatrix","applyDefaultModelTransformation","format","RevealCadModel","premultiply","EptPointCloud","Model3DOutputList","outputs","outputFormat","supportedVersions","candidates","_client","toString","model","revisions3D","retrieve","rotation","makeRotationFromEuler","mostRecentOutput","getOutputs","findMostRecentOutput","directoryId","blobId","getBaseUrl","getRequestPath","project","params","response","status","items","fetchWithStatusCheck","ok","body","LocalModelIdentifier","localPath","Promise","resolve","VERSION","MIXPANEL_TOKEN","applicationId","eventProps","init","disable_cookie","disable_persistence","ip","property_blacklist","reset","identify","_sessionProps","application","sessionId","replace","innerTrackEvent","logMetrics","globalThis","revealMetricsLogger","metricsLogger","eventName","combined","track","toolName","trackEvent","nodeCollectionClassToken","appearance","style","stack","worldToViewportVars","renderSize","worldToNormalizedViewportCoordinates","position3D","worldToViewportCoordinates","canvas","domElement","canvasWidth","canvasHeight","round","BoundingBoxClipper","_clippingPlanes","_box","updatePlanes","setFromNormalAndCoplanarPoint","minX","maxX","minY","maxY","minZ","maxZ","_disposedEvent","_disposed","event","handler","subscribe","unsubscribe","fire","unsubscribeAll","dimensions","_removedElements","_dimensions","_cells","_bounds","element","cell","cellsIntersecting","visitedElements","candidateElement","dimX","dimY","relativeBoundsMinX","relativeBoundsMaxX","relativeBoundsMinY","relativeBoundsMaxY","clamp","minI","maxI","minJ","maxJ","viewer","_htmlOverlays","_compositeOverlays","_preallocatedVariables","camNormal","point","nearPlane","farPlane","position2D","_onSceneRenderedHandler","onSceneRendered","_onViewerDisposedHandler","onViewerDisposed","_options","_viewer","on","scheduleUpdate","forceUpdate","trackCreateTool","getCamera","info","off","htmlElement","viewerDomElement","visibility","appendChild","getComputedStyle","removeChild","state","overlays","cleanupClusterElements","updateNewElementSizes","viewerCamera","viewerRenderer","getWorldPosition","getWorldDirection","addScaledVector","near","far","positionUpdatedCallback","insideCameraPlanes","distanceTo","clusterElements","commitDOMChanges","clientRect","offsetLeft","offsetTop","opacity","transition","fadeIn","fadeOut","clusteringOptions","clusterByOverlapInScreenSpace","createClusterElementCallback","canvasBounds","bottom","canvasSize","grid","elementBounds","createElementBounds","clusterMidpoint","removeOverlappingElements","midpoint","divideScalar","compositeElement","addComposite","treeIndex","cadModel","_cadModel","_rootTreeIndex","preloadBoundingBoxData","_treeBoundingBoxdata","then","expandRadius","expandData","all","direction","transform","resetNodeTransformByTreeIndex","setPosition","setNodeTransformByTreeIndex","rootTreeIndexBoundingBox","getBoundingBoxByTreeIndex","rootBoundingBox","getCenter","subTreeBoundingBoxes","getSubtreeTreeIndices","subTreeIndices","subTreeIndex","subTreeIndexBoundingBoxCenter","rootCenter","subTreeCenters","subVectors","payloads","payload","hideCameraHelper","_cameraHelper","addObject3D","removeObject3D","Corner","defaultAxisBoxCompassConfig","ringLabel","labelDelta","fontSize","fontColor","tickColor","defaultFaceConfig","label","outlineSize","outlineColor","faceColor","defaultAxisBoxConfig","corner","BottomRight","padding","animationSpeed","faces","xPositiveFace","xNegativeFace","yPositiveFace","yNegativeFace","zPositiveFace","zNegativeFace","compass","config","_dynamicUpdatePosition","_updateClickDiv","_screenPosition","_boxFaceGeometry","_raycastCamera","_raycaster","_layoutConfig","_axisGroup","_interactiveObjects","createAxisCross","_disposeClickDiv","createClickDiv","addAxisBoxToViewer","removeUiObject","querySelector","divElement","document","createElement","zIndex","xMouse","yMouse","addEventListener","mouseDownEvent","button","dispatchEvent","mouseMoveEvent","preventDefault","mouseUpEvent","handleClick","axisGroup","xAbsolute","yAbsolute","isAbsolute","clientWidth","TopRight","clientHeight","TopLeft","BottomLeft","addUiObject","xScreenPos","yScreenPos","boundingRect","xNdc","yNdc","setFromCamera","rayOrigin","rayDirection","normalize","intersectObjects","targetPosition","targetUp","upVector","moveCameraTo","cameraControls","interactiveObjects","createBoxFaces","createCompass","setupTransformOnRender","onBeforeRender","quaternion","facesConfig","createBoxFace","compassPlaneGeometry","createCompassTexture","side","transparent","sin","cos","up","lookAt","compassLayout","textureSize","context","getContext","halfSize","radius","tickWidth","tickSpace","strokeStyle","getStyle","lineWidth","setLineDash","beginPath","arc","stroke","font","textAlign","fillStyle","fillText","faceConfig","fillRect","face","getFaceTexture","multiplyScalar","parameters","targetAxis","targetUpAxis","currentCameraPosition","cameraTarget","getState","targetRelativeStartPosition","sub","normalizedFrom","omega","acos","dot","animation","Tween","forward","fromRotation","toRotation","setFromRotationMatrix","makeBasis","cross","angleTo","tmpPosition","tmpRotation","cachedCameraControlsEnabled","to","onUpdate","slerpQuaternions","setRotationFromQuaternion","start","onStart","onComplete","setState","update","MapProviders","MapboxMode","MapboxStyle","MapboxId","MapboxImageFormat","BingMapType","BingMapImageFormat","HereMapType","HereMapScheme","HereMapImageFormat","mapConfig","_intervalId","_onCameraChange","handleCameraChange","mapProvider","getMapProvider","_map","PLANAR","coords","datumsToSpherical","latlong","latitude","longitude","bound","models","getModelBoundingBox","requestRedraw","timeOut","setInterval","setTimeout","clearInterval","provider","BingMap","APIKey","HereMap","appCode","scheme","imageFormat","MapboxMap","tileFormat","OpenStreetMap","latLong","_maps","latLongToWorldCoordinates","date","_nodeCollectionAndAppearance","_model","_date","_index","assignStyledNodeCollection","nodes","nodeAppearance","unassignStyledNodeCollection","nodeCollection","trackCadModelStyled","classToken","_playback","_events","dateChanged","_keyframes","keyframe","sortKeyframesByDates","find","getKeyframeDate","startDate","endDate","totalDurationInMilliSeconds","stop","playState","dateInMs","getTime","tween","currentKeyframeIndex","prevIndex","deactivate","activate","activeKeyframe","isPlaying","pause","isPaused","resume","_boundingBoxes","setOptions","showDetailedSectors","showDiscardedSectors","showSimpleSectors","colorBy","leafsOnly","sectorPathFilterRegex","updateBoundingBoxes","getModelTransformation","shouldShowLod","Simple","Detailed","selectedSectorNodes","cadNode","isSectorNode","sectorNode","isSectorAcceptedByCurrentFilter","some","isLeaf","bboxNode","createBboxNodeFor","RegExp","allSelectedNodes","Colors","green","lerpHSL","red","yellow","nodesByTimestamp","updatedTimestamp","indexOfNode","determineColor"],"mappings":"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","file":"tools.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})((typeof self !== 'undefined' ? self : this), function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"https://apps-cdn.cogniteapp.com/@cognite/reveal-parser-worker/1.2.0/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 65);\n","module.exports = require(\"three\");","/*!\n * Copyright 2021 Cognite AS\n */\n\ninterface WithChildren<T> {\n readonly children: T[];\n}\n\nexport function traverseDepthFirst<T extends WithChildren<T>>(root: T, visitor: (element: T) => boolean): void {\n if (!visitor(root)) {\n return;\n }\n\n for (let i = 0; i < root.children.length; i++) {\n traverseDepthFirst(root.children[i], visitor);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\nimport { CameraConfiguration } from './CameraConfiguration';\n\nexport function transformCameraConfiguration(\n cameraConfiguration: CameraConfiguration | undefined,\n modelMatrix: THREE.Matrix4\n): CameraConfiguration | undefined {\n if (cameraConfiguration === undefined) {\n return undefined;\n }\n\n const { position, target } = cameraConfiguration;\n position.applyMatrix4(modelMatrix);\n target.applyMatrix4(modelMatrix);\n return {\n position,\n target\n };\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\n/**\n * Utility class for creating reasonable visible colors. Mainly meant for use\n * in debugging.\n */\nexport class RandomColors {\n private static readonly _colors: Map<number, THREE.Color> = new Map();\n\n /**\n * Returns a color as a THREE.Color.\n * @param colorIndex\n * @returns\n */\n static color(colorIndex: number): THREE.Color {\n const color = RandomColors._colors.get(colorIndex);\n if (color !== undefined) {\n return color;\n }\n\n const newColor = RandomColors.generateRandomColor();\n RandomColors._colors.set(colorIndex, newColor);\n return newColor;\n }\n\n /**\n * Returns color as RGB components between 0 and 255.\n * @param colorIndex Return\n * @returns\n */\n static colorRGB(colorIndex: number): [number, number, number] {\n const c = RandomColors.color(colorIndex);\n return [Math.floor(c.r * 255), Math.floor(c.g * 255), Math.floor(c.b * 255)];\n }\n\n /**\n * Returns a color string suitable for usage in CSS styles.\n * @param colorIndex\n * @returns\n */\n static colorCSS(colorIndex: number): string {\n const [r, g, b] = RandomColors.colorRGB(colorIndex);\n return `rgb(${r}, ${g}, ${b})`;\n }\n\n /**\n * Returns a random color with reasonable lightness and saturation\n * to make the color easily distinguishable from other colors.\n */\n static generateRandomColor(): THREE.Color {\n const hue = Math.random();\n const saturation = 0.4 + Math.random() * 0.6;\n const lightness = 0.3 + 0.4 * Math.random();\n return new THREE.Color().setHSL(hue, saturation, lightness);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Determines clicked or touched coordinate as offset\n * @param ev An MouseEvent or TouchEvent.\n * @param target HTML element to find coordinates relative to.\n * @returns A struct containing coordinates relative to the HTML element provided.\n */\nexport function clickOrTouchEventOffset(\n ev: MouseEvent | TouchEvent,\n target: HTMLElement\n): { offsetX: number; offsetY: number } {\n const rect = target.getBoundingClientRect();\n\n if (ev instanceof MouseEvent) {\n return {\n offsetX: ev.clientX - rect.left,\n offsetY: ev.clientY - rect.top\n };\n } else if (ev.changedTouches.length > 0) {\n const touch = ev.changedTouches[0];\n return {\n offsetX: touch.clientX - rect.left,\n offsetY: touch.clientY - rect.top\n };\n }\n\n // Invalid event\n return {\n offsetX: -1,\n offsetY: -1\n };\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Subscribable event source.\n */\nexport class EventTrigger<TListener extends (...args: any[]) => void> {\n private readonly _listeners: TListener[] = [];\n\n subscribe(listener: TListener): void {\n this._listeners.push(listener);\n }\n\n unsubscribe(listener: TListener): void {\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n unsubscribeAll(): void {\n this._listeners.splice(0);\n }\n\n fire(...args: Parameters<TListener>): void {\n this._listeners.forEach(listener => listener(...args));\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * See https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#union-exhaustiveness-checking\n */\nexport function assertNever(x: never, message?: string): never {\n throw new Error(message || 'Unexpected object: ' + x);\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nexport class NumericRange {\n readonly from: number;\n readonly count: number;\n readonly toInclusive: number;\n\n constructor(from: number, count: number) {\n if (count < 0) {\n throw new Error('Range cannot have negative number of elements');\n }\n\n this.from = from;\n this.count = count;\n this.toInclusive = from + count - 1;\n }\n\n static createFromInterval(from: number, toInclusive: number): NumericRange {\n return new NumericRange(from, toInclusive - from + 1);\n }\n\n *values(): Generator<number> {\n for (let i = this.from; i <= this.toInclusive; ++i) {\n yield i;\n }\n }\n\n toArray(): number[] {\n return Array.from(this.values());\n }\n\n equal(other: NumericRange): boolean {\n return this.from === other.from && this.count === other.count;\n }\n\n contains(value: number): boolean {\n return value >= this.from && value <= this.toInclusive;\n }\n\n intersects(range: NumericRange): boolean {\n return this.from <= range.toInclusive && this.toInclusive >= range.from;\n }\n\n intersectsOrCoinciding(range: NumericRange): boolean {\n return this.from <= range.toInclusive + 1 && this.toInclusive + 1 >= range.from;\n }\n\n intersectionWith(range: NumericRange): NumericRange | undefined {\n if (!this.intersects(range)) {\n return undefined;\n } else {\n return NumericRange.createFromInterval(\n Math.max(this.from, range.from),\n Math.min(this.toInclusive, range.toInclusive)\n );\n }\n }\n\n isInside(range: NumericRange): boolean {\n return this.from >= range.from && this.toInclusive <= range.toInclusive;\n }\n\n union(range: NumericRange): NumericRange {\n return NumericRange.createFromInterval(\n Math.min(this.from, range.from),\n Math.max(this.toInclusive, range.toInclusive)\n );\n }\n\n forEach(action: (value: number) => void): void {\n for (let i = this.from; i <= this.toInclusive; ++i) {\n action(i);\n }\n }\n\n toString(): string {\n return '(' + this.from + ', ' + this.toInclusive + ')';\n }\n\n static isNumericRange(value: any): value is NumericRange {\n if (!value) return false;\n\n const range = value as NumericRange;\n return range.from !== undefined && range.count !== undefined && range.toInclusive !== undefined;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Computes minimal power-of-two width and height that holds at least the number of elements provided.\n * This is useful to compute texture sizes.\n */\nexport function determinePowerOfTwoDimensions(elementCount: number): { width: number; height: number } {\n const width = Math.max(1, ceilToPowerOfTwo(Math.sqrt(elementCount)));\n const height = Math.max(1, ceilToPowerOfTwo(elementCount / width));\n return { width, height };\n}\n\nconst log2 = Math.log(2);\nfunction ceilToPowerOfTwo(v: number): number {\n return Math.pow(2, Math.ceil(Math.log(v) / log2));\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { IndexNode } from './IndexSet';\nimport { LeafIndexNode } from './LeafIndexNode';\nimport { NumericRange } from '../NumericRange';\nimport assert from 'assert';\n\nexport class IntermediateIndexNode {\n readonly range: NumericRange;\n readonly maxSubtreeDepth: number;\n readonly left: IndexNode;\n readonly right: IndexNode;\n readonly count: number;\n\n constructor(left: IndexNode, right: IndexNode) {\n this.left = left;\n this.right = right;\n\n this.maxSubtreeDepth = Math.max(this.left.maxSubtreeDepth, this.right.maxSubtreeDepth) + 1;\n this.range = NumericRange.createFromInterval(this.left.range.from, this.right.range.toInclusive);\n this.count = this.left.count + this.right.count;\n }\n\n static fromIndexNodesAndBalance(r0: IndexNode, r1: IndexNode): IntermediateIndexNode {\n if (r0.range.from > r1.range.toInclusive + 1) {\n return new IntermediateIndexNode(r1, r0).balance();\n } else if (r0.range.toInclusive + 1 < r1.range.from) {\n return new IntermediateIndexNode(r0, r1).balance();\n } else {\n // Help, overlapping nodes! There is an error somewhere!\n assert(false, 'Internal error in IndexSet: Overlapping nodes');\n }\n }\n\n traverse(visitor: (range: NumericRange) => void): void {\n // Note! The actual ranges are kept in leafs, so we do not visit \"this\"\n this.left.traverse(visitor);\n this.right.traverse(visitor);\n }\n\n contains(index: number): boolean {\n if (!this.range.contains(index)) {\n return false;\n }\n\n return this.left.contains(index) || this.right.contains(index);\n }\n\n addRange(range: NumericRange): IndexNode {\n const canUnionThis = range.intersectsOrCoinciding(this.range);\n\n if (!canUnionThis) {\n // The range is either entirely above or below the range of this node\n if (range.from < this.range.from) {\n const newNode = this.left.addRange(range);\n return IntermediateIndexNode.fromIndexNodesAndBalance(newNode, this.right);\n } else {\n const newNode = this.right.addRange(range);\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left, newNode);\n }\n }\n\n const canUnionLeft = range.intersectsOrCoinciding(this.left.range);\n const canUnionRight = range.intersectsOrCoinciding(this.right.range);\n\n if (canUnionLeft && canUnionRight) {\n // Range intersects both subtrees...\n const [newLeft, leftRange] = this.left.soak(range);\n const [newRight, rightRange] = this.right.soak(range);\n\n const unioned = leftRange.union(rightRange);\n\n if (newLeft === undefined && newRight === undefined) {\n return new LeafIndexNode(unioned);\n } else if (newLeft === undefined && newRight !== undefined) {\n // Last term is added to please compiler\n return newRight.addRange(unioned);\n } else if (newRight === undefined && newLeft !== undefined) {\n // ---\"---\n return newLeft.addRange(unioned);\n }\n\n // We have guaranteed that newLeft and newRight is defined\n const newNode = IntermediateIndexNode.fromIndexNodesAndBalance(newLeft!, newRight!);\n\n return newNode.addRange(unioned);\n } else if (canUnionLeft) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left.addRange(range), this.right);\n } else if (canUnionRight) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left, this.right.addRange(range));\n } else {\n // Range lies between ranges of left and right subtree,\n // add to smallest\n if (this.left.maxSubtreeDepth < this.right.maxSubtreeDepth) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left.addRange(range), this.right);\n } else {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left, this.right.addRange(range));\n }\n }\n }\n\n removeRange(range: NumericRange): IndexNode | undefined {\n // If input range does not intersect with this range, return\n if (!range.intersects(this.range)) {\n return this;\n }\n\n const [newThis, soakedRange] = this.soak(range);\n\n let leftRange: NumericRange | undefined = undefined;\n let rightRange: NumericRange | undefined = undefined;\n\n // If soakedRange extends to either the left or right to the\n // numeric range, we take the ranges extending out and insert anew.\n if (soakedRange.from < range.from) {\n leftRange = NumericRange.createFromInterval(soakedRange.from, range.from - 1);\n }\n\n if (soakedRange.toInclusive > range.toInclusive) {\n rightRange = NumericRange.createFromInterval(range.toInclusive + 1, soakedRange.toInclusive);\n }\n\n if (newThis === undefined) {\n // If all ranges in this was soaked up, create new node with\n // non-empty left and right ranges\n if (leftRange !== undefined && rightRange !== undefined) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(\n new LeafIndexNode(leftRange),\n new LeafIndexNode(rightRange)\n );\n } else if (leftRange != undefined) {\n return new LeafIndexNode(leftRange);\n } else if (rightRange != undefined) {\n return new LeafIndexNode(rightRange);\n } else {\n return undefined;\n }\n } else {\n // Add non-empty left- and right ranges\n let nodeToReturn = newThis;\n\n if (leftRange !== undefined) {\n nodeToReturn = nodeToReturn.addRange(leftRange);\n }\n\n if (rightRange !== undefined) {\n nodeToReturn = nodeToReturn.addRange(rightRange);\n }\n\n return nodeToReturn;\n }\n }\n\n balance(): IntermediateIndexNode {\n const leftSubTreeSize = this.left.maxSubtreeDepth;\n const rightSubTreeSize = this.right.maxSubtreeDepth;\n\n if (rightSubTreeSize + 2 <= leftSubTreeSize) {\n // Left side too deep\n const newLeft = (this.left as IntermediateIndexNode).rotateSmallerRight();\n const newNode = new IntermediateIndexNode(newLeft, this.right).rotateRight().balance();\n return newNode;\n } else if (leftSubTreeSize + 2 <= rightSubTreeSize) {\n // Right side too deep\n const newRight = (this.right as IntermediateIndexNode).rotateSmallerLeft();\n const newNode = new IntermediateIndexNode(this.left, newRight).rotateLeft().balance();\n return newNode;\n }\n\n return this;\n }\n\n clone(): IntermediateIndexNode {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left.clone(), this.right.clone());\n }\n\n hasIntersectionWith(node: IndexNode): boolean {\n if (!node.range.intersects(this.range)) {\n return false;\n }\n\n // Make sure containing range is the \"this\"\n if (this.range.isInside(node.range)) {\n return node.hasIntersectionWith(this);\n }\n\n // Here, we know this range is not contained within node range\n if (this.left.range.intersects(node.range) && this.left.hasIntersectionWith(node)) {\n return true;\n }\n\n if (this.right.range.intersects(node.range) && this.right.hasIntersectionWith(node)) {\n return true;\n }\n\n return false;\n }\n\n /*\n * Utilities\n */\n // Soak up/ delete numeric range touching the input range,\n // returning union of soaked ranges and input range\n // This operation is used as a substep when adding a range - the range\n // is first used to \"soak\" up all touching ranges in the tree, since these must be part of a\n // common union range at the end of the insertion. In the end, the range, unioned with\n // all its soaked ranges in the tree, is inserted normally.\n soak(range: NumericRange): [IndexNode | undefined, NumericRange] {\n let [leftRes, leftRange]: [IndexNode | undefined, NumericRange] = [this.left, range];\n let [rightRes, rightRange]: [IndexNode | undefined, NumericRange] = [this.right, range];\n\n // Both subtrees are inside range, soak up everything\n if (this.right.range.isInside(range) && this.left.range.isInside(range)) {\n return [undefined, range];\n }\n\n // Compute what's left on the left, and the soaked-up range\n if (this.left.range.intersectsOrCoinciding(range)) {\n [leftRes, leftRange] = this.left.soak(range);\n }\n\n // Compute what's left on the right, and the soaked-up range\n if (this.right.range.intersectsOrCoinciding(range)) {\n [rightRes, rightRange] = this.right.soak(range);\n }\n\n // The two soaked-up ranges must touch (they both contain the argument range)\n const unionRange = leftRange.union(rightRange);\n\n if (rightRes == undefined) {\n return [leftRes, unionRange];\n } else if (leftRes == undefined) {\n return [rightRes, unionRange];\n } else {\n const newNode = IntermediateIndexNode.fromIndexNodesAndBalance(leftRes, rightRes);\n return [newNode, unionRange];\n }\n }\n\n /*\n * Rotations\n */\n rotateRight(): IntermediateIndexNode {\n if (!('right' in this.left)) {\n // Left node is leaf node. Abort rotation\n return this;\n }\n\n return new IntermediateIndexNode(\n (this.left as IntermediateIndexNode).left,\n new IntermediateIndexNode((this.left as IntermediateIndexNode).right, this.right)\n );\n }\n\n rotateLeft(): IntermediateIndexNode {\n if (!('left' in this.right)) {\n // Left node is leaf node. Abort rotation\n return this;\n }\n\n return new IntermediateIndexNode(\n new IntermediateIndexNode(this.left, (this.right as IntermediateIndexNode).left),\n (this.right as IntermediateIndexNode).right\n );\n }\n\n // Rotate so that smaller subtree is on left\n rotateSmallerLeft(): IntermediateIndexNode {\n if (this.left.maxSubtreeDepth > this.right.maxSubtreeDepth) {\n // If left subtree depth is larger, it must be of type IntermediateIndexNode\n let nextRoot = this.rotateRight() as IntermediateIndexNode;\n nextRoot = nextRoot.rotateSmallerLeft();\n return nextRoot;\n }\n\n return this;\n }\n\n // Rotate so that smaller subtree is on right\n rotateSmallerRight(): IntermediateIndexNode {\n if (this.right.maxSubtreeDepth > this.left.maxSubtreeDepth) {\n // If left subtree depth is larger, it must be of type IntermediateIndexNode\n let nextRoot = this.rotateLeft() as IntermediateIndexNode;\n nextRoot = nextRoot.rotateSmallerRight();\n return nextRoot;\n }\n\n return this;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS../NumericRange\n */\nimport { IntermediateIndexNode } from './IntermediateIndexNode';\nimport { IndexNode } from './IndexSet';\nimport { NumericRange } from '../NumericRange';\n\nexport class LeafIndexNode {\n readonly range: NumericRange;\n readonly count: number;\n readonly maxSubtreeDepth: number;\n\n static fromInterval(begin: number, endInclusive: number): LeafIndexNode {\n return new LeafIndexNode(NumericRange.createFromInterval(begin, endInclusive));\n }\n\n constructor(range: NumericRange) {\n this.range = range;\n this.maxSubtreeDepth = 0;\n this.count = range.count;\n }\n\n traverse(visitor: (range: NumericRange) => void): void {\n visitor(this.range);\n }\n\n contains(index: number): boolean {\n return this.range.contains(index);\n }\n\n addRange(range: NumericRange): IndexNode {\n if (this.range.intersectsOrCoinciding(range)) {\n // Create union range\n return new LeafIndexNode(this.range.union(range));\n }\n\n return IntermediateIndexNode.fromIndexNodesAndBalance(this, new LeafIndexNode(range));\n }\n\n removeRange(range: NumericRange): IndexNode | undefined {\n if (!range.intersects(this.range)) {\n return this;\n }\n\n if (this.range.isInside(range)) {\n return undefined;\n }\n\n let leftRange: NumericRange | undefined = undefined;\n let rightRange: NumericRange | undefined = undefined;\n\n if (this.range.from < range.from) {\n leftRange = NumericRange.createFromInterval(this.range.from, range.from - 1);\n }\n\n if (this.range.toInclusive > range.toInclusive) {\n rightRange = NumericRange.createFromInterval(range.toInclusive + 1, this.range.toInclusive);\n }\n\n if (leftRange != undefined && rightRange != undefined) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(\n new LeafIndexNode(leftRange),\n new LeafIndexNode(rightRange)\n );\n } else if (leftRange != undefined) {\n return new LeafIndexNode(leftRange);\n } else if (rightRange != undefined) {\n return new LeafIndexNode(rightRange);\n } else {\n return undefined;\n }\n }\n\n hasIntersectionWith(node: IndexNode): boolean {\n return node.range.intersects(this.range);\n }\n\n soak(range: NumericRange): [IndexNode | undefined, NumericRange] {\n if (this.range.intersectsOrCoinciding(range)) {\n return [undefined, this.range.union(range)];\n } else {\n return [this, range];\n }\n }\n\n clone(): LeafIndexNode {\n return new LeafIndexNode(this.range);\n }\n}\n","/*\n * Copyright 2021 Cognite AS\n */\nimport { IntermediateIndexNode } from './IntermediateIndexNode';\nimport { LeafIndexNode } from './LeafIndexNode';\nimport { NumericRange } from '../NumericRange';\n\nexport type IndexNode = IntermediateIndexNode | LeafIndexNode;\n\nexport class IndexSet {\n rootNode?: IndexNode;\n\n constructor(values?: Iterable<number>);\n constructor(values?: NumericRange);\n constructor(values?: Iterable<number> | NumericRange) {\n if (values == undefined) {\n this.rootNode = undefined;\n } else if (NumericRange.isNumericRange(values)) {\n this.addRange(values);\n } else {\n for (const index of values) {\n this.add(index);\n }\n }\n }\n\n forEachRange(visitor: (range: NumericRange) => void): void {\n if (this.rootNode) {\n this.rootNode.traverse(visitor);\n }\n }\n\n add(index: number): void {\n const range = new NumericRange(index, 1);\n\n this.addRange(range);\n }\n\n addRange(range: NumericRange): void {\n if (this.rootNode) {\n this.rootNode = this.rootNode.addRange(range);\n } else {\n this.rootNode = new LeafIndexNode(range);\n }\n }\n\n remove(index: number): void {\n const range = new NumericRange(index, 1);\n this.removeRange(range);\n }\n\n removeRange(range: NumericRange): void {\n if (this.rootNode) {\n this.rootNode = this.rootNode.removeRange(range);\n }\n\n // Do nothing if root is empty\n }\n\n contains(index: number): boolean {\n if (this.rootNode) {\n return this.rootNode.contains(index);\n }\n\n return false;\n }\n\n get count(): number {\n if (this.rootNode) {\n return this.rootNode.count;\n }\n\n return 0;\n }\n\n toRangeArray(): NumericRange[] {\n const ranges: NumericRange[] = [];\n this.forEachRange(range => {\n ranges.push(range);\n });\n return ranges;\n }\n\n toIndexArray(): number[] {\n const result: number[] = [];\n\n if (this.rootNode) {\n this.forEachRange(range => {\n range.forEach(num => {\n result.push(num);\n });\n });\n }\n\n return result;\n }\n\n toPlainSet(): Set<number> {\n const arr: number[] = this.toIndexArray();\n const st = new Set(arr);\n return st;\n }\n\n // NB: Assumes that this.ranges() are in order from left to right\n invertedRanges(): NumericRange[] {\n const originalRanges = this.toRangeArray();\n\n const newRanges: NumericRange[] = [];\n\n for (let i = 0; i < originalRanges.length - 1; i++) {\n if (originalRanges[i].toInclusive + 1 >= originalRanges[i + 1].from) {\n // Should not happen, but let's be safe\n continue;\n }\n newRanges.push(\n NumericRange.createFromInterval(originalRanges[i].toInclusive + 1, originalRanges[i + 1].from - 1)\n );\n }\n\n return newRanges;\n }\n\n unionWith(otherSet: IndexSet): IndexSet {\n if (this.rootNode) {\n otherSet.forEachRange(range => {\n this.rootNode = this.rootNode!.addRange(range);\n });\n } else {\n this.rootNode = otherSet.rootNode;\n }\n\n return this;\n }\n\n differenceWith(otherSet: IndexSet): IndexSet {\n if (this.rootNode) {\n otherSet.forEachRange(range => {\n this.rootNode = this.rootNode?.removeRange(range);\n });\n }\n\n return this;\n }\n\n hasIntersectionWith(otherSet: IndexSet | Set<number>): boolean {\n if (otherSet instanceof IndexSet) {\n if (this.rootNode === undefined || otherSet.rootNode === undefined) {\n return false;\n }\n\n return this.rootNode.hasIntersectionWith(otherSet.rootNode);\n } else {\n for (const index of otherSet) {\n if (this.contains(index)) {\n return true;\n }\n }\n\n return false;\n }\n }\n\n intersectWith(otherSet: IndexSet): IndexSet {\n if (this.rootNode && otherSet.rootNode) {\n // Tackle endpoints\n // Remove left bounds outside input set\n if (this.rootNode.range.from < otherSet.rootNode.range.from) {\n const leftBoundRange = NumericRange.createFromInterval(\n this.rootNode.range.from,\n otherSet.rootNode.range.from - 1\n );\n this.rootNode = this.rootNode.removeRange(leftBoundRange);\n\n if (!this.rootNode) {\n return this;\n }\n }\n\n // Remove right bounds outside input set\n if (this.rootNode.range.toInclusive > otherSet.rootNode.range.toInclusive) {\n const rightBoundRange = NumericRange.createFromInterval(\n otherSet.rootNode.range.toInclusive + 1,\n this.rootNode.range.toInclusive\n );\n this.rootNode = this.rootNode.removeRange(rightBoundRange);\n }\n\n // Invert otherSet ranges and remove them\n const invRanges = otherSet.invertedRanges();\n\n invRanges.forEach(range => {\n if (this.rootNode) {\n this.rootNode = this.rootNode.removeRange(range);\n }\n });\n } else if (this.rootNode) {\n // Otherset is empty, set this to empty as well\n this.rootNode = undefined;\n }\n return this;\n }\n\n clear(): void {\n this.rootNode = undefined;\n }\n\n clone(): IndexSet {\n const st: IndexSet = new IndexSet();\n\n if (this.rootNode) {\n st.rootNode = this.rootNode.clone();\n }\n\n return st;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n// https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float @ Arjan\n\nexport function packFloat(f: number): [number, number, number, number] {\n const F = abs(f);\n if (F == 0) {\n return [0, 0, 0, 0];\n }\n const Sign = step(0.0, -f);\n let Exponent = floor(log2(F));\n\n const Mantissa = F / exp2(Exponent);\n\n if (Mantissa < 1) Exponent -= 1;\n\n Exponent += 127;\n\n const rgba: [number, number, number, number] = [\n 128.0 * Sign + floor(Exponent * exp2(-1.0)),\n 128.0 * mod(Exponent, 2.0) + mod(floor(Mantissa * 128.0), 128.0),\n floor(mod(floor(Mantissa * exp2(23.0 - 8.0)), exp2(8.0))),\n floor(exp2(23.0) * mod(Mantissa, exp2(-15.0)))\n ];\n return rgba;\n}\n\nexport function packFloatInto(f: number, targetBuffer: Uint8ClampedArray, offset: number): void {\n const F = abs(f);\n if (F == 0) {\n return;\n }\n const Sign = step(0.0, -f);\n let Exponent = floor(log2(F));\n\n const Mantissa = F / exp2(Exponent);\n\n if (Mantissa < 1) Exponent -= 1;\n\n Exponent += 127;\n\n targetBuffer[offset] = 128.0 * Sign + floor(Exponent * exp2(-1.0));\n targetBuffer[offset + 1] = 128.0 * mod(Exponent, 2.0) + mod(floor(Mantissa * 128.0), 128.0);\n targetBuffer[offset + 2] = floor(mod(floor(Mantissa * exp2(23.0 - 8.0)), exp2(8.0)));\n targetBuffer[offset + 3] = floor(exp2(23.0) * mod(Mantissa, exp2(-15.0)));\n}\n\nexport function unpackFloat4(packedFloat: [number, number, number, number]): number {\n const [r, g, b, a] = packedFloat;\n const sign = 1.0 - step(128.0, r) * 2.0;\n const exponent = 2.0 * mod(r, 128.0) + step(128.0, g) - 127.0;\n if (exponent == -127) return 0;\n const mantissa = mod(g, 128.0) * 65536.0 + b * 256.0 + a + 8388608.0;\n return sign * exp2(exponent - 23.0) * mantissa;\n}\n\nfunction step(edge: number, x: number): number {\n return x < edge ? 0.0 : 1.0;\n}\n\nfunction exp2(x: number) {\n return Math.pow(2, x);\n}\n\nfunction mod(x: number, y: number) {\n return x - y * floor(x / y);\n}\n\nfunction floor(x: number) {\n return Math.floor(x);\n}\n\nfunction log2(x: number) {\n return Math.log(x) / Math.log(2);\n}\n\nfunction abs(x: number) {\n return Math.abs(x);\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { TypedArray } from '../types';\n\ntype Batch = {\n from: number;\n count: number;\n prev: Batch | undefined;\n next: Batch | undefined;\n};\n\nexport class DynamicDefragmentedBuffer<T extends TypedArray> {\n public get length(): number {\n return this._numFilled;\n }\n\n public get buffer(): T {\n return this._buffer;\n }\n\n private _buffer: T;\n private _numFilled: number;\n private readonly _type: new (length: number) => T;\n\n private readonly _batchMap: Map<number, Batch>;\n private _currentTail: Batch | undefined;\n\n private _batchIdCounter: number;\n\n constructor(initialSize: number, type: new (length: number) => T) {\n this._numFilled = 0;\n this._batchIdCounter = 0;\n this._batchMap = new Map<number, Batch>();\n\n this._type = type;\n\n const minimalPowerOfTwo = Math.pow(2, Math.ceil(Math.log2(initialSize)));\n this._buffer = new type(minimalPowerOfTwo);\n }\n\n public add(array: T): { batchId: number; bufferIsReallocated: boolean } {\n let isReallocated = false;\n if (this._numFilled + array.length > this._buffer.length) {\n const newSize = Math.pow(2, Math.ceil(Math.log2(this._numFilled + array.length)));\n this.allocateNewBuffer(newSize);\n isReallocated = true;\n }\n\n this._buffer.set(array, this._numFilled);\n\n const batchId = this.createBatch(array);\n\n this._numFilled += array.length;\n\n return { batchId: batchId, bufferIsReallocated: isReallocated };\n }\n\n public remove(batchId: number): void {\n const batch = this._batchMap.get(batchId);\n\n if (!batch) {\n throw new Error('batch does not exist in buffer');\n }\n\n this._buffer.copyWithin(batch.from, batch.from + batch.count, this.buffer.length);\n\n this._numFilled -= batch.count;\n\n if (this._currentTail === batch) {\n this._currentTail = batch.prev;\n }\n\n const prev = batch.prev;\n const next = batch.next;\n\n if (prev) {\n prev.next = next;\n }\n\n if (next) {\n next.prev = prev;\n }\n\n let currentBatch = next;\n\n while (currentBatch) {\n currentBatch.from -= batch.count;\n currentBatch = currentBatch.next;\n }\n\n this._batchMap.delete(batchId);\n }\n\n private createBatch(array: T) {\n const batch: Batch = {\n from: this._numFilled,\n count: array.length,\n prev: this._currentTail,\n next: undefined\n };\n\n if (this._currentTail) {\n this._currentTail.next = batch;\n }\n\n this._currentTail = batch;\n\n const batchId = this._batchIdCounter;\n this._batchIdCounter++;\n\n this._batchMap.set(batchId, batch);\n return batchId;\n }\n\n private allocateNewBuffer(newSize: number): void {\n const newBuffer = new this._type(newSize);\n newBuffer.set(this._buffer);\n\n this._buffer = newBuffer;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nconst emptyGeometry = new THREE.BufferGeometry();\n\n/**\n * Referenced count implementation of THREE.Group that\n * automatically disposes all geometries contained in meshes that\n * are direct children of the group.\n */\nexport class AutoDisposeGroup extends THREE.Group {\n private _isDisposed = false;\n private _referenceCount = 0;\n\n reference(): void {\n this.ensureNotDisposed();\n this._referenceCount++;\n }\n\n dereference(): void {\n this.ensureNotDisposed();\n if (this._referenceCount === 0) {\n throw new Error('No references');\n }\n if (--this._referenceCount === 0) {\n this.dispose();\n }\n }\n\n private dispose(): void {\n this.ensureNotDisposed();\n this._isDisposed = true;\n const meshes: THREE.Mesh[] = this.children.filter(x => x instanceof THREE.Mesh).map(x => x as THREE.Mesh);\n for (const mesh of meshes) {\n if (mesh.geometry !== undefined) {\n mesh.geometry.dispose();\n // // NOTE: Forcefully creating a new reference here to make sure\n // // there are no lingering references to the large geometry buffer\n mesh.geometry = emptyGeometry;\n }\n }\n }\n\n private ensureNotDisposed() {\n if (this._isDisposed) {\n throw new Error('Already disposed/dereferenced');\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\n// For BoundingBoxLOD.update()\nconst updateVars = {\n camPos: new THREE.Vector3(),\n bounds: new THREE.Box3()\n};\n\n/**\n * Class similar to THREE.LOD except that it doesn't use `matrixWorld` to determine distance to camera, but a\n * bounding box.\n */\nexport class BoundingBoxLOD extends THREE.Object3D {\n private readonly _boundingBox: THREE.Box3;\n private _activeLevel = 0;\n private readonly _levels: { distance: number; object: THREE.Object3D }[] = [];\n\n // Note! isLOD and autoUpdate is used by WebGLRenderer to perform automatic update of LOD\n // level before rendering\n public readonly isLOD = true;\n public readonly autoUpdate = true;\n\n constructor(boundingBox: THREE.Box3) {\n super();\n this._boundingBox = boundingBox.clone();\n this.type = 'BoundingBoxLOD';\n }\n\n setBoundingBox(boundingBox: THREE.Box3): void {\n this._boundingBox.copy(boundingBox);\n }\n\n addLevel(object: THREE.Object3D, distance: number = 0): void {\n this._levels.push({ object, distance: Math.abs(distance) });\n this._levels.sort((a, b) => b.distance - a.distance);\n object.visible = false;\n this.add(object);\n }\n\n /**\n * Returns the index of the current active LOD. 0 means highest detail.\n */\n getCurrentLevel(): number {\n return this._levels.length > 0 ? this._levels.length - this._activeLevel - 1 : 0;\n }\n\n /**\n * Update selected LOD level based on distance to camera.\n */\n update(camera: THREE.Camera): void {\n this.updateCurrentLevel(camera);\n }\n\n private updateCurrentLevel(camera: THREE.Camera) {\n const levels = this._levels;\n const { camPos, bounds } = updateVars;\n bounds.copy(this._boundingBox).applyMatrix4(this.matrixWorld);\n const cameraZoom = camera instanceof THREE.PerspectiveCamera ? camera.zoom : 1.0;\n\n if (levels.length > 0) {\n camPos.setFromMatrixPosition(camera.matrixWorld);\n const distanceToCamera = bounds.distanceToPoint(camPos) / cameraZoom;\n\n levels[this._activeLevel].object.visible = false;\n this._activeLevel = levels.findIndex(p => distanceToCamera >= p.distance);\n this._activeLevel = this._activeLevel >= 0 ? this._activeLevel : levels.length - 1;\n levels[this._activeLevel].object.visible = true;\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\nexport function getBox3CornerPoints(box: THREE.Box3): THREE.Vector3[] {\n return [\n new THREE.Vector3(box.min.x, box.min.y, box.min.z), // 000\n new THREE.Vector3(box.min.x, box.min.y, box.max.z), // 001\n new THREE.Vector3(box.min.x, box.max.y, box.min.z), // 010\n new THREE.Vector3(box.min.x, box.max.y, box.max.z), // 011\n new THREE.Vector3(box.max.x, box.min.y, box.min.z), // 100\n new THREE.Vector3(box.max.x, box.min.y, box.max.z), // 101\n new THREE.Vector3(box.max.x, box.max.y, box.min.z), // 110\n new THREE.Vector3(box.max.x, box.max.y, box.max.z) // 111\n ];\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nexport function isMobileOrTablet(): boolean {\n // https://stackoverflow.com/a/11381730/167251\n let check = false;\n (a => {\n if (\n /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(\n a\n ) ||\n /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(\n a.substr(0, 4)\n )\n ) {\n check = true;\n }\n })(navigator.userAgent || navigator.vendor || (window as any).opera);\n return check;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\ntype WebGLRendererState = {\n autoClear?: boolean;\n clearColor?: THREE.Color | string | number;\n clearAlpha?: number;\n size?: THREE.Vector2;\n localClippingEnabled?: boolean;\n renderTarget?: THREE.RenderTarget | null;\n};\n\nexport class WebGLRendererStateHelper {\n private _originalState: WebGLRendererState = {};\n private readonly _renderer: THREE.WebGLRenderer;\n\n constructor(renderer: THREE.WebGLRenderer) {\n this._renderer = renderer;\n this._originalState = {};\n }\n\n setClearColor(color: THREE.Color | number | string, alpha?: number): void {\n this._originalState = {\n clearColor: this._renderer.getClearColor(new THREE.Color()),\n clearAlpha: this._renderer.getClearAlpha(),\n ...this._originalState\n };\n this._renderer.setClearColor(color, alpha);\n }\n\n setSize(width: number, height: number): void {\n this._originalState = { size: this._renderer.getSize(new THREE.Vector2()), ...this._originalState };\n this._renderer.setSize(width, height);\n }\n\n set localClippingEnabled(enabled: boolean) {\n this._originalState = { localClippingEnabled: this._renderer.localClippingEnabled, ...this._originalState };\n this._renderer.localClippingEnabled = enabled;\n }\n\n set autoClear(enabled: boolean) {\n this._originalState = { autoClear: this._renderer.autoClear, ...this._originalState };\n this._renderer.autoClear = enabled;\n }\n\n setRenderTarget(renderTarget: THREE.RenderTarget | null): void {\n this._originalState = { renderTarget: this._renderer.getRenderTarget(), ...this._originalState };\n this._renderer.setRenderTarget(renderTarget);\n }\n\n resetState(): void {\n if (this._originalState.autoClear !== undefined) {\n this._renderer.autoClear = this._originalState.autoClear;\n }\n if (this._originalState.clearColor !== undefined) {\n this._renderer.setClearColor(this._originalState.clearColor, this._originalState.clearAlpha);\n }\n if (this._originalState.localClippingEnabled !== undefined) {\n this._renderer.localClippingEnabled = this._originalState.localClippingEnabled;\n }\n if (this._originalState.size !== undefined) {\n this._renderer.setSize(this._originalState.size.width, this._originalState.size.height);\n }\n if (this._originalState.renderTarget !== undefined) {\n this._renderer.setRenderTarget(this._originalState.renderTarget);\n }\n\n this._originalState = {};\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Used to specify custom url for worker/wasm files\n * in cases when you need the latest local files or CDN is blocked by CSP.\n */\nexport const revealEnv = {\n publicPath: ''\n};\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { wrap } from 'comlink';\nimport { RevealParserWorker } from '@cognite/reveal-parser-worker';\nimport { revealEnv } from '../revealEnv';\nimport { isTheSameDomain } from '../networking/isTheSameDomain';\n\nimport log from '@reveal/logger';\n\ntype WorkDelegate<T> = (worker: RevealParserWorker) => Promise<T>;\n\ninterface PooledWorker {\n // The worker returned by Comlink.wrap is not strictly speaking a RevealParserWorker,\n // but it should expose the same functions\n worker: RevealParserWorker;\n activeJobCount: number;\n messageIdCounter: number;\n}\n\nexport class WorkerPool {\n static get defaultPool(): WorkerPool {\n WorkerPool._defaultPool = WorkerPool._defaultPool || new WorkerPool();\n return WorkerPool._defaultPool;\n }\n\n private static _defaultPool: WorkerPool | undefined;\n\n private readonly workerList: PooledWorker[] = [];\n\n private workerObjUrl?: string;\n\n constructor() {\n const numberOfWorkers = this.determineNumberOfWorkers();\n\n for (let i = 0; i < numberOfWorkers; i++) {\n const newWorker = {\n // NOTE: As of Comlink 4.2.0 we need to go through unknown before RevealParserWorker\n // Please feel free to remove `as unknown` if possible.\n worker: wrap(this.createWorker()) as unknown as RevealParserWorker,\n activeJobCount: 0,\n messageIdCounter: 0\n };\n this.workerList.push(newWorker);\n }\n\n if (process.env.NODE_ENV !== 'test') {\n checkWorkerVersion(this.workerList[0].worker).catch(x => log.error(x));\n }\n\n if (this.workerObjUrl) {\n URL.revokeObjectURL(this.workerObjUrl);\n }\n }\n\n // Used to construct workers with or without importScripts usage to overcome CORS.\n // When publicPath is not set we need to fetch worker from CDN (perform cross-origin request)\n // and that's possible only with importScripts.\n // If publicPath is set and points on the same domain, we use it normally.\n private createWorker() {\n const workerUrl = (revealEnv.publicPath || __webpack_public_path__) + 'reveal.parser.worker.js';\n const options = { name: `reveal.parser #${this.workerList.length}` };\n\n if (isTheSameDomain(workerUrl)) {\n return new Worker(workerUrl, options);\n }\n\n if (!this.workerObjUrl) {\n const blob = new Blob([`importScripts(${JSON.stringify(workerUrl)});`], {\n type: 'text/javascript'\n });\n this.workerObjUrl = URL.createObjectURL(blob);\n }\n\n return new Worker(this.workerObjUrl, options);\n }\n\n async postWorkToAvailable<T>(work: WorkDelegate<T>): Promise<T> {\n const targetWorker = this.workerList.reduce((bestWorker, candidate) => {\n if (bestWorker.activeJobCount > candidate.activeJobCount) {\n return candidate;\n }\n return bestWorker;\n }, this.workerList[0]);\n\n targetWorker.activeJobCount += 1;\n const result = await (async () => {\n try {\n return await work(targetWorker.worker);\n } finally {\n targetWorker.activeJobCount -= 1;\n }\n })();\n\n return result;\n }\n\n // TODO j-bjorne 16-04-2020: Send in constructor instead\n private determineNumberOfWorkers() {\n // Use between 2-4 workers, depending on hardware\n return Math.max(2, Math.min(4, window.navigator.hardwareConcurrency || 2));\n }\n}\n\nexport async function checkWorkerVersion(worker: RevealParserWorker): Promise<void> {\n let actualWorkerVersion: string;\n try {\n actualWorkerVersion = await worker.getVersion();\n } catch (e) {\n // versions below 1.1.1 do not have getVersion method\n // notice also you cannot use 'in' operator on worker object\n // because it's merely a proxy-wrapper over postmessage('methodname')\n // so `'getVersion' in worker` - will be always false\n actualWorkerVersion = '1.1.0';\n }\n const minWorkerVersion = process.env.WORKER_VERSION;\n\n const [majorMin, minorMin, patchMin] = minWorkerVersion.split('.').map(i => parseInt(i, 10));\n const [majorWorker, minorWorker, patchWorker] = actualWorkerVersion.split('.').map(i => parseInt(i, 10));\n\n const errorMessage = `Update your local copy of @cognite/reveal-parser-worker. Required version is ${minWorkerVersion}. Received ${actualWorkerVersion}.`;\n\n if (majorMin !== majorWorker) {\n throw new Error(errorMessage);\n }\n if (minorWorker < minorMin) {\n throw new Error(errorMessage);\n }\n if (minorWorker === minorMin && patchWorker < patchMin) {\n throw new Error(errorMessage);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Use to determine if the strings that represent urls\n * are pointing on different domains.\n * @param url1\n * @param url2 Optional. Default is `location.origin`. If provided then it must be\n * absolute url to avoid comparison between two relative urls.\n */\nexport function isTheSameDomain(url1: string, url2: string = location.origin): boolean {\n const isRelative = (url: string) => {\n if (url.match(/^.*\\/\\//)) {\n return false; // starts with protocol - means absolute url, e.g. https://foo.bar/baz\n }\n return true;\n };\n\n if (isRelative(url2)) {\n throw new Error(`isTheSameDomain: the second argument must be an absolute url or omitted. Received ${url2}`);\n }\n\n if (isRelative(url1)) {\n return true;\n }\n\n try {\n // url that starts with '//' considered invalid for URL constructor\n // but browsers usually work just fine with them when it comes to links\n // and we just need to compare origins here anyway\n const urls = [url1, url2].map(url => (url.startsWith('//') ? 'https:' + url : url));\n\n const constructedURLs = urls.map(url => new URL(url));\n return constructedURLs[0].host === constructedURLs[1].host;\n } catch (e) {\n console.error(`can not create URLs for ${url1} and ${url2}`, e);\n return false;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { RequestCache } from './RequestCache';\n\nclass TimestampedContainer<T> {\n private _lastAccessTime: number;\n private readonly _value: T;\n\n constructor(value: T) {\n this._value = value;\n this._lastAccessTime = Date.now();\n }\n\n get value() {\n this.touch();\n return this._value;\n }\n\n get lastAccessTime() {\n return this._lastAccessTime;\n }\n\n private touch() {\n this._lastAccessTime = Date.now();\n }\n}\n\nexport interface MemoryRequestCacheOptions {\n maxElementsInCache?: number;\n}\n\nexport class MemoryRequestCache<Key, Data> implements RequestCache<Key, Data> {\n private readonly _maxElementsInCache: number;\n private readonly _data: Map<Key, TimestampedContainer<Data>>;\n private readonly _defaultCleanupCount: number;\n private readonly _removeCallback: ((value: Data) => void) | undefined;\n\n constructor(\n maxElementsInCache: number = 50,\n removeCallback?: (value: Data) => void,\n defaultCleanupCount: number = 10\n ) {\n this._data = new Map();\n this._maxElementsInCache = maxElementsInCache;\n this._defaultCleanupCount = defaultCleanupCount;\n this._removeCallback = removeCallback;\n }\n\n has(id: Key): boolean {\n return this._data.has(id);\n }\n\n forceInsert(id: Key, data: Data): void {\n if (this.isFull()) {\n this.cleanCache(this._defaultCleanupCount);\n }\n this.insert(id, data);\n }\n\n insert(id: Key, data: Data): void {\n if (this._data.size < this._maxElementsInCache) {\n this._data.set(id, new TimestampedContainer(data));\n } else {\n throw new Error('Cache full, please clean Cache and retry adding data');\n }\n }\n\n remove(id: Key): void {\n if (this._removeCallback !== undefined) {\n const value = this._data.get(id);\n if (value !== undefined) {\n this._removeCallback(value.value);\n }\n }\n this._data.delete(id);\n }\n\n get(id: Key): Data {\n const data = this._data.get(id);\n if (data !== undefined) {\n // Don't really like the touch for lastTime being hidden within a get function. Should we maybe make a\n // TimeConstrainedCache interface where the geter is called something like getAndUpdateTimestamp for clarity?\n return data.value;\n }\n throw new Error(`Cache element ${id} does not exist`);\n }\n\n isFull(): boolean {\n return !(this._data.size < this._maxElementsInCache);\n }\n\n cleanCache(count: number): void {\n const allResults = Array.from(this._data.entries());\n allResults.sort((left, right) => {\n return right[1].lastAccessTime - left[1].lastAccessTime;\n });\n for (let i = 0; i < count; i++) {\n const entry = allResults.pop();\n if (entry !== undefined) {\n this.remove(entry[0]);\n } else {\n return;\n }\n }\n }\n\n clear(): void {\n if (this._removeCallback !== undefined) {\n for (const value of this._data.values()) {\n this._removeCallback(value.value);\n }\n }\n this._data.clear();\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n/**\n * A cache that keeps values that is most frequently used (MFU) rather than a more common\n * least recently used (LRU) approach.\n */\nexport class MostFrequentlyUsedCache<TKey, TValue> {\n private readonly _capacity: number;\n private readonly _cache = new Map<TKey, TValue>();\n private readonly _retrieves = new Map<TKey, number>();\n private readonly _disposeCallback: ((value: TValue) => void) | undefined;\n\n constructor(capacity: number, disposeCallback?: (value: TValue) => void) {\n this._capacity = capacity;\n this._disposeCallback = disposeCallback;\n }\n\n get(key: TKey): TValue | undefined {\n const retrieveCount = this._retrieves.get(key) || 0;\n this._retrieves.set(key, retrieveCount + 1);\n return this._cache.get(key);\n }\n\n set(key: TKey, value: TValue): boolean {\n if (this._cache.has(key) || this._capacity < this._cache.size) {\n this._cache.set(key, value);\n return true;\n } else {\n // TODO 2020-12-05 larsmoa: Very inefficient way to set value.\n // We often set a value and discard it a moment later because its not\n // imporant. Fix this.\n this._cache.set(key, value);\n this.ensureWithinCapacity();\n return this._cache.has(key);\n }\n }\n\n remove(key: TKey): boolean {\n this._retrieves.delete(key);\n const value = this._cache.get(key);\n if (value !== undefined) {\n if (this._disposeCallback !== undefined) {\n this._disposeCallback(value);\n }\n this._cache.delete(key);\n return true;\n }\n return false;\n }\n\n clear(): void {\n if (this._disposeCallback !== undefined) {\n for (const value of this._cache.values()) {\n this._disposeCallback(value);\n }\n }\n this._retrieves.clear();\n this._cache.clear();\n }\n\n private ensureWithinCapacity(): void {\n if (this._capacity >= this._cache.size) return;\n const keys = Array.from(this._cache.keys());\n // Figure out what to remove\n const keysForRemoval = keys\n .map(x => ({ key: x, retrivalCount: this._retrieves.get(x) || 0 }))\n .sort((a, b) => a.retrivalCount - b.retrivalCount)\n .slice(0, this._cache.size - this._capacity)\n .map(x => x.key);\n\n for (const key of keysForRemoval) {\n this.remove(key);\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Handler for THREE.BufferAttribute.onUpload() that frees the underlying JS side array\n * of values after they have been uploaded to the GPU.\n *\n * @example\n * const geometry = new THREE.BufferGeometry();\n * const indices = new THREE.Uint32BufferAttribute(mesh.indices.buffer, 1).onUpload(disposeAttributeArrayOnUpload);\n * const vertices = new THREE.Float32BufferAttribute(mesh.vertices.buffer, 3).onUpload(disposeAttributeArrayOnUpload);\n * const colors = new THREE.Float32BufferAttribute(mesh.colors.buffer, 3).onUpload(disposeAttributeArrayOnUpload);\n * const treeIndices = new THREE.Float32BufferAttribute(mesh.treeIndices.buffer, 1).onUpload(disposeAttributeArrayOnUpload);\n */\nexport function disposeAttributeArrayOnUpload(this: { array: ArrayLike<number> }): void {\n (this.array as ArrayLike<number> | null) = null;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { traverseDepthFirst } from '@reveal/utilities';\nimport { SectorScene } from './types';\nimport { SectorMetadata } from '../metadata/types';\nimport skmeans from 'skmeans';\n\nexport class SectorSceneImpl implements SectorScene {\n readonly version: number;\n readonly maxTreeIndex: number;\n readonly root: SectorMetadata;\n readonly unit: string;\n private readonly sectors: Map<number, SectorMetadata>;\n\n constructor(\n version: number,\n maxTreeIndex: number,\n unit: string,\n root: SectorMetadata,\n sectorsById: Map<number, SectorMetadata>\n ) {\n this.version = version;\n this.maxTreeIndex = maxTreeIndex;\n this.root = root;\n this.sectors = sectorsById;\n this.unit = unit;\n }\n\n get sectorCount(): number {\n return this.sectors.size;\n }\n\n getSectorById(sectorId: number): SectorMetadata | undefined {\n return this.sectors.get(sectorId);\n }\n\n getAllSectors(): SectorMetadata[] {\n return [...this.sectors.values()];\n }\n\n getSectorsContainingPoint(p: THREE.Vector3): SectorMetadata[] {\n const accepted: SectorMetadata[] = [];\n traverseDepthFirst(this.root, x => {\n if (x.bounds.containsPoint(p)) {\n accepted.push(x);\n return true;\n }\n return false;\n });\n return accepted;\n }\n\n getSectorsIntersectingBox(b: THREE.Box3): SectorMetadata[] {\n const accepted: SectorMetadata[] = [];\n traverseDepthFirst(this.root, x => {\n if (x.bounds.intersectsBox(b)) {\n accepted.push(x);\n return true;\n }\n return false;\n });\n return accepted;\n }\n\n getBoundsOfMostGeometry(): THREE.Box3 {\n if (this.root.children.length === 0) {\n return this.root.bounds;\n }\n\n // Determine all corners of the bboxes\n const allBounds: THREE.Box3[] = [];\n const corners: number[][] = [];\n traverseDepthFirst(this.root, x => {\n if (x.children.length === 0) {\n corners.push(x.bounds.min.toArray(), x.bounds.max.toArray());\n allBounds.push(x.bounds, x.bounds);\n }\n return true;\n });\n // Cluster the corners into four groups and determine bounds of each cluster\n const numClusters = Math.min(corners.length, 4);\n const clusters = skmeans(corners, numClusters, 'kmpp', 10);\n const clusterCounts = new Array<number>(clusters.idxs.length).fill(0);\n const clusterBounds = clusterCounts.map(_ => new THREE.Box3());\n clusters.idxs.map(x => clusterCounts[x]++);\n const biggestCluster = clusterCounts.reduce(\n (max, count, idx) => {\n if (count > max.count) {\n max.count = count;\n max.idx = idx;\n }\n return max;\n },\n { count: 0, idx: -1 }\n ).idx;\n clusters.idxs.forEach((cluster, idx) => {\n clusterCounts[cluster]++;\n clusterBounds[cluster].expandByPoint(allBounds[idx].min);\n clusterBounds[cluster].expandByPoint(allBounds[idx].max);\n });\n\n const intersectingBounds = clusterBounds.filter((x, idx) => {\n if (idx !== biggestCluster && x.intersectsBox(clusterBounds[biggestCluster])) {\n return true;\n }\n return false;\n });\n if (intersectingBounds.length > 0) {\n // Overlapping clusters - assume it's because the model doesn't contain junk geometry\n const merged = clusterBounds[biggestCluster].clone();\n intersectingBounds.forEach(x => {\n merged.expandByPoint(x.min);\n merged.expandByPoint(x.max);\n });\n return merged;\n } else {\n // Create bounds of the biggest cluster - assume the smallest one is junk geometry\n return clusterBounds[biggestCluster];\n }\n }\n\n getSectorsIntersectingFrustum(\n projectionMatrix: THREE.Matrix4,\n inverseCameraModelMatrix: THREE.Matrix4\n ): SectorMetadata[] {\n const frustumMatrix = new THREE.Matrix4().multiplyMatrices(projectionMatrix, inverseCameraModelMatrix);\n const frustum = new THREE.Frustum().setFromProjectionMatrix(frustumMatrix);\n const accepted: SectorMetadata[] = [];\n traverseDepthFirst(this.root, x => {\n if (frustum.intersectsBox(x.bounds)) {\n accepted.push(x);\n return true;\n }\n return false;\n });\n return accepted;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { SectorMetadata, SectorMetadataFacesFileSection } from '../types';\nimport { SectorScene } from '../../utilities/types';\nimport { SectorSceneImpl } from '../../utilities/SectorScene';\n\nexport interface CadSectorMetadataV8 {\n readonly id: number;\n readonly parentId: number;\n readonly path: string;\n readonly depth: number;\n readonly estimatedDrawCallCount: number;\n readonly estimatedTriangleCount: number;\n\n readonly boundingBox: {\n readonly min: {\n x: number;\n y: number;\n z: number;\n };\n readonly max: {\n x: number;\n y: number;\n z: number;\n };\n };\n readonly indexFile: {\n readonly fileName: string;\n readonly peripheralFiles: string[];\n readonly downloadSize: number;\n };\n readonly facesFile: {\n readonly quadSize: number;\n readonly coverageFactors: {\n xy: number;\n yz: number;\n xz: number;\n };\n readonly recursiveCoverageFactors:\n | {\n xy: number;\n yz: number;\n xz: number;\n }\n | undefined;\n readonly fileName: string | null;\n readonly downloadSize: number;\n } | null;\n}\n\nexport interface CadMetadataV8 {\n readonly version: 8;\n readonly maxTreeIndex: number;\n readonly sectors: CadSectorMetadataV8[];\n readonly unit: string | null;\n\n // Available, but unused:\n // readonly projectId: number;\n // readonly modelId: number;\n // readonly revisionId: number;\n // readonly subRevisionId: number;\n}\n\nexport function parseCadMetadataV8(metadata: CadMetadataV8): SectorScene {\n // Create list of sectors and a map of child -> parent\n const sectorsById = new Map<number, SectorMetadata>();\n const parentIds: number[] = [];\n metadata.sectors.forEach(s => {\n const sector = createSectorMetadata(s);\n sectorsById.set(s.id, sector);\n parentIds[s.id] = s.parentId;\n });\n\n // Establish relationships between sectors\n for (const sector of sectorsById.values()) {\n const parentId = parentIds[sector.id];\n if (parentId === -1) {\n continue;\n }\n const parent = sectorsById.get(parentId)!;\n parent.children.push(sector);\n }\n\n const rootSector = sectorsById.get(0);\n if (!rootSector) {\n throw new Error('Root sector not found, must have ID 0');\n }\n // Check for missing facesFile-sections and provide coverage factors from parents when necessary\n populateCoverageFactorsFromAnchestors(rootSector, rootSector.facesFile);\n\n const unit = metadata.unit !== null ? metadata.unit : 'Meters';\n\n return new SectorSceneImpl(metadata.version, metadata.maxTreeIndex, unit, rootSector, sectorsById);\n}\n\nfunction createSectorMetadata(metadata: CadSectorMetadataV8): SectorMetadata {\n const facesFile = determineFacesFile(metadata);\n\n const bb = metadata.boundingBox;\n const min_x = bb.min.x;\n const min_y = bb.min.y;\n const min_z = bb.min.z;\n const max_x = bb.max.x;\n const max_y = bb.max.y;\n const max_z = bb.max.z;\n return {\n id: metadata.id,\n path: metadata.path,\n depth: metadata.depth,\n bounds: new THREE.Box3(new THREE.Vector3(min_x, min_y, min_z), new THREE.Vector3(max_x, max_y, max_z)),\n estimatedDrawCallCount: metadata.estimatedDrawCallCount,\n estimatedRenderCost: metadata.estimatedTriangleCount || 0,\n\n // I3D\n indexFile: { ...metadata.indexFile },\n // F3D\n facesFile,\n\n // Populated later\n children: []\n };\n}\n\nfunction determineFacesFile(metadata: CadSectorMetadataV8): SectorMetadataFacesFileSection {\n if (!metadata.facesFile) {\n return {\n quadSize: -1.0,\n coverageFactors: {\n xy: -1.0,\n yz: -1.0,\n xz: -1.0\n },\n recursiveCoverageFactors: {\n xy: -1.0,\n yz: -1.0,\n xz: -1.0\n },\n fileName: null,\n downloadSize: metadata.indexFile.downloadSize\n };\n }\n const facesFile = {\n ...metadata.facesFile,\n recursiveCoverageFactors: metadata.facesFile.recursiveCoverageFactors || metadata.facesFile.coverageFactors\n };\n return facesFile;\n}\n\nfunction hasDummyFacesFileSection(metadata: SectorMetadata): boolean {\n return metadata.facesFile.coverageFactors.xy === -1.0;\n}\n\nfunction populateCoverageFactorsFromAnchestors(\n sector: SectorMetadata,\n validFacesFileSection: SectorMetadataFacesFileSection\n) {\n if (hasDummyFacesFileSection(sector)) {\n sector.facesFile.coverageFactors.xy = validFacesFileSection.recursiveCoverageFactors.xy;\n sector.facesFile.coverageFactors.yz = validFacesFileSection.recursiveCoverageFactors.yz;\n sector.facesFile.coverageFactors.xz = validFacesFileSection.recursiveCoverageFactors.xz;\n sector.facesFile.recursiveCoverageFactors.xy = validFacesFileSection.recursiveCoverageFactors.xy;\n sector.facesFile.recursiveCoverageFactors.yz = validFacesFileSection.recursiveCoverageFactors.yz;\n sector.facesFile.recursiveCoverageFactors.xz = validFacesFileSection.recursiveCoverageFactors.xz;\n sector.children.forEach(child => populateCoverageFactorsFromAnchestors(child, validFacesFileSection));\n } else {\n sector.children.forEach(child => populateCoverageFactorsFromAnchestors(child, sector.facesFile));\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { parseCadMetadataV8 } from './parsers/CadMetadataParserV8';\nimport { SectorScene } from '../utilities/types';\n\ninterface VersionHeader {\n readonly version: number;\n}\n\nexport class CadMetadataParser {\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n public parse(parsedJson: any): SectorScene {\n const version = (parsedJson as VersionHeader).version;\n switch (version) {\n case 8:\n return parseCadMetadataV8(parsedJson);\n\n case undefined:\n throw new Error('Metadata must contain a \"version\"-field');\n\n default:\n throw new Error(`Version ${version} is not supported`);\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { SectorMetadata } from '../metadata/types';\n/**\n * Conversion factors from a given unit to meters.\n */\nexport const WellKnownDistanceToMeterConversionFactors = new Map<string, number>([\n ['Meters', 1.0],\n ['Centimeters', 0.01],\n ['Millimeters', 0.001],\n ['Micrometers', 1e-6],\n ['Kilometers', 1000],\n ['Feet', 0.3048],\n ['Inches', 0.0254],\n ['Yards', 0.9144],\n ['Miles', 1609.34],\n ['Mils', 0.0254 * 1e-3],\n ['Microinches', 0.0254 * 1e-6]\n]);\n\nexport interface SectorScene {\n readonly version: number;\n readonly maxTreeIndex: number;\n readonly root: SectorMetadata;\n readonly unit: string;\n\n readonly sectorCount: number;\n getSectorById(sectorId: number): SectorMetadata | undefined;\n getSectorsContainingPoint(p: THREE.Vector3): SectorMetadata[];\n getSectorsIntersectingBox(b: THREE.Box3): SectorMetadata[];\n\n /**\n * Returns bounds that contains \"most geometry\". This bounds is an\n * attempt to remove junk geometry from the bounds to allow e.g. setting\n * a good camera position.\n */\n getBoundsOfMostGeometry(): THREE.Box3;\n\n /**\n * Gets the sectors intersecting the frustum provided from the projection and inverse\n * camera matrix. Note that this function expects matrices in the the coordinate system\n * of the metadata. See below how to convert ThreeJS camera matrices to the correct format.\n *\n * @example Converting a ThreeJS camera to a frustum\n * ```\n * const cameraMatrixWorldInverse = camera.matrixWorldInverse;\n * const cameraProjectionMatrix = camera.projectionMatrix;\n *\n * const transformedCameraMatrixWorldInverse =\n * new THREE.Matrix4().multiplyMatrices(cameraMatrixWorldInverse, model.modelMatrix)\n *\n * const intersectingSectors = model.scene.getSectorsIntersectingFrustum(\n * cameraProjectionMatrix,\n * transformedCameraMatrixWorldInverse\n * );\n * ```\n * @param projectionMatrix\n * @param inverseCameraModelMatrix\n */\n getSectorsIntersectingFrustum(\n projectionMatrix: THREE.Matrix4,\n inverseCameraModelMatrix: THREE.Matrix4\n ): SectorMetadata[];\n getAllSectors(): SectorMetadata[];\n\n // Available, but not supported:\n // readonly projectId: number;\n // readonly modelId: number;\n // readonly revisionId: number;\n // readonly subRevisionId: number;\n // readonly unit: string | null;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { CadMetadataParser } from './CadMetadataParser';\n\nimport { SectorScene, WellKnownDistanceToMeterConversionFactors } from '../utilities/types';\nimport { CadModelMetadata } from './CadModelMetadata';\nimport { MetadataRepository } from './MetadataRepository';\nimport { transformCameraConfiguration } from '@reveal/utilities';\n\nimport { ModelDataProvider, ModelMetadataProvider, ModelIdentifier } from '@reveal/modeldata-api';\n\nexport class CadModelMetadataRepository implements MetadataRepository<Promise<CadModelMetadata>> {\n private readonly _modelMetadataProvider: ModelMetadataProvider;\n private readonly _modelDataProvider: ModelDataProvider;\n private readonly _cadSceneParser: CadMetadataParser;\n private readonly _blobFileName: string;\n private _currentModelIdentifier = 0;\n\n constructor(\n modelMetadataProvider: ModelMetadataProvider,\n modelDataProvider: ModelDataProvider,\n cadMetadataParser: CadMetadataParser,\n blobFileName: string = 'scene.json'\n ) {\n this._modelMetadataProvider = modelMetadataProvider;\n this._modelDataProvider = modelDataProvider;\n this._cadSceneParser = cadMetadataParser;\n this._blobFileName = blobFileName;\n }\n\n async loadData(modelIdentifier: ModelIdentifier): Promise<CadModelMetadata> {\n const blobBaseUrlPromise = this._modelMetadataProvider.getModelUri(modelIdentifier);\n const modelMatrixPromise = this._modelMetadataProvider.getModelMatrix(modelIdentifier);\n const modelCameraPromise = this._modelMetadataProvider.getModelCamera(modelIdentifier);\n\n const blobBaseUrl = await blobBaseUrlPromise;\n const json = await this._modelDataProvider.getJsonFile(blobBaseUrl, this._blobFileName);\n const scene: SectorScene = this._cadSceneParser.parse(json);\n const modelMatrix = createScaleToMetersModelMatrix(scene.unit, await modelMatrixPromise);\n const inverseModelMatrix = new THREE.Matrix4().copy(modelMatrix).invert();\n const cameraConfiguration = await modelCameraPromise;\n\n return {\n modelIdentifier: `${this._currentModelIdentifier++}`, // TODO 2021-10-03 larsmoa: Change to ModelIdentifier\n modelBaseUrl: blobBaseUrl,\n // Clip box is not loaded, it must be set elsewhere\n geometryClipBox: null,\n modelMatrix,\n inverseModelMatrix,\n cameraConfiguration: transformCameraConfiguration(cameraConfiguration, modelMatrix),\n scene\n };\n }\n}\n\nfunction createScaleToMetersModelMatrix(unit: string, modelMatrix: THREE.Matrix4): THREE.Matrix4 {\n const conversionFactor = WellKnownDistanceToMeterConversionFactors.get(unit);\n if (conversionFactor === undefined) {\n throw new Error(`Unknown model unit '${unit}'`);\n }\n\n const scaledModelMatrix = new THREE.Matrix4().makeScale(conversionFactor, conversionFactor, conversionFactor);\n return scaledModelMatrix.multiply(modelMatrix);\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nexport enum LevelOfDetail {\n Discarded,\n Simple,\n Detailed\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { SectorSceneImpl } from './SectorScene';\nimport { SectorMetadata } from '../metadata/types';\nimport { SectorScene } from './types';\n\nimport { traverseDepthFirst } from '@reveal/utilities';\n\nimport assert from 'assert';\n\n/**\n * Factory for creating instance of {@link SectorScene} based on\n * the version of the format provided.\n */\nexport class SectorSceneFactory {\n createSectorScene(version: number, maxTreeIndex: number, unit: string, root: SectorMetadata): SectorScene {\n assert(version === 8, 'Only version 8 is currently supported');\n\n const sectorsById: Map<number, SectorMetadata> = new Map();\n traverseDepthFirst(root, x => {\n sectorsById.set(x.id, x);\n return true;\n });\n return new SectorSceneImpl(version, maxTreeIndex, unit, root, sectorsById);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { AutoDisposeGroup } from '@reveal/utilities';\nimport { LevelOfDetail } from '../cad/LevelOfDetail';\n\nexport class SectorNode extends THREE.Group {\n public readonly sectorPath: string;\n public readonly sectorId: number;\n public readonly bounds: THREE.Box3;\n public readonly depth: number;\n\n private _group?: AutoDisposeGroup;\n private _lod = LevelOfDetail.Discarded;\n private _updatedTimestamp: number = Date.now();\n\n constructor(sectorId: number, sectorPath: string, bounds: THREE.Box3) {\n super();\n this.name = `Sector ${sectorPath} [id=${sectorId}]`;\n this.sectorId = sectorId;\n this.sectorPath = sectorPath;\n this.bounds = bounds;\n this.depth = determineSectorDepth(sectorPath);\n }\n\n get levelOfDetail(): LevelOfDetail {\n return this._lod;\n }\n\n get group(): THREE.Group | undefined {\n return this._group;\n }\n\n get updatedTimestamp(): number {\n return this._updatedTimestamp;\n }\n\n updateGeometry(geomtryGroup: AutoDisposeGroup | undefined, levelOfDetail: LevelOfDetail): void {\n this.resetGeometry();\n this._group = geomtryGroup;\n if (this._group !== undefined) {\n this._group.reference();\n }\n this._lod = levelOfDetail;\n this._updatedTimestamp = Date.now();\n this.visible = this._lod !== LevelOfDetail.Discarded;\n this.updateMatrixWorld(true);\n }\n\n resetGeometry(): void {\n if (this._group !== undefined) {\n this._group.dereference();\n this.remove(this._group);\n }\n\n this._group = undefined;\n this._lod = LevelOfDetail.Discarded;\n this._updatedTimestamp = Date.now();\n }\n}\n\nfunction determineSectorDepth(path: string): number {\n let depth = 0;\n for (let i = 0; i < path.length; ++i) {\n depth += path[i] === '/' ? 1 : 0;\n }\n return depth - 1;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { SectorNode } from './SectorNode';\nimport { SectorMetadata } from '../metadata/types';\nimport { CadModelMetadata } from '../metadata/CadModelMetadata';\n\nexport class RootSectorNode extends SectorNode {\n public readonly sectorNodeMap: Map<number, SectorNode>;\n\n constructor(modelMetadata: CadModelMetadata) {\n const modelBounds = modelMetadata.scene.root.bounds.clone();\n modelBounds.applyMatrix4(modelMetadata.modelMatrix);\n super(0, '/', modelBounds);\n\n const { scene, modelMatrix } = modelMetadata;\n this.sectorNodeMap = new Map();\n buildScene(scene.root, this, this.sectorNodeMap, modelMatrix);\n\n // Disable automatic update of matrices of the subtree as it\n // is quite time consuming. We trust that our owner keeps\n // our matrices updated.\n this.matrixAutoUpdate = false;\n this.setModelTransformation(modelMatrix);\n }\n\n setModelTransformation(matrix: THREE.Matrix4): void {\n this.matrix.copy(matrix);\n this.updateMatrixWorld(true);\n }\n\n getModelTransformation(out = new THREE.Matrix4()): THREE.Matrix4 {\n return out.copy(this.matrix);\n }\n}\n\nfunction buildScene(\n sector: SectorMetadata,\n parent: SectorNode,\n sectorNodeMap: Map<number, SectorNode>,\n modelMatrix: THREE.Matrix4\n) {\n const bounds = sector.bounds.clone();\n bounds.applyMatrix4(modelMatrix);\n const sectorGroup = new SectorNode(sector.id, sector.path, bounds);\n sectorGroup.name = `Sector ${sector.id}`;\n parent.add(sectorGroup);\n sectorGroup.matrixAutoUpdate = false;\n sectorGroup.updateMatrixWorld(true);\n\n sectorNodeMap.set(sector.id, sectorGroup);\n for (const child of sector.children) {\n buildScene(child, sectorGroup, sectorNodeMap, modelMatrix);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { WorkerPool } from '@reveal/utilities';\n\nimport { ParseSectorResult, ParseCtmResult, RevealParserWorker, SectorQuads } from '@cognite/reveal-parser-worker';\n\nexport class CadSectorParser {\n private readonly workerPool: WorkerPool;\n constructor(workerPool: WorkerPool = WorkerPool.defaultPool) {\n this.workerPool = workerPool;\n }\n\n parseI3D(data: Uint8Array): Promise<ParseSectorResult> {\n return this.parseDetailed(data);\n }\n\n parseF3D(data: Uint8Array): Promise<SectorQuads> {\n return this.parseSimple(data);\n }\n\n parseCTM(data: Uint8Array): Promise<ParseCtmResult> {\n return this.parseCtm(data);\n }\n\n private async parseSimple(quadsArrayBuffer: Uint8Array): Promise<SectorQuads> {\n return this.workerPool.postWorkToAvailable<SectorQuads>(async (worker: RevealParserWorker) =>\n worker.parseQuads(quadsArrayBuffer)\n );\n }\n\n private async parseDetailed(sectorArrayBuffer: Uint8Array): Promise<ParseSectorResult> {\n return this.workerPool.postWorkToAvailable(async (worker: RevealParserWorker) =>\n worker.parseSector(sectorArrayBuffer)\n );\n }\n\n private async parseCtm(ctmArrayBuffer: Uint8Array): Promise<ParseCtmResult> {\n return this.workerPool.postWorkToAvailable(async (worker: RevealParserWorker) => worker.parseCtm(ctmArrayBuffer));\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport { ParsePrimitiveAttribute } from '@cognite/reveal-parser-worker';\n\nconst computeBoundingBoxFromCenterAndRadiusAttributesVars = {\n centerA: new THREE.Vector3(),\n centerB: new THREE.Vector3(),\n sphere: new THREE.Sphere(),\n box: new THREE.Box3()\n};\n\nexport function computeBoundingBoxFromCenterAndRadiusAttributes(\n centerAattribute: ParsePrimitiveAttribute,\n centerBattribute: ParsePrimitiveAttribute,\n radiusAattribute: ParsePrimitiveAttribute,\n radiusBattribute: ParsePrimitiveAttribute,\n attributeFloatValues: Float32Array,\n elementSize: number,\n elementIndex: number,\n out: THREE.Box3\n): THREE.Box3 {\n const { centerA, centerB, sphere, box } = computeBoundingBoxFromCenterAndRadiusAttributesVars;\n\n function readAttribute(attribute: ParsePrimitiveAttribute, idx: number = 0): number {\n const offset = (elementIndex * elementSize + attribute.offset) / attributeFloatValues.BYTES_PER_ELEMENT;\n return attributeFloatValues[offset + idx];\n }\n\n centerA.set(\n readAttribute(centerAattribute, 0),\n readAttribute(centerAattribute, 1),\n readAttribute(centerAattribute, 2)\n );\n centerB.set(\n readAttribute(centerBattribute, 0),\n readAttribute(centerBattribute, 1),\n readAttribute(centerBattribute, 2)\n );\n const radiusA = readAttribute(radiusAattribute);\n const radiusB = readAttribute(radiusBattribute);\n\n // Note! Not the tighest fit we could make, works ok for now but could be improved by\n // using normal of each cap to determine exact end points of the top/bottom\n sphere.set(centerA, radiusA);\n sphere.getBoundingBox(out);\n sphere.set(centerB, radiusB);\n sphere.getBoundingBox(box);\n out.expandByPoint(box.min);\n out.expandByPoint(box.max);\n return out;\n}\n\nconst computeBoundingBoxFromVertexAttributesVars = {\n vertex1: new THREE.Vector3(),\n vertex2: new THREE.Vector3(),\n vertex3: new THREE.Vector3(),\n vertex4: new THREE.Vector3()\n};\n\nexport function computeBoundingBoxFromVertexAttributes(\n vertex1Attribute: ParsePrimitiveAttribute,\n vertex2Attribute: ParsePrimitiveAttribute,\n vertex3Attribute: ParsePrimitiveAttribute,\n vertex4Attribute: ParsePrimitiveAttribute,\n attributeFloatValues: Float32Array,\n elementSize: number,\n elementIndex: number,\n out: THREE.Box3\n): THREE.Box3 {\n const { vertex1, vertex2, vertex3, vertex4 } = computeBoundingBoxFromVertexAttributesVars;\n\n function readAttribute(attribute: ParsePrimitiveAttribute, idx: number = 0): number {\n const offset = (elementIndex * elementSize + attribute.offset) / attributeFloatValues.BYTES_PER_ELEMENT;\n return attributeFloatValues[offset + idx];\n }\n\n vertex1.set(\n readAttribute(vertex1Attribute, 0),\n readAttribute(vertex1Attribute, 1),\n readAttribute(vertex1Attribute, 2)\n );\n vertex2.set(\n readAttribute(vertex2Attribute, 0),\n readAttribute(vertex2Attribute, 1),\n readAttribute(vertex2Attribute, 2)\n );\n vertex3.set(\n readAttribute(vertex3Attribute, 0),\n readAttribute(vertex3Attribute, 1),\n readAttribute(vertex3Attribute, 2)\n );\n vertex4.set(\n readAttribute(vertex4Attribute, 0),\n readAttribute(vertex4Attribute, 1),\n readAttribute(vertex4Attribute, 2)\n );\n\n out.setFromPoints([vertex1, vertex2, vertex3, vertex4]);\n return out;\n}\n\nconst computeBoundingBoxFromInstanceMatrixAttributesVars = {\n instanceMatrix: new THREE.Matrix4()\n};\n\nexport function computeBoundingBoxFromInstanceMatrixAttributes(\n instanceMatrixAttribute: ParsePrimitiveAttribute,\n attributeFloatValues: Float32Array,\n elementSize: number,\n elementIndex: number,\n baseBoundingBox: THREE.Box3,\n out: THREE.Box3\n): THREE.Box3 {\n const { instanceMatrix } = computeBoundingBoxFromInstanceMatrixAttributesVars;\n\n const offset = (elementIndex * elementSize + instanceMatrixAttribute.offset) / attributeFloatValues.BYTES_PER_ELEMENT;\n // Note! set() accepts row-major, stored column-major\n instanceMatrix.set(\n attributeFloatValues[offset + 0],\n attributeFloatValues[offset + 4],\n attributeFloatValues[offset + 8],\n attributeFloatValues[offset + 12],\n\n attributeFloatValues[offset + 1],\n attributeFloatValues[offset + 5],\n attributeFloatValues[offset + 9],\n attributeFloatValues[offset + 13],\n\n attributeFloatValues[offset + 2],\n attributeFloatValues[offset + 6],\n attributeFloatValues[offset + 10],\n attributeFloatValues[offset + 14],\n\n attributeFloatValues[offset + 3],\n attributeFloatValues[offset + 7],\n attributeFloatValues[offset + 11],\n attributeFloatValues[offset + 15]\n );\n out.copy(baseBoundingBox).applyMatrix4(instanceMatrix);\n return out;\n}\n\nconst computeBoundingBoxFromEllipseAttributesVars = {\n center: new THREE.Vector3(),\n size: new THREE.Vector3()\n};\n\nexport function computeBoundingBoxFromEllipseAttributes(\n centerAttribute: ParsePrimitiveAttribute,\n radius1Attribute: ParsePrimitiveAttribute,\n radius2Attribute: ParsePrimitiveAttribute,\n heightAttribute: ParsePrimitiveAttribute,\n attributeFloatValues: Float32Array,\n elementSize: number,\n elementIndex: number,\n out: THREE.Box3\n): THREE.Box3 {\n const { center, size } = computeBoundingBoxFromEllipseAttributesVars;\n\n function readAttribute(attribute: ParsePrimitiveAttribute, idx: number = 0): number {\n const offset = (elementIndex * elementSize + attribute.offset) / attributeFloatValues.BYTES_PER_ELEMENT;\n return attributeFloatValues[offset + idx];\n }\n\n center.set(readAttribute(centerAttribute, 0), readAttribute(centerAttribute, 1), readAttribute(centerAttribute, 2));\n const radius1 = readAttribute(radius1Attribute);\n const radius2 = readAttribute(radius2Attribute);\n const height = readAttribute(heightAttribute);\n const extent = 2.0 * Math.max(radius1, radius2, height);\n size.set(extent, extent, extent);\n out.setFromCenterAndSize(center, size);\n return out;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { ParsePrimitiveAttribute } from '@cognite/reveal-parser-worker';\nimport assert from 'assert';\nimport {\n computeBoundingBoxFromCenterAndRadiusAttributes,\n computeBoundingBoxFromEllipseAttributes,\n computeBoundingBoxFromInstanceMatrixAttributes,\n computeBoundingBoxFromVertexAttributes\n} from '../utilities/computeBoundingBoxFromAttributes';\n\nfunction filterPrimitivesOutsideClipBox(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n clipBox: THREE.Box3,\n getBoundsOfElementsCallback: (\n index: number,\n elementSize: number,\n attributeFloatValues: Float32Array,\n outBox: THREE.Box3\n ) => void\n): Uint8Array {\n const elementSize = Array.from(attributes.values()).reduce((a, b) => Math.max(a, b.offset + b.size), 0);\n const elementCount = attributesByteValues.length / elementSize;\n const attributeFloatValues = new Float32Array(attributesByteValues.buffer);\n\n const instanceBbox = new THREE.Box3();\n\n const filteredByteValues = new Uint8Array(attributesByteValues.length);\n let filteredCount = 0;\n for (let i = 0; i < elementCount; ++i) {\n getBoundsOfElementsCallback(i, elementSize, attributeFloatValues, instanceBbox);\n\n if (clipBox.intersectsBox(instanceBbox)) {\n const elementValues = attributesByteValues.subarray(i * elementSize, (i + 1) * elementSize);\n filteredByteValues.set(elementValues, filteredCount * elementSize);\n filteredCount++;\n }\n }\n return filteredByteValues.slice(0, filteredCount * elementSize);\n}\n\nexport function filterPrimitivesOutsideClipBoxByBaseBoundsAndInstanceMatrix(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n baseBox: THREE.Box3,\n geometryClipBox: THREE.Box3 | null\n): Uint8Array {\n if (geometryClipBox === null) {\n return attributesByteValues;\n }\n const instanceMatrixAttribute = attributes.get('instanceMatrix');\n assert(instanceMatrixAttribute !== undefined);\n return filterPrimitivesOutsideClipBox(\n attributesByteValues,\n attributes,\n geometryClipBox,\n (index, elementSize, attributeFloatValues, outBox) => {\n computeBoundingBoxFromInstanceMatrixAttributes(\n instanceMatrixAttribute,\n attributeFloatValues,\n elementSize,\n index,\n baseBox,\n outBox\n );\n }\n );\n}\n\nexport function filterPrimitivesOutsideClipBoxByCenterAndRadius(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n geometryClipBox: THREE.Box3 | null,\n radiusAattributeName: string = 'radiusA',\n radiusBattributeName: string = 'radiusB'\n): Uint8Array {\n if (geometryClipBox === null) {\n return attributesByteValues;\n }\n\n const centerAattribute = attributes.get('centerA');\n const centerBattribute = attributes.get('centerB');\n const radiusAattribute = attributes.get(radiusAattributeName);\n const radiusBattribute = attributes.get(radiusBattributeName);\n assert(\n centerAattribute !== undefined &&\n centerBattribute !== undefined &&\n radiusAattribute !== undefined &&\n radiusBattribute !== undefined\n );\n return filterPrimitivesOutsideClipBox(\n attributesByteValues,\n attributes,\n geometryClipBox,\n (index, elementSize, attributeFloatValues, outBox) => {\n computeBoundingBoxFromCenterAndRadiusAttributes(\n centerAattribute,\n centerBattribute,\n radiusAattribute,\n radiusBattribute,\n attributeFloatValues,\n elementSize,\n index,\n outBox\n );\n }\n );\n}\n\nexport function filterPrimitivesOutsideClipBoxByVertices(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n geometryClipBox: THREE.Box3 | null\n): Uint8Array {\n if (geometryClipBox === null) {\n return attributesByteValues;\n }\n\n const vertex1attribute = attributes.get('vertex1');\n const vertex2attribute = attributes.get('vertex2');\n const vertex3attribute = attributes.get('vertex3');\n const vertex4attribute = attributes.get('vertex4');\n assert(\n vertex1attribute !== undefined &&\n vertex2attribute !== undefined &&\n vertex3attribute !== undefined &&\n vertex4attribute !== undefined\n );\n return filterPrimitivesOutsideClipBox(\n attributesByteValues,\n attributes,\n geometryClipBox,\n (index, elementSize, attributeFloatValues, outBox) => {\n computeBoundingBoxFromVertexAttributes(\n vertex1attribute,\n vertex2attribute,\n vertex3attribute,\n vertex4attribute,\n attributeFloatValues,\n elementSize,\n index,\n outBox\n );\n }\n );\n}\n\nexport function filterPrimitivesOutsideClipBoxByEllipse(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n geometryClipBox: THREE.Box3 | null,\n radius1AttributeName: string = 'horizontalRadius',\n radius2AttributeName: string = 'verticalRadius'\n): Uint8Array {\n if (geometryClipBox === null) {\n return attributesByteValues;\n }\n const centerAttribute = attributes.get('center');\n const horizontalRadiusAttribute = attributes.get(radius1AttributeName);\n const verticalRadiusAttribute = attributes.get(radius2AttributeName);\n const heightAttribute = attributes.get('height');\n assert(\n centerAttribute !== undefined &&\n horizontalRadiusAttribute !== undefined &&\n verticalRadiusAttribute !== undefined &&\n heightAttribute !== undefined\n );\n return filterPrimitivesOutsideClipBox(\n attributesByteValues,\n attributes,\n geometryClipBox,\n (index, elementSize, attributeFloatValues, outBox) => {\n computeBoundingBoxFromEllipseAttributes(\n centerAttribute,\n horizontalRadiusAttribute,\n verticalRadiusAttribute,\n heightAttribute,\n attributeFloatValues,\n elementSize,\n index,\n outBox\n );\n }\n );\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport { InstancedMesh } from './types';\n\nimport { float32BufferToMatrix } from '../utilities/float32BufferToMatrix';\n\nconst filterInstanceMeshVars = {\n p: new THREE.Vector3(),\n instanceMatrix: new THREE.Matrix4(),\n baseBounds: new THREE.Box3(),\n instanceBounds: new THREE.Box3()\n};\n\nexport function filterInstanceMesh(\n vertices: Float32Array,\n indices: Uint32Array,\n instanceMesh: InstancedMesh,\n geometryClipBox: THREE.Box3 | null\n): InstancedMesh {\n if (geometryClipBox === null) {\n return instanceMesh;\n }\n const { p, instanceMatrix, baseBounds, instanceBounds } = filterInstanceMeshVars;\n\n // Determine base bounds\n baseBounds.makeEmpty();\n for (let j = instanceMesh.triangleOffset; j < instanceMesh.triangleOffset + instanceMesh.triangleCount; ++j) {\n const v0 = indices[3 * j + 0];\n const v1 = indices[3 * j + 1];\n const v2 = indices[3 * j + 2];\n p.set(vertices[v0 + 0], vertices[v0 + 1], vertices[v0 + 2]);\n baseBounds.expandByPoint(p);\n p.set(vertices[v1 + 0], vertices[v1 + 1], vertices[v1 + 2]);\n baseBounds.expandByPoint(p);\n p.set(vertices[v2 + 0], vertices[v2 + 1], vertices[v2 + 2]);\n baseBounds.expandByPoint(p);\n }\n\n let filteredOffset = 0;\n const instanceCount = instanceMesh.treeIndices.length;\n const filteredInstanceMatrices = new Float32Array(instanceMesh.instanceMatrices.length);\n const filteredTreeIndices = new Float32Array(instanceCount);\n const filteredColors = new Uint8Array(4 * instanceCount);\n for (let i = 0; i < instanceCount; ++i) {\n float32BufferToMatrix(instanceMesh.instanceMatrices, i, instanceMatrix);\n\n instanceBounds.copy(baseBounds).applyMatrix4(instanceMatrix);\n if (geometryClipBox.intersectsBox(instanceBounds)) {\n const elementInstanceMatrix = instanceMesh.instanceMatrices.subarray(16 * i, 16 * (i + 1));\n const elementColor = instanceMesh.colors.subarray(4 * i, 4 * (i + 1));\n const elementTreeIndex = instanceMesh.treeIndices[i];\n\n filteredInstanceMatrices.set(elementInstanceMatrix, 16 * filteredOffset);\n filteredColors.set(elementColor, 4 * filteredOffset);\n filteredTreeIndices[filteredOffset] = elementTreeIndex;\n\n filteredOffset++;\n }\n }\n\n if (instanceCount === filteredOffset) {\n return instanceMesh; // Unchanged\n }\n\n const filteredMesh: InstancedMesh = {\n triangleCount: instanceMesh.triangleCount,\n triangleOffset: instanceMesh.triangleOffset,\n instanceMatrices: filteredInstanceMatrices.slice(0, 16 * filteredOffset),\n colors: filteredColors.slice(0, 4 * filteredOffset),\n treeIndices: filteredTreeIndices.slice(0, filteredOffset)\n };\n return filteredMesh;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\n/**\n * Sets the elements of a matrix from a row-major\n * matrix stored in a Float32Array.\n * @param buffer\n * @param indexOffset\n * @param outMatrix\n */\nexport function float32BufferToMatrix(\n buffer: Float32Array,\n indexOffset: number,\n outMatrix: THREE.Matrix4\n): THREE.Matrix4 {\n outMatrix.set(\n buffer[indexOffset + 0],\n buffer[indexOffset + 4],\n buffer[indexOffset + 8],\n buffer[indexOffset + 12],\n\n buffer[indexOffset + 1],\n buffer[indexOffset + 5],\n buffer[indexOffset + 9],\n buffer[indexOffset + 13],\n\n buffer[indexOffset + 2],\n buffer[indexOffset + 6],\n buffer[indexOffset + 10],\n buffer[indexOffset + 14],\n\n buffer[indexOffset + 3],\n buffer[indexOffset + 7],\n buffer[indexOffset + 11],\n buffer[indexOffset + 15]\n );\n return outMatrix;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\n/**\n * Generate a three-dimensional plane geometry,\n * with an optional applied tranformation function (u, v) => [ x, y, z ]\n */\nfunction generatePlane3D(\n segmentsX: number,\n segmentsY: number,\n transformFunc: (u: number, v: number) => number[] = (u, v) => [u, v, 0]\n) {\n const vertices = [];\n const indices = [];\n\n const segmentsXInv = 1 / segmentsX;\n const segmentsYInv = 1 / segmentsY;\n for (let j = 0; j <= segmentsY; j++) {\n for (let i = 0; i <= segmentsX; i++) {\n // vertices\n const [x, y, z] = transformFunc(i * segmentsXInv, j * segmentsYInv);\n vertices.push(x || 0, y || 0, z || 0);\n }\n }\n\n for (let j = 1; j <= segmentsY; j++) {\n for (let i = 1; i <= segmentsX; i++) {\n // indices\n const a = (segmentsX + 1) * j + i - 1;\n const b = (segmentsX + 1) * (j - 1) + i - 1;\n const c = (segmentsX + 1) * (j - 1) + i;\n const d = (segmentsX + 1) * j + i;\n\n // faces\n indices.push(a, b, d);\n indices.push(b, c, d);\n }\n }\n\n return {\n index: new THREE.Uint16BufferAttribute(indices, 1),\n position: new THREE.Float32BufferAttribute(vertices, 3)\n };\n}\n\nexport const { boxGeometry, boxGeometryBoundingBox } = (() => {\n const geometry = new THREE.BoxBufferGeometry(1, 1, 1, 1, 1, 1);\n try {\n const result = {\n index: geometry.getIndex(),\n position: geometry.getAttribute('position'),\n normal: geometry.getAttribute('normal')\n };\n geometry.computeBoundingBox();\n return { boxGeometry: result, boxGeometryBoundingBox: geometry.boundingBox! };\n } finally {\n geometry.dispose();\n }\n})();\n\nexport const { quadGeometry, quadGeometryBoundingBox } = (() => {\n const geometry = new THREE.PlaneBufferGeometry(1, 1, 1, 1);\n try {\n const result = {\n index: geometry.getIndex(),\n position: geometry.getAttribute('position'),\n normal: geometry.getAttribute('normal')\n };\n geometry.computeBoundingBox();\n return { quadGeometry: result, quadGeometryBoundingBox: geometry.boundingBox! };\n } finally {\n geometry.dispose();\n }\n})();\n\nexport const { trapeziumGeometry, trapeziumGeometryBoundingBox } = (() => {\n const index = [0, 1, 3, 0, 3, 2];\n const position = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3];\n return {\n trapeziumGeometry: {\n index: new THREE.BufferAttribute(new Uint16Array(index), 1),\n position: new THREE.BufferAttribute(new Float32Array(position), 3)\n },\n trapeziumGeometryBoundingBox: new THREE.Box3().setFromArray(position)\n };\n})();\n\n// cone\nexport const { coneGeometry, coneGeometryBoundingBox } = (() => {\n const positions = [];\n positions.push(-1, 1, -1);\n positions.push(-1, -1, -1);\n positions.push(1, 1, -1);\n positions.push(1, -1, -1);\n positions.push(1, 1, 1);\n positions.push(1, -1, 1);\n\n const indices = new Uint16Array([1, 2, 0, 1, 3, 2, 3, 4, 2, 3, 5, 4]);\n return {\n coneGeometry: {\n index: new THREE.BufferAttribute(indices, 1),\n position: new THREE.BufferAttribute(new Float32Array(positions), 3)\n },\n coneGeometryBoundingBox: new THREE.Box3().setFromArray(positions)\n };\n})();\n\nexport const { torusLodGeometries, torusGeometryBoundingBox } = (() => {\n const lods = [\n { tubularSegments: 9, radialSegments: 18 },\n { tubularSegments: 5, radialSegments: 12 },\n { tubularSegments: 4, radialSegments: 5 }\n ];\n const transformFunc = (u: number, v: number) => [u, v * 2.0 * Math.PI];\n const torusLodGeometries = lods.map(({ tubularSegments, radialSegments }) => {\n return generatePlane3D(radialSegments, tubularSegments, transformFunc);\n });\n\n return {\n torusLodGeometries,\n torusGeometryBoundingBox: new THREE.Box3().setFromArray(\n torusLodGeometries[torusLodGeometries.length - 1].position.array\n )\n };\n})();\n\nexport const { nutGeometry, nutGeometryBoundingBox } = (() => {\n const geometry = new THREE.CylinderBufferGeometry(0.5, 0.5, 1, 6);\n try {\n geometry.applyMatrix4(new THREE.Matrix4().makeRotationX(-Math.PI / 2));\n const result = {\n index: geometry.getIndex(),\n position: geometry.getAttribute('position'),\n normal: geometry.getAttribute('normal')\n };\n return { nutGeometry: result, nutGeometryBoundingBox: new THREE.Box3().setFromArray(result.position.array) };\n } finally {\n geometry.dispose();\n }\n})();\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { disposeAttributeArrayOnUpload } from '@reveal/utilities';\nimport { TriangleMesh } from '@reveal/cad-parsers';\n\nexport function createTriangleMeshes(\n triangleMeshes: TriangleMesh[],\n bounds: THREE.Box3,\n material: THREE.ShaderMaterial,\n geometryClipBox: THREE.Box3 | null\n): THREE.Mesh[] {\n const result: THREE.Mesh[] = [];\n\n const filteredTriangleMeshes = triangleMeshes.filter(mesh => {\n return geometryClipBox === null || isTriangleMeshWithin(mesh, geometryClipBox);\n });\n for (const mesh of filteredTriangleMeshes) {\n const geometry = new THREE.BufferGeometry();\n const indices = new THREE.Uint32BufferAttribute(mesh.indices.buffer, 1).onUpload(disposeAttributeArrayOnUpload);\n const vertices = new THREE.Float32BufferAttribute(mesh.vertices.buffer, 3).onUpload(disposeAttributeArrayOnUpload);\n const colors = new THREE.Uint8BufferAttribute(mesh.colors.buffer, 3).onUpload(disposeAttributeArrayOnUpload);\n\n const treeIndices = new THREE.Float32BufferAttribute(mesh.treeIndices.buffer, 1).onUpload(\n disposeAttributeArrayOnUpload\n );\n geometry.setIndex(indices);\n geometry.setAttribute('color', colors);\n geometry.setAttribute('position', vertices);\n geometry.setAttribute('treeIndex', treeIndices);\n geometry.boundingBox = bounds.clone();\n geometry.boundingSphere = new THREE.Sphere();\n bounds.getBoundingSphere(geometry.boundingSphere);\n\n const obj = new THREE.Mesh(geometry, material);\n obj.name = `Triangle mesh ${mesh.fileId}`;\n\n obj.userData.treeIndices = new Set(mesh.treeIndices);\n\n result.push(obj);\n }\n return result;\n}\n\nconst isTriangleMeshWithinArgs = {\n p: new THREE.Vector3(),\n box: new THREE.Box3()\n};\n\nfunction isTriangleMeshWithin(mesh: TriangleMesh, bounds: THREE.Box3): boolean {\n const { p, box } = isTriangleMeshWithinArgs;\n box.makeEmpty();\n for (let i = 0; i < mesh.vertices.length; i += 3) {\n p.set(mesh.vertices[i + 0], mesh.vertices[i + 1], mesh.vertices[i + 2]);\n box.expandByPoint(p);\n }\n return bounds.intersectsBox(box);\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { CogniteClient, HttpHeaders } from '@cognite/sdk';\n\nimport { ModelDataProvider } from './types';\n\n/**\n * Provides 3D V2 specific extensions for the standard CogniteClient used by Reveal.\n */\nexport class CdfModelDataProvider implements ModelDataProvider {\n private readonly client: CogniteClient;\n\n constructor(client: CogniteClient) {\n this.client = client;\n }\n\n get headers(): HttpHeaders {\n return this.client.getDefaultRequestHeaders();\n }\n\n public async getBinaryFile(baseUrl: string, fileName: string): Promise<ArrayBuffer> {\n const url = `${baseUrl}/${fileName}`;\n const headers = {\n ...this.client.getDefaultRequestHeaders(),\n Accept: '*/*'\n };\n\n const response = await fetchWithRetry(url, { headers, method: 'GET' });\n return response.arrayBuffer();\n }\n\n async getJsonFile(baseUrl: string, fileName: string): Promise<any> {\n const response = await this.client.get(`${baseUrl}/${fileName}`);\n return response.data;\n }\n}\n\nasync function fetchWithRetry(input: RequestInfo, options: RequestInit | undefined, retries: number = 3) {\n let error: Error | undefined;\n for (let i = 0; i < retries; i++) {\n try {\n return await fetch(input, options);\n } catch (err) {\n // Keep first error only\n if (error !== undefined) {\n error = err as Error;\n }\n }\n }\n throw error;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { ModelIdentifier } from '..';\nimport { File3dFormat } from './types';\n\n/**\n * Identifies a 3D model stored in CDF by the combination of a modelId, a revisionId\n * and a format.\n */\nexport class CdfModelIdentifier implements ModelIdentifier {\n readonly revealInternalId: symbol;\n readonly modelFormat: File3dFormat;\n\n readonly modelId: number;\n readonly revisionId: number;\n\n constructor(modelId: number, revisionId: number, modelFormat: File3dFormat) {\n this.revealInternalId = Symbol(`${modelId}/${revisionId}[${modelFormat}]`);\n this.modelId = modelId;\n this.revisionId = revisionId;\n this.modelFormat = modelFormat;\n }\n\n public toString(): string {\n return `${CdfModelIdentifier.name} (${String(this.revealInternalId)} - ${this.modelFormat})`;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { HttpHeaders } from '@cognite/sdk-core';\nexport interface JsonFileProvider {\n getJsonFile(baseUrl: string, fileName: string): Promise<any>;\n}\n\nexport interface BinaryFileProvider {\n getBinaryFile(baseUrl: string, fileName: string): Promise<ArrayBuffer>;\n}\n\n/**\n * Provides data for 3D models.\n * @version New since 2.2\n */\nexport interface ModelDataProvider extends HttpHeadersProvider, JsonFileProvider, BinaryFileProvider {\n /**\n * Download and parse a JSON file and return the resulting struct.\n * @param baseUrl Base URL of the model.\n * @param fileName Filename of JSON file.\n */\n getJsonFile(baseUrl: string, fileName: string): Promise<any>;\n /**\n * Downloads a binary blob.\n * @param baseUrl Base URL of the model.\n * @param fileName Filename of binary file.\n */\n getBinaryFile(baseUrl: string, fileName: string): Promise<ArrayBuffer>;\n}\n\nexport interface HttpHeadersProvider {\n readonly headers: HttpHeaders;\n}\n\nexport enum File3dFormat {\n EptPointCloud = 'ept-pointcloud',\n RevealCadModel = 'reveal-directory',\n AnyFormat = 'all-outputs'\n}\n\nexport interface BlobOutputMetadata {\n blobId: number;\n format: File3dFormat | string;\n version: number;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { File3dFormat } from './types';\n\n// The below is equal to new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(-Math.PI / 2, 0, 0));\nconst cadFromCdfToThreeMatrix = new THREE.Matrix4().set(1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1);\n\nexport function applyDefaultModelTransformation(matrix: THREE.Matrix4, format: File3dFormat | string): void {\n switch (format) {\n case File3dFormat.RevealCadModel:\n matrix.premultiply(cadFromCdfToThreeMatrix);\n break;\n\n case File3dFormat.EptPointCloud:\n // No action, identity transform\n break;\n\n default:\n throw new Error(`Unknown model format '${format}`);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { BlobOutputMetadata, File3dFormat } from './types';\n\nexport class Model3DOutputList {\n public readonly modelId: number;\n public readonly revisionId: number;\n public readonly outputs: BlobOutputMetadata[];\n\n constructor(modelId: number, revisionId: number, outputs: BlobOutputMetadata[]) {\n this.modelId = modelId;\n this.revisionId = revisionId;\n this.outputs = outputs;\n }\n\n /**\n * Finds an output with a given format of the most recent version.\n *\n * @param outputFormat Format to find output for, either a well known format a custom format.\n * @param supportedVersions Optional list of supported version. If not provided all versions are considered.\n */\n public findMostRecentOutput(\n outputFormat: File3dFormat | string,\n supportedVersions?: number[]\n ): BlobOutputMetadata | undefined {\n const candidates = this.outputs.filter(\n x => x.format === outputFormat && (!supportedVersions || supportedVersions.indexOf(x.version) !== -1)\n );\n return candidates.length > 0\n ? candidates.reduce((left, right) => {\n return right.version > left.version ? right : left;\n })\n : undefined;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport { BlobOutputMetadata } from './types';\nimport { ModelMetadataProvider } from './ModelMetadataProvider';\n\nimport { applyDefaultModelTransformation } from './applyDefaultModelTransformation';\nimport { Model3DOutputList } from './Model3DOutputList';\n\nimport { CogniteClient } from '@cognite/sdk';\nimport { ItemsResponse } from '@cognite/sdk-core';\nimport { ModelIdentifier } from './ModelIdentifier';\nimport { CdfModelIdentifier } from './CdfModelIdentifier';\n\n// TODO 2020-06-25 larsmoa: Extend CogniteClient.files3d.retrieve() to support subpath instead of\n// using URLs directly. Also add support for listing outputs in the SDK.\nexport class CdfModelMetadataProvider implements ModelMetadataProvider {\n private readonly _client: CogniteClient;\n\n constructor(client: CogniteClient) {\n this._client = client;\n }\n\n public async getModelMatrix(modelIdentifier: ModelIdentifier): Promise<THREE.Matrix4> {\n if (!(modelIdentifier instanceof CdfModelIdentifier)) {\n throw new Error(`Model must be a ${CdfModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n const { modelId, revisionId, modelFormat } = modelIdentifier;\n const model = await this._client.revisions3D.retrieve(modelId, revisionId);\n\n const modelMatrix = new THREE.Matrix4();\n if (model.rotation) {\n modelMatrix.makeRotationFromEuler(new THREE.Euler(...model.rotation));\n }\n applyDefaultModelTransformation(modelMatrix, modelFormat);\n return modelMatrix;\n }\n\n public async getModelCamera(\n modelIdentifier: ModelIdentifier\n ): Promise<{ position: THREE.Vector3; target: THREE.Vector3 } | undefined> {\n if (!(modelIdentifier instanceof CdfModelIdentifier)) {\n throw new Error(`Model must be a ${CdfModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n const { modelId, revisionId } = modelIdentifier;\n const model = await this._client.revisions3D.retrieve(modelId, revisionId);\n if (model.camera && model.camera.position && model.camera.target) {\n const { position, target } = model.camera;\n return {\n position: new THREE.Vector3(position[0], position[1], position[2]),\n target: new THREE.Vector3(target[0], target[1], target[2])\n };\n }\n return undefined;\n }\n\n public async getModelUri(modelIdentifier: ModelIdentifier): Promise<string> {\n if (!(modelIdentifier instanceof CdfModelIdentifier)) {\n throw new Error(`Model must be a ${CdfModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n const { modelId, revisionId, modelFormat } = modelIdentifier;\n const outputs = await this.getOutputs(modelIdentifier);\n const mostRecentOutput = outputs.findMostRecentOutput(modelFormat);\n if (!mostRecentOutput) {\n throw new Error(\n `Model '${modelId}/${revisionId}' is not compatible with this version of Reveal, because no outputs for format '(${modelFormat})' was found. If this model works with a previous version of Reveal it must be reprocessed to support this version.`\n );\n }\n const directoryId = mostRecentOutput.blobId;\n return `${this._client.getBaseUrl()}${this.getRequestPath(directoryId)}`;\n }\n\n private async getOutputs(modelIdentifier: CdfModelIdentifier): Promise<Model3DOutputList> {\n const { modelId, revisionId, modelFormat } = modelIdentifier;\n const url = `/api/v1/projects/${this._client.project}/3d/models/${modelId}/revisions/${revisionId}/outputs`;\n const params = modelFormat !== undefined ? { params: { format: modelFormat } } : undefined;\n const response = await this._client.get<ItemsResponse<BlobOutputMetadata>>(url, params);\n if (response.status === 200) {\n return new Model3DOutputList(modelId, revisionId, response.data.items);\n }\n throw new Error(`Unexpected response ${response.status} (payload: '${response.data})`);\n }\n\n private getRequestPath(directoryId: number): string {\n return `/api/v1/projects/${this._client.project}/3d/files/${directoryId}`;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { CdfModelIdentifier } from './CdfModelIdentifier';\nimport { Model3DOutputList } from './Model3DOutputList';\nimport { BlobOutputMetadata } from './types';\n\nimport { CogniteClient } from '@cognite/sdk';\nimport { ItemsResponse } from '@cognite/sdk-core';\n\n/**\n * Helper class for getting the available 'outputs' from the Cognite\n * 3D processing pipeline for a given model.\n */\nexport class CdfModelOutputsProvider {\n private readonly _client: CogniteClient;\n\n constructor(client: CogniteClient) {\n this._client = client;\n }\n\n public async getOutputs(modelIdentifier: CdfModelIdentifier): Promise<Model3DOutputList> {\n const { modelId, revisionId, modelFormat } = modelIdentifier;\n const url = `/api/v1/projects/${this._client.project}/3d/models/${modelId}/revisions/${revisionId}/outputs`;\n const params = modelFormat !== undefined ? { params: { format: modelFormat } } : undefined;\n const response = await this._client.get<ItemsResponse<BlobOutputMetadata>>(url, params);\n if (response.status === 200) {\n return new Model3DOutputList(modelId, revisionId, response.data.items);\n }\n throw new Error(`Unexpected response ${response.status} (payload: '${response.data})`);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { Versioned3DFile } from '@cognite/sdk';\n\n// To avoid direct dependency on @cognite/sdk we use sdk-core here for HttpError.\n// that's why it's avoided https://github.com/cognitedata/cdf-hub/pull/687/files#r489204315\nimport { HttpError } from '@cognite/sdk-core';\n\nexport const supportedVersions = [8];\n\nexport function getNewestVersionedFile(files: Versioned3DFile[]): Versioned3DFile {\n return files\n .filter(file => supportedVersions.includes(file.version))\n .reduce((newestFile, file) => (file.version > newestFile.version ? file : newestFile), {\n fileId: -1,\n version: -1\n });\n}\n\nexport async function fetchWithStatusCheck(url: string): Promise<Response> {\n const response = await fetch(url);\n if (!response.ok) {\n const headers: { [key: string]: string } = {};\n response.headers.forEach((key, value) => {\n headers[key] = value;\n });\n throw new HttpError(response.status, response.body, headers);\n }\n return response;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { HttpHeaders } from '@cognite/sdk-core';\nimport { ModelDataProvider } from './types';\nimport { fetchWithStatusCheck } from './utilities';\n\nexport class LocalModelDataProvider implements ModelDataProvider {\n get headers(): HttpHeaders {\n return {};\n }\n\n async getBinaryFile(baseUrl: string, fileName: string): Promise<ArrayBuffer> {\n const response = await fetchWithStatusCheck(`${baseUrl}/${fileName}`);\n return response.arrayBuffer();\n }\n\n async getJsonFile(baseUrl: string, fileName: string): Promise<any> {\n const response = await fetchWithStatusCheck(`${baseUrl}/${fileName}`);\n return response.json();\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { ModelIdentifier } from './ModelIdentifier';\n\n/**\n * Identifies a 3D model by a URL. This implementation is used for testing\n * purposes.\n */\nexport class LocalModelIdentifier implements ModelIdentifier {\n readonly revealInternalId: symbol;\n readonly localPath: string;\n\n constructor(localPath: string) {\n this.revealInternalId = Symbol(localPath);\n this.localPath = localPath;\n }\n\n public toString(): string {\n return `${LocalModelIdentifier.name} (${this.localPath})`;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\nimport { applyDefaultModelTransformation } from './applyDefaultModelTransformation';\nimport { LocalModelIdentifier } from './LocalModelIdentifier';\nimport { ModelIdentifier } from './ModelIdentifier';\nimport { ModelMetadataProvider } from './ModelMetadataProvider';\nimport { File3dFormat } from './types';\n\nexport class LocalModelMetadataProvider implements ModelMetadataProvider {\n getModelUri(modelIdentifier: ModelIdentifier): Promise<string> {\n if (!(modelIdentifier instanceof LocalModelIdentifier)) {\n throw new Error(`Model must be a ${LocalModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n return Promise.resolve(`${location.origin}/${modelIdentifier.localPath}`);\n }\n\n async getModelMatrix(modelIdentifier: ModelIdentifier): Promise<THREE.Matrix4> {\n if (!(modelIdentifier instanceof LocalModelIdentifier)) {\n throw new Error(`Model must be a ${LocalModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n const matrix = new THREE.Matrix4();\n applyDefaultModelTransformation(matrix, File3dFormat.RevealCadModel);\n return matrix;\n }\n\n getModelCamera(\n modelIdentifier: ModelIdentifier\n ): Promise<{ position: THREE.Vector3; target: THREE.Vector3 } | undefined> {\n if (!(modelIdentifier instanceof LocalModelIdentifier)) {\n throw new Error(`Model must be a ${LocalModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n return Promise.resolve(undefined);\n }\n}\n","module.exports = require(\"assert\");","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport mixpanel from 'mixpanel-browser';\n\nimport log from '@reveal/logger';\n\nimport { TrackedEvents, EventProps } from './types';\n\n/**\n * Source: https://stackoverflow.com/a/2117523/167251\n */\nfunction generateUuidv4(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n const r = (Math.random() * 16) | 0,\n v = c == 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nconst { VERSION, MIXPANEL_TOKEN } = process.env;\n\n// Don't identify users in MixPanel to avoid GDPR problems\nconst mixpanelDistinctId = 'reveal-single-user';\n\nexport class MetricsLogger {\n _sessionProps: {\n VERSION: string;\n project: string;\n application: string;\n sessionId: string;\n };\n\n private constructor(project: string, applicationId: string, eventProps: EventProps) {\n // Even though mixpanel has an opt out property, the mixpanel object\n // used by Metrics is not available here, so we have our own way of opting out.\n\n mixpanel.init(MIXPANEL_TOKEN, {\n disable_cookie: true,\n disable_persistence: true,\n // Don't send IP which disables geolocation\n ip: false,\n // Avoid sending a bunch of properties that might help identifying a user\n property_blacklist: [\n // https://help.mixpanel.com/hc/en-us/articles/115004613766-Default-Properties-Collected-by-Mixpanel#profile-properties-javascript\n '$city',\n '$region',\n 'mp_country_code',\n '$geo_source',\n '$timezone',\n 'mp_lib',\n '$lib_version',\n '$device_id',\n '$user_id',\n '$current_url',\n '$screen_width',\n '$screen_height',\n '$referrer',\n '$referring_domain',\n '$initial_referrer',\n '$initial_referring_domain'\n ]\n });\n // Reset device ID (even if we don't send it)\n mixpanel.reset();\n\n mixpanel.identify(mixpanelDistinctId);\n\n this._sessionProps = {\n VERSION,\n project: 'unknown',\n application: 'unknown',\n // Use a random identifier because we want to don't track users over multiple sessions to not\n // violate GDPR.\n sessionId: generateUuidv4()\n };\n\n if (project) {\n this._sessionProps.project = project;\n }\n if (applicationId) {\n this._sessionProps.application = applicationId;\n }\n this.innerTrackEvent('init', eventProps);\n }\n\n static init(logMetrics: boolean, project: string, applicationId: string, eventProps: EventProps): void {\n if (globalThis.revealMetricsLogger === undefined && logMetrics) {\n const metricsLogger = new MetricsLogger(project, applicationId, eventProps);\n globalThis.revealMetricsLogger = { metricsLogger };\n }\n }\n\n private innerTrackEvent(eventName: TrackedEvents, eventProps: EventProps): void {\n const combined = { ...this._sessionProps, ...eventProps };\n mixpanel.track(eventName, combined);\n }\n\n static trackEvent(eventName: TrackedEvents, eventProps: EventProps): void {\n if (globalThis.revealMetricsLogger) {\n globalThis.revealMetricsLogger.metricsLogger.innerTrackEvent(eventName, eventProps);\n }\n }\n\n static trackCreateTool(toolName: string): void {\n MetricsLogger.trackEvent('toolCreated', { toolName });\n }\n\n static trackLoadModel(eventProps: EventProps, modelIdentifier: any): void {\n MetricsLogger.trackEvent('loadModel', { ...eventProps, modelIdentifier });\n }\n\n static trackCadModelStyled(nodeCollectionClassToken: string, appearance: any): void {\n MetricsLogger.trackEvent('cadModelStyleAssigned', { nodeCollectionClassToken, style: appearance });\n }\n\n static trackError(error: Error, eventProps: EventProps): void {\n log.error(error);\n\n this.trackEvent('error', {\n message: error.message,\n name: error.name,\n stack: error.stack,\n ...eventProps\n });\n }\n\n static trackCameraNavigation(eventProps: EventProps): void {\n MetricsLogger.trackEvent('cameraNavigated', eventProps);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n// This file is in place for future-proofing. We can change the implementation here if\n// we want to use something else than loglevel.\n\nimport * as log from 'loglevel';\nexport default log;\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport log from './src/Log';\nexport default log;\n","module.exports = require(\"@tweenjs/tween.js\");","module.exports = require(\"mixpanel-browser\");","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nconst worldToViewportVars = {\n renderSize: new THREE.Vector2(),\n position: new THREE.Vector3()\n};\n\n/**\n * Maps from 3D world coordinates to normalized screen coordinates\n * relative to the canvas being rendered to. X and Y will\n * be in range [0, 1]. Z is in range [-1, 1] if the coordinate\n * is inside the camera near and far planes.\n * @param camera Camera used to project point from 3D to NDC coordinates\n * @param position3D World position in 3D\n * @param out Optionally pre-allocated THREE.Vector3\n * @returns Relative screen coordinates in X, Y and Z in range [-1, 1] if point\n * is within near/far of camera.\n */\nexport function worldToNormalizedViewportCoordinates(\n camera: THREE.PerspectiveCamera,\n position3D: THREE.Vector3,\n out: THREE.Vector3 = new THREE.Vector3()\n): THREE.Vector3 {\n const { position } = worldToViewportVars;\n\n // map to normalized device coordinate (NDC) space\n position.copy(position3D);\n position.project(camera);\n\n // map to 2D screen space\n const x = (position.x + 1) / 2;\n const y = (-position.y + 1) / 2;\n\n return out.set(x, y, position.z);\n}\n\n/**\n * Maps from 3D world coordinates to screen coordinates\n * relative to the canvas. X and Y will be in absolute\n * coordinates (0,0 being the top left of the canvas). Z is\n * in range [-1, 1] if the coordinate\n * is inside the camera near and far planes.\n * @param renderer Renderer used to render the \"world\"\n * @param camera Camera used to project point from 3D to NDC coordinates\n * @param position3D World position in 3D\n * @param out Optionally pre-allocated THREE.Vector3\n * @returns Relative screen coordinates in X, Y and Z in range [-1, 1] if point\n * is within near/far of camera.\n */\nexport function worldToViewportCoordinates(\n renderer: THREE.WebGLRenderer,\n camera: THREE.PerspectiveCamera,\n position3D: THREE.Vector3,\n out: THREE.Vector3 = new THREE.Vector3()\n): THREE.Vector3 {\n worldToNormalizedViewportCoordinates(camera, position3D, out);\n\n const { renderSize } = worldToViewportVars;\n renderer.getSize(renderSize);\n\n const canvas = renderer.domElement;\n const { width: canvasWidth, height: canvasHeight } = canvas.getBoundingClientRect();\n\n out.x = Math.round(out.x * canvasWidth);\n out.y = Math.round(out.y * canvasHeight);\n return out;\n}\n","module.exports = require(\"lodash/cloneDeep\");","module.exports = require(\"geo-three\");","module.exports = require(\"@cognite/sdk-core\");","/*!\n * Copyright 2021 Cognite AS\n */\n\nexport { worldToViewportCoordinates, worldToNormalizedViewportCoordinates } from './worldToViewport';\nexport { BoundingBoxClipper } from './BoundingBoxClipper';\n\nexport { assertNever, EventTrigger } from '@reveal/utilities';\n\nexport { LoadingState } from '@reveal/cad-geometry-loaders';\n\nexport { LocalModelIdentifier, CdfModelIdentifier } from '@reveal/modeldata-api';\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nexport class BoundingBoxClipper {\n private readonly _box: THREE.Box3;\n private readonly _clippingPlanes: THREE.Plane[] = [\n new THREE.Plane(),\n new THREE.Plane(),\n new THREE.Plane(),\n new THREE.Plane(),\n new THREE.Plane(),\n new THREE.Plane()\n ];\n\n constructor(box?: THREE.Box3) {\n this._box = box || new THREE.Box3();\n this.updatePlanes();\n }\n\n set minX(x: number) {\n this._box.min.x = x;\n this.updatePlanes();\n }\n\n get minX(): number {\n return this._box.min.x;\n }\n\n set minY(y: number) {\n this._box.min.y = y;\n this.updatePlanes();\n }\n\n get minY(): number {\n return this._box.min.y;\n }\n\n set minZ(z: number) {\n this._box.min.z = z;\n this.updatePlanes();\n }\n\n get minZ(): number {\n return this._box.min.z;\n }\n\n set maxX(x: number) {\n this._box.max.x = x;\n this.updatePlanes();\n }\n\n get maxX(): number {\n return this._box.max.x;\n }\n\n set maxY(y: number) {\n this._box.max.y = y;\n this.updatePlanes();\n }\n\n get maxY(): number {\n return this._box.max.y;\n }\n\n set maxZ(z: number) {\n this._box.max.z = z;\n this.updatePlanes();\n }\n\n get maxZ(): number {\n return this._box.max.z;\n }\n\n private updatePlanes() {\n this._clippingPlanes[0].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(1, 0, 0),\n new THREE.Vector3(this.minX, 0, 0)\n );\n this._clippingPlanes[1].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(-1, 0, 0),\n new THREE.Vector3(this.maxX, 0, 0)\n );\n this._clippingPlanes[2].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(0, 1, 0),\n new THREE.Vector3(0, this.minY, 0)\n );\n this._clippingPlanes[3].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(0, -1, 0),\n new THREE.Vector3(0, this.maxY, 0)\n );\n this._clippingPlanes[4].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(0, 0, 1),\n new THREE.Vector3(0, 0, this.minZ)\n );\n this._clippingPlanes[5].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(0, 0, -1),\n new THREE.Vector3(0, 0, this.maxZ)\n );\n }\n\n get clippingPlanes(): THREE.Plane[] {\n return this._clippingPlanes;\n }\n}\n","module.exports = require(\"lodash/debounce\");","module.exports = require(\"lodash/range\");","module.exports = require(\"comlink\");","module.exports = require(\"loglevel\");","module.exports = require(\"skmeans\");","module.exports = require(\"lodash/merge\");","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { assertNever, EventTrigger } from '@reveal/core/utilities';\n\n/**\n * Base class for tools attaching to a {@see Cognite3DViewer}.\n */\nexport abstract class Cognite3DViewerToolBase {\n private readonly _disposedEvent = new EventTrigger<() => void>();\n private _disposed = false;\n\n /**\n * Registers an event handler that is triggered when {@see Cognite3DViewerToolBase.dispose} is\n * called.\n * @param event\n * @param handler\n * @internal\n */\n on(event: 'disposed', handler: () => void): void {\n switch (event) {\n case 'disposed':\n this._disposedEvent.subscribe(handler);\n break;\n\n default:\n assertNever(event);\n }\n }\n\n /**\n * Unregisters an event handler for the 'disposed'-event.\n * @param event\n * @param handler\n */\n off(event: 'disposed', handler: () => void): void {\n switch (event) {\n case 'disposed':\n this._disposedEvent.unsubscribe(handler);\n break;\n\n default:\n assertNever(event);\n }\n }\n\n /**\n * Disposes the element and triggeres the 'disposed' event before clearing the list\n * of dipose-listeners.\n */\n dispose(): void {\n if (this._disposed) {\n throw new Error('Already disposed');\n }\n this._disposed = true;\n this._disposedEvent.fire();\n this._disposedEvent.unsubscribeAll();\n }\n\n /**\n * Throws an error if the instance has been disposed.\n */\n protected ensureNotDisposed(): void {\n if (this._disposed) {\n throw new Error('The tool has been disposed');\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport range from 'lodash/range';\n\ntype SimpleGrid2DElement<T> = {\n bounds: THREE.Box2;\n element: T;\n};\n\n/**\n * Data structure that splits a 2D region into cells where each cell can contain zero to many\n * elements. Elements can be stored in several cells. This data structure make overlap lookups\n * efficient.\n *\n * Note! This class is tailored for usage with {@link HtmlOverlayTool} and has a few restrictions\n * and assumptions associated with the usage. If used elsewhere, take care as to how this affects\n * performance and behaviour.\n */\nexport class BucketGrid2D<T> {\n private readonly _dimensions: [width: number, height: number];\n private readonly _bounds: THREE.Box2;\n private readonly _cells: SimpleGrid2DElement<T>[][];\n /**\n * Holds elements that has been removed from the collection using {@link removeOverlappingElements}.\n * This is used to avoid expensive re-allocations of cells when removing elements.\n */\n private readonly _removedElements = new Set<T>();\n\n constructor(bounds: THREE.Box2, dimensions: [width: number, height: number]) {\n this._dimensions = dimensions;\n this._cells = range(0, dimensions[0] * dimensions[1]).map(() => new Array<SimpleGrid2DElement<T>>());\n this._bounds = bounds;\n }\n\n insert(bounds: THREE.Box2, element: T): void {\n if (!this._bounds.intersectsBox(bounds)) {\n throw new Error('Element to be added must be partially inside grid');\n }\n if (this._removedElements.has(element)) {\n throw new Error('Re-adding previously taken elements is currently not supported');\n }\n\n for (const cell of this.cellsIntersecting(bounds)) {\n cell.push({ bounds, element });\n }\n }\n\n *overlappingElements(bounds: THREE.Box2): Generator<T> {\n if (!this._bounds.intersectsBox(bounds)) {\n return;\n }\n\n const visitedElements = new Set<T>();\n for (const cell of this.cellsIntersecting(bounds)) {\n for (const candidateElement of cell) {\n if (\n !visitedElements.has(candidateElement.element) &&\n !this._removedElements.has(candidateElement.element) &&\n bounds.intersectsBox(candidateElement.bounds)\n ) {\n visitedElements.add(candidateElement.element);\n yield candidateElement.element;\n }\n }\n }\n }\n\n *removeOverlappingElements(bounds: THREE.Box2): Generator<T> {\n if (!this._bounds.intersectsBox(bounds)) {\n return;\n }\n\n for (const cell of this.cellsIntersecting(bounds)) {\n for (let i = 0; i < cell.length; i++) {\n const candidateElement = cell[i];\n if (!this._removedElements.has(candidateElement.element) && bounds.intersectsBox(candidateElement.bounds)) {\n this._removedElements.add(candidateElement.element);\n yield candidateElement.element;\n }\n }\n }\n }\n\n private *cellsIntersecting(bounds: THREE.Box2): Generator<SimpleGrid2DElement<T>[]> {\n const { min, max } = this._bounds;\n const dimX = this._dimensions[0];\n const dimY = this._dimensions[1];\n const relativeBoundsMinX = (bounds.min.x - min.x) / (max.x - min.x);\n const relativeBoundsMaxX = (bounds.max.x - min.x) / (max.x - min.x);\n const relativeBoundsMinY = (bounds.min.y - min.y) / (max.y - min.y);\n const relativeBoundsMaxY = (bounds.max.y - min.y) / (max.y - min.y);\n\n const clamp = THREE.MathUtils.clamp;\n const minI = clamp(Math.floor(dimX * relativeBoundsMinX), 0, dimX - 1);\n const maxI = clamp(Math.floor(dimX * relativeBoundsMaxX), 0, dimX - 1);\n const minJ = clamp(Math.floor(dimY * relativeBoundsMinY), 0, dimY - 1);\n const maxJ = clamp(Math.floor(dimY * relativeBoundsMaxY), 0, dimY - 1);\n for (let j = minJ; j <= maxJ; ++j) {\n for (let i = minI; i <= maxI; ++i) {\n yield this._cells[j * dimX + i];\n }\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { Cognite3DViewerToolBase } from '../Cognite3DViewerToolBase';\nimport { BucketGrid2D } from './BucketGrid2D';\n\nimport { MetricsLogger } from '@reveal/metrics';\nimport { assertNever, worldToViewportCoordinates } from '@reveal/core/utilities';\nimport { Cognite3DViewer, DisposedDelegate, SceneRenderedDelegate } from '@reveal/core';\nimport debounce from 'lodash/debounce';\n\n/**\n * Callback that is triggered whenever the 2D position of an overlay is updated\n * in {@link HtmlOverlayTool}.\n */\nexport type HtmlOverlayPositionUpdatedDelegate = (\n element: HTMLElement,\n position2D: THREE.Vector2,\n position3D: THREE.Vector3,\n distanceToCamera: number,\n userData: any\n) => void;\n\n/**\n * Callback that is triggered when a set of overlays are clustered together in\n * {@link HtmlOverlayTool}.\n */\nexport type HtmlOverlayCreateClusterDelegate = (\n overlayElements: {\n htmlElement: HTMLElement;\n userData: any;\n }[]\n) => HTMLElement;\n\n/**\n * Options for an overlay added using {@link HtmlOverlayTool.add}.\n */\nexport type HtmlOverlayOptions = {\n /**\n * Callback that is triggered whenever the position of the overlay is updated. Optional.\n */\n positionUpdatedCallback?: HtmlOverlayPositionUpdatedDelegate;\n /**\n * Optional user specified data that is provided to the {@link HtmlOverlayCreateClusterDelegate} and\n * {@link HtmlOverlayPositionUpdatedDelegate}.\n */\n userData?: any;\n};\n\n/**\n * Controls how close overlay elements are clustered together.\n */\nexport type HtmlOverlayToolClusteringOptions = {\n /**\n * Currently only 'overlapInScreenSpace' is supported. In this mode,\n * overlays are clustered together into a single element as defined by\n * the {@link createClusterElementCallback} and hidden when they overlap\n * in screen space. The composite element is placed at the midpoint of\n * all clustered elements.\n *\n * Clustered elements are faded in/out using CSS styling `transition`,\n * `opacity` and `visibility`.\n */\n mode: 'overlapInScreenSpace';\n\n /**\n * Callback that is triggered when a set of overlays are clustered together\n * to create a \"composite\" element as a placeholder for the clustered elements.\n * Note that this callback will be triggered every frame for each cluster so it\n * must be performant.\n */\n createClusterElementCallback: HtmlOverlayCreateClusterDelegate;\n};\n\nexport type HtmlOverlayToolOptions = {\n clusteringOptions?: HtmlOverlayToolClusteringOptions;\n};\n\ntype HtmlOverlayElement = {\n position3D: THREE.Vector3;\n options: HtmlOverlayOptions;\n\n state: {\n visible: boolean;\n position2D: THREE.Vector2;\n width: number;\n height: number;\n };\n};\n\n/**\n * Manages HTMLoverlays for {@see Cognite3DViewer}. Attaches HTML elements to a\n * 3D position and updates its position/visibility as user moves the camera. This is\n * useful to create HTML overlays to highlight information about key positions in the 3D model.\n *\n * Attached elements *must* have CSS style 'position: absolute'. It's also recommended\n * in most cases to have styles 'pointer-events: none' and 'touch-action: none' to avoid\n * interfering with 3D navigation. Consider also applying 'transform: translate(-50%, -50%)'\n * to anchor the center of the element rather than the top-left corner. In some cases the\n * `zIndex`-attribute is necessary for the element to appear on top of the viewer.\n *\n * @example\n * ```js\n * const el = document.createElement('div');\n * el.style.position = 'absolute'; // Required!\n * // Anchor to center of element\n * el.style.transform = 'translate(-50%, -50%)';\n * // Avoid being target for events\n * el.style.pointerEvents = 'none;\n * el.style.touchAction = 'none';\n * // Render in front of other elements\n * el.style.zIndex = 10;\n *\n * el.style.color = 'red';\n * el.innerHtml = '<h1>Overlay</h1>';\n *\n * const overlayTool = new HtmlOverlayTool(viewer);\n * overlayTool.add(el, new THREE.Vector3(10, 10, 10));\n * // ...\n * overlayTool.remove(el);\n * // or, to remove all attached elements\n * overlayTool.clear();\n *\n * // detach the tool from the viewer\n * overlayTool.dispose();\n * ```\n */\nexport class HtmlOverlayTool extends Cognite3DViewerToolBase {\n private readonly _viewer: Cognite3DViewer;\n private readonly _options: HtmlOverlayToolOptions;\n private readonly _htmlOverlays: Map<HTMLElement, HtmlOverlayElement> = new Map();\n private readonly _compositeOverlays: HTMLElement[] = [];\n\n private readonly _onSceneRenderedHandler: SceneRenderedDelegate;\n private readonly _onViewerDisposedHandler: DisposedDelegate;\n // Allocate variables needed for processing once to avoid allocations\n private readonly _preallocatedVariables = {\n camPos: new THREE.Vector3(),\n camNormal: new THREE.Vector3(),\n point: new THREE.Vector3(),\n nearPlane: new THREE.Plane(),\n farPlane: new THREE.Plane(),\n position2D: new THREE.Vector2()\n };\n\n private readonly scheduleUpdate: () => void;\n\n private get viewerDomElement(): HTMLElement {\n return this._viewer.domElement;\n }\n\n private get viewerCamera(): THREE.PerspectiveCamera {\n return this._viewer.getCamera();\n }\n\n private get viewerRenderer(): THREE.WebGLRenderer {\n return this._viewer.renderer;\n }\n\n constructor(viewer: Cognite3DViewer, options?: HtmlOverlayToolOptions) {\n super();\n\n this._onSceneRenderedHandler = this.onSceneRendered.bind(this);\n this._onViewerDisposedHandler = this.onViewerDisposed.bind(this);\n this._options = options ?? {};\n this._viewer = viewer;\n this._viewer.on('sceneRendered', this._onSceneRenderedHandler);\n this._viewer.on('disposed', this._onViewerDisposedHandler);\n\n this.scheduleUpdate = debounce(() => this.forceUpdate(), 20);\n\n MetricsLogger.trackCreateTool('HtmlOverlayTool');\n }\n\n /**\n * Returns all added HTML elements along with their 3D positions.\n */\n get elements(): { element: HTMLElement; position3D: THREE.Vector3 }[] {\n return Array.from(this._htmlOverlays.entries()).map(([element, info]) => {\n return { element, position3D: info.position3D };\n });\n }\n\n /**\n * Removes all elements and detaches from the viewer.\n * @override\n */\n dispose(): void {\n this._viewer.off('sceneRendered', this._onSceneRenderedHandler);\n this._viewer.off('disposed', this._onViewerDisposedHandler);\n this.clear();\n super.dispose();\n }\n\n /**\n * Registers a HTML overlay that will be updated on rendering.\n *\n * @param htmlElement\n * @param position3D\n * @param options\n */\n add(htmlElement: HTMLElement, position3D: THREE.Vector3, options: HtmlOverlayOptions = {}): void {\n this.ensureNotDisposed();\n\n if (this.viewerDomElement.contains(htmlElement)) {\n throw new Error(`Element is already attached to viewer`);\n }\n\n htmlElement.style.visibility = 'hidden';\n\n // Note! Must be part of DOM tree before we do getComputedStyle(), so add before check\n this.viewerDomElement.appendChild(htmlElement);\n const style = getComputedStyle(htmlElement);\n if (style.position !== 'absolute') {\n this.viewerDomElement.removeChild(htmlElement);\n throw new Error(`htmlElement style must have a position of absolute. but was '${style.position}'`);\n }\n\n const element: HtmlOverlayElement = {\n position3D,\n options,\n state: {\n position2D: new THREE.Vector2(),\n width: -1,\n height: -1,\n visible: true\n }\n };\n this._htmlOverlays.set(htmlElement, element);\n\n this.scheduleUpdate();\n }\n\n /**\n * Removes a overlay and removes it from the DOM.\n * @param htmlElement\n */\n remove(htmlElement: HTMLElement): void {\n this.ensureNotDisposed();\n if (!this.viewerDomElement.contains(htmlElement) || !this._htmlOverlays.has(htmlElement)) {\n throw new Error(`Element is not attached to viewer`);\n }\n this.viewerDomElement.removeChild(htmlElement);\n this._htmlOverlays.delete(htmlElement);\n }\n\n /**\n * Removes all attached HTML overlay elements.\n */\n clear(): void {\n const overlays = Array.from(this._htmlOverlays.keys());\n for (const element of overlays) {\n this.remove(element);\n }\n }\n\n /**\n * Updates positions of all overlays. This is automatically managed and there\n * shouldn't be any reason to trigger this unless the attached elements are\n * modified externally.\n *\n * Calling this function often might cause degraded performance.\n */\n forceUpdate(): void {\n this.ensureNotDisposed();\n this.cleanupClusterElements();\n if (this._htmlOverlays.size === 0) {\n return;\n }\n this.updateNewElementSizes();\n\n const camera = this.viewerCamera;\n const renderer = this.viewerRenderer;\n const { camPos, camNormal, point, nearPlane, farPlane, position2D } = this._preallocatedVariables;\n\n // Determine near/far plane to cull based on distance. Note! We don't cull outside the \"walls\"\n // of the frustum to allow HTML elements that are partially outside the edges. The HTML clipping\n // will fix this anyways\n camera.getWorldPosition(camPos);\n camera.getWorldDirection(camNormal);\n point.copy(camPos).addScaledVector(camNormal, camera.near);\n nearPlane.setFromNormalAndCoplanarPoint(camNormal, point);\n point.copy(camPos).addScaledVector(camNormal, camera.far);\n farPlane.setFromNormalAndCoplanarPoint(camNormal, point);\n\n this._htmlOverlays.forEach((element, htmlElement) => {\n const {\n position3D,\n options: { positionUpdatedCallback, userData },\n state\n } = element;\n\n const insideCameraPlanes =\n nearPlane.distanceToPoint(position3D) >= 0.0 && farPlane.distanceToPoint(position3D) <= 0.0;\n // TODO 2021-11-19 larsmoa: Replace worldToViewportCoordinates() with something that doesn't cause\n // canvas.getClientBoundingRect() to be called when PR #1700 is done.\n // https://github.com/cognitedata/reveal/pull/1700\n const { x, y } = worldToViewportCoordinates(renderer, camera, position3D);\n\n if (insideCameraPlanes) {\n state.position2D.set(x, y);\n state.visible = true;\n } else {\n // Outside frustum - hide point\n state.visible = false;\n }\n\n if (positionUpdatedCallback) {\n position2D.set(x, y);\n const distanceToCamera = camPos.distanceTo(position3D);\n positionUpdatedCallback(htmlElement, position2D, position3D, distanceToCamera, userData);\n }\n });\n this.clusterElements();\n this.commitDOMChanges();\n }\n\n /**\n * Update size of new elements. This is only done once as this causes\n * layout to be invalidated which is an expensive operation.\n */\n private updateNewElementSizes() {\n this._htmlOverlays.forEach((element, htmlElement) => {\n if (element.state.width === -1) {\n const clientRect = htmlElement.getBoundingClientRect();\n element.state.width = clientRect.width;\n element.state.height = clientRect.height;\n }\n });\n }\n\n private commitDOMChanges() {\n const canvas = this.viewerRenderer.domElement;\n // Compute once as updating styles below will cause (unnecessary)\n // recomputation which slows down the process\n const offsetLeft = canvas.offsetLeft;\n const offsetTop = canvas.offsetTop;\n\n this._htmlOverlays.forEach((element, htmlElement) => {\n const { state } = element;\n htmlElement.style.left = `${state.position2D.x + offsetLeft}px`;\n htmlElement.style.top = `${state.position2D.y + offsetTop}px`;\n\n if (state.visible && htmlElement.style.visibility !== 'visible') {\n fadeIn(htmlElement);\n } else if (!state.visible && htmlElement.style.visibility !== 'hidden') {\n fadeOut(htmlElement);\n }\n });\n\n this._compositeOverlays.forEach(htmlElement => {\n this.viewerDomElement.appendChild(htmlElement);\n });\n }\n\n private clusterElements() {\n const options = this._options.clusteringOptions;\n if (options === undefined) {\n return;\n }\n\n switch (options.mode) {\n case 'overlapInScreenSpace':\n this.clusterByOverlapInScreenSpace(options.createClusterElementCallback);\n break;\n\n default:\n assertNever(options.mode, `Unsupported clustering mode: '${options.mode}`);\n }\n }\n\n private cleanupClusterElements(): void {\n this._compositeOverlays.forEach(element => {\n this.viewerDomElement.removeChild(element);\n });\n this._compositeOverlays.splice(0);\n }\n\n private clusterByOverlapInScreenSpace(createClusterElementCallback: HtmlOverlayCreateClusterDelegate) {\n type Element = HtmlOverlayElement & { htmlElement: HTMLElement };\n\n const canvas = this.viewerRenderer.domElement;\n const canvasBounds = domRectToBox2(canvas.getBoundingClientRect());\n const canvasSize = canvasBounds.getSize(new THREE.Vector2());\n canvasBounds.set(new THREE.Vector2(0, 0), canvasSize);\n // Compute once as updating styles below will cause (unnecessary)\n // recomputation which slows down the process\n\n const grid = new BucketGrid2D<Element>(canvasBounds, [10, 10]);\n for (const [htmlElement, element] of this._htmlOverlays.entries()) {\n const { state } = element;\n const elementBounds = createElementBounds(element);\n if (!state.visible || !elementBounds.intersectsBox(canvasBounds)) {\n continue;\n }\n grid.insert(elementBounds, { htmlElement, ...element });\n }\n\n const elementBounds = new THREE.Box2();\n const clusterMidpoint = new THREE.Vector2();\n for (const element of this._htmlOverlays.values()) {\n const { state } = element;\n createElementBounds(element, elementBounds);\n if (!state.visible || !elementBounds.intersectsBox(canvasBounds)) {\n continue;\n }\n\n const cluster = Array.from(grid.removeOverlappingElements(elementBounds));\n if (cluster.length > 1) {\n const midpoint = cluster\n .reduce((position, element) => position.add(element.state.position2D), clusterMidpoint.set(0, 0))\n .divideScalar(cluster.length);\n const compositeElement = createClusterElementCallback(\n cluster.map(element => ({ htmlElement: element.htmlElement, userData: element.options.userData }))\n );\n // Hide all elements in cluster\n cluster.forEach(element => (element.state.visible = false));\n // ... and replace with a composite\n this.addComposite(compositeElement, midpoint);\n }\n }\n }\n\n private addComposite(htmlElement: HTMLElement, position: THREE.Vector2) {\n const canvas = this.viewerRenderer.domElement;\n htmlElement.style.visibility = 'visible';\n htmlElement.style.left = `${position.x + canvas.offsetLeft}px`;\n htmlElement.style.top = `${position.y + canvas.offsetTop}px`;\n this._compositeOverlays.push(htmlElement);\n }\n\n private onSceneRendered(): void {\n this.forceUpdate();\n }\n\n private onViewerDisposed(): void {\n this.dispose();\n }\n}\n\n/**\n * Hides an element and applies a CSS transition.\n */\nfunction fadeOut(htmlElement: HTMLElement) {\n // https://stackoverflow.com/a/4861306\n htmlElement.style.visibility = 'hidden';\n htmlElement.style.opacity = '0';\n htmlElement.style.transition = 'visibility 0s 0.2s, opacity 0.2s linear';\n}\n\n/**\n * Shows an element and applies a CSS transition.\n */\nfunction fadeIn(htmlElement: HTMLElement) {\n // https://stackoverflow.com/a/4861306\n htmlElement.style.visibility = 'visible';\n htmlElement.style.opacity = '1';\n htmlElement.style.transition = 'opacity 0.2s linear';\n}\n\nfunction domRectToBox2(rect: DOMRect, out?: THREE.Box2): THREE.Box2 {\n out = out ?? new THREE.Box2();\n out.min.set(rect.left, rect.top);\n out.max.set(rect.right, rect.bottom);\n return out;\n}\n\nfunction createElementBounds(element: HtmlOverlayElement, out?: THREE.Box2) {\n const { state } = element;\n out = out ?? new THREE.Box2();\n out.min.set(state.position2D.x, state.position2D.y);\n out.max.set(state.position2D.x + state.width, state.position2D.y + state.height);\n return out;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport { Cognite3DModel } from '@reveal/core';\nimport { Cognite3DViewerToolBase } from './Cognite3DViewerToolBase';\nimport { MetricsLogger } from '@reveal/metrics';\n\nexport class ExplodedViewTool extends Cognite3DViewerToolBase {\n private readonly _cadModel: Cognite3DModel;\n private _treeBoundingBoxdata!: Promise<{ treeIndex: number; direction: THREE.Vector3; transform: THREE.Matrix4 }[]>;\n private readonly _rootTreeIndex: number;\n\n public get readyPromise(): Promise<void> {\n return this._treeBoundingBoxdata.then();\n }\n\n constructor(treeIndex: number, cadModel: Cognite3DModel) {\n super();\n\n this._cadModel = cadModel;\n this._rootTreeIndex = treeIndex;\n\n this.preloadBoundingBoxData(cadModel, treeIndex);\n\n MetricsLogger.trackCreateTool('ExplodedViewTool');\n }\n\n public async expand(expandRadius: number): Promise<void> {\n const expandData = await this._treeBoundingBoxdata;\n\n await Promise.all(\n expandData.map(({ treeIndex, direction, transform }) => {\n if (expandRadius === 0) {\n this._cadModel.resetNodeTransformByTreeIndex(treeIndex);\n return Promise.resolve(0);\n }\n\n transform.setPosition(direction.x * expandRadius, direction.y * expandRadius, direction.z * expandRadius);\n\n return this._cadModel.setNodeTransformByTreeIndex(treeIndex, transform);\n })\n );\n }\n\n public reset(): void {\n this._cadModel.resetNodeTransformByTreeIndex(this._rootTreeIndex, true);\n }\n\n private preloadBoundingBoxData(cadModel: Cognite3DModel, treeIndex: number) {\n const rootTreeIndexBoundingBox = cadModel\n .getBoundingBoxByTreeIndex(treeIndex)\n .then(rootBoundingBox => rootBoundingBox.getCenter(new THREE.Vector3()));\n\n const subTreeBoundingBoxes = cadModel\n .getSubtreeTreeIndices(treeIndex)\n .then(subTreeIndices => {\n if (subTreeIndices.count > 1000) {\n throw new Error(`Subtree size of ${subTreeIndices.count} is too large (max size = 1000)`);\n }\n\n return subTreeIndices;\n })\n .then(subTreeIndices => {\n return Promise.all(\n subTreeIndices.toArray().map(async subTreeIndex => {\n // TODO 2021-06-09 larsmoa: We could make this a lot more efficient by\n // batching bounding box lookups together to one/a few API calls rather than\n // one per node\n const subTreeBox = await cadModel.getBoundingBoxByTreeIndex(subTreeIndex);\n return {\n subTreeIndex: subTreeIndex,\n subTreeIndexBoundingBoxCenter: subTreeBox.getCenter(new THREE.Vector3())\n };\n })\n );\n });\n\n this._treeBoundingBoxdata = Promise.all([rootTreeIndexBoundingBox, subTreeBoundingBoxes])\n .then(data => {\n const [rootCenter, subTreeCenters] = data;\n return subTreeCenters.map(({ subTreeIndex, subTreeIndexBoundingBoxCenter }) => {\n return {\n treeIndex: subTreeIndex,\n direction: new THREE.Vector3().subVectors(subTreeIndexBoundingBoxCenter, rootCenter),\n transform: new THREE.Matrix4()\n };\n });\n })\n .then(async payloads => {\n await Promise.all(\n payloads.map(payload => {\n return cadModel.setNodeTransformByTreeIndex(payload.treeIndex, payload.transform);\n })\n );\n return payloads;\n });\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { Cognite3DViewer } from '@reveal/core';\nimport { DisposedDelegate } from './types';\n\nimport { Cognite3DViewerToolBase } from './Cognite3DViewerToolBase';\n\nexport class DebugCameraTool extends Cognite3DViewerToolBase {\n private readonly _viewer: Cognite3DViewer;\n private readonly _onViewerDisposedHandler: DisposedDelegate;\n private _cameraHelper?: THREE.CameraHelper;\n\n private get viewerCamera(): THREE.PerspectiveCamera {\n return this._viewer.getCamera();\n }\n\n constructor(viewer: Cognite3DViewer) {\n super();\n\n this._onViewerDisposedHandler = this.onViewerDisposed.bind(this);\n this._viewer = viewer;\n this._viewer.on('disposed', this._onViewerDisposedHandler);\n }\n\n /**\n * Removes all elements and detaches from the viewer.\n * @override\n */\n dispose(): void {\n this._viewer.off('disposed', this._onViewerDisposedHandler);\n super.dispose();\n }\n\n showCameraHelper(): void {\n this.hideCameraHelper();\n this._cameraHelper = new THREE.CameraHelper(this.viewerCamera.clone() as THREE.PerspectiveCamera);\n this._viewer.addObject3D(this._cameraHelper);\n }\n\n hideCameraHelper(): void {\n if (this._cameraHelper !== undefined) {\n this._viewer.removeObject3D(this._cameraHelper);\n this._cameraHelper = undefined;\n }\n }\n\n private onViewerDisposed(): void {\n this.dispose();\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\n/**\n * Configuration of {@link AxisViewTool}.\n */\nexport type AxisBoxConfig = {\n /**\n * Size in pixels of the axis tool.\n */\n size?: number;\n /**\n * Position, either absolute or relative.\n */\n position?: AbsolutePosition | RelativePosition;\n /**\n * How long the camera animation lasts when\n * clicking a face of the orientation box.\n */\n animationSpeed?: number;\n /**\n * Configuration for each of the faces of the orientation box.\n * Note that Reveal uses a right-handed Y up coordinate system,\n * which might differ from the original model space. To account\n * for this, you might want to reassign labels of the faces.\n */\n faces?: {\n xPositiveFace?: AxisBoxFaceConfig;\n xNegativeFace?: AxisBoxFaceConfig;\n yPositiveFace?: AxisBoxFaceConfig;\n yNegativeFace?: AxisBoxFaceConfig;\n zPositiveFace?: AxisBoxFaceConfig;\n zNegativeFace?: AxisBoxFaceConfig;\n };\n /**\n * Configuration of the compass \"base\" of the tool.\n */\n compass?: AxisBoxCompassConfig;\n};\n\n/**\n * Absolute position in pixels.\n */\nexport type AbsolutePosition = {\n xAbsolute: number;\n yAbsolute: number;\n};\n\n/**\n * Relative position from a corner of the viewer\n * and a given padding.\n */\nexport type RelativePosition = {\n corner: Corner;\n padding: THREE.Vector2;\n};\n\n/**\n * Configuration of each face of the orientation box.\n */\nexport type AxisBoxFaceConfig = {\n /**\n * Label of the respective face, e.g. 'X' or 'Right'.\n */\n label?: string;\n fontSize?: number;\n fontColor?: THREE.Color;\n outlineSize?: number;\n outlineColor?: THREE.Color;\n faceColor?: THREE.Color;\n};\n\n/**\n * Configuration of the compass.\n */\nexport type AxisBoxCompassConfig = {\n /**\n * Label of the orientation indicator. Defaults\n * to 'N' for north.\n */\n ringLabel?: string;\n /**\n * Offset in radians of the orientation indicator.\n */\n labelDelta?: number;\n fontSize?: number;\n fontColor?: THREE.Color;\n tickColor?: THREE.Color;\n};\n\n/**\n * A corner of the viewer.\n */\nexport enum Corner {\n TopRight,\n TopLeft,\n BottomLeft,\n BottomRight\n}\n\nexport const defaultAxisBoxCompassConfig: AxisBoxCompassConfig = {\n ringLabel: 'N',\n labelDelta: Math.PI,\n fontSize: undefined,\n fontColor: new THREE.Color(0xff0000),\n tickColor: new THREE.Color(0x949494)\n};\n\nexport const defaultFaceConfig: AxisBoxFaceConfig = {\n label: '',\n fontSize: undefined,\n fontColor: new THREE.Color(0x333333),\n outlineSize: undefined,\n outlineColor: new THREE.Color(0x333333),\n faceColor: new THREE.Color(0x949494)\n};\n\nexport const defaultAxisBoxConfig: Required<AxisBoxConfig> = {\n size: 128,\n position: {\n corner: Corner.BottomRight,\n padding: new THREE.Vector2()\n },\n animationSpeed: 200,\n faces: {\n xPositiveFace: {\n ...defaultFaceConfig,\n label: 'Right'\n },\n xNegativeFace: {\n ...defaultFaceConfig,\n label: 'Left'\n },\n yPositiveFace: {\n ...defaultFaceConfig,\n label: 'Up'\n },\n yNegativeFace: {\n ...defaultFaceConfig,\n label: 'Down'\n },\n zPositiveFace: {\n ...defaultFaceConfig,\n label: 'Front'\n },\n zNegativeFace: {\n ...defaultFaceConfig,\n label: 'Back'\n }\n },\n compass: defaultAxisBoxCompassConfig\n};\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport cloneDeep from 'lodash/cloneDeep';\nimport merge from 'lodash/merge';\nimport TWEEN from '@tweenjs/tween.js';\n\nimport { Cognite3DViewerToolBase } from '../Cognite3DViewerToolBase';\nimport {\n AxisBoxConfig,\n defaultAxisBoxConfig,\n AxisBoxFaceConfig,\n Corner,\n AbsolutePosition,\n RelativePosition\n} from './types';\nimport ComboControls from '@reveal/camera-manager';\nimport { Cognite3DViewer } from '@reveal/core';\nimport { MetricsLogger } from '@reveal/metrics';\n\nexport class AxisViewTool extends Cognite3DViewerToolBase {\n private readonly _layoutConfig: Required<AxisBoxConfig>;\n\n private readonly _boxFaceGeometry: THREE.PlaneGeometry;\n\n private readonly _viewer: Cognite3DViewer;\n\n private readonly _axisGroup: THREE.Group;\n\n private readonly _interactiveObjects: THREE.Mesh[];\n private readonly _raycastCamera: THREE.OrthographicCamera;\n private readonly _raycaster: THREE.Raycaster;\n\n private readonly _screenPosition: THREE.Vector2;\n\n private readonly _disposeClickDiv: () => void;\n\n private _dynamicUpdatePosition = () => {};\n private readonly _updateClickDiv = () => {};\n\n constructor(viewer: Cognite3DViewer, config?: AxisBoxConfig) {\n super();\n\n this._screenPosition = new THREE.Vector2();\n this._boxFaceGeometry = new THREE.PlaneGeometry(0.85, 0.85, 1, 1);\n\n this._raycastCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);\n this._raycaster = new THREE.Raycaster();\n\n this._viewer = viewer;\n\n this._layoutConfig = merge(cloneDeep(defaultAxisBoxConfig), config);\n\n this._axisGroup = new THREE.Group();\n this._interactiveObjects = this.createAxisCross(this._axisGroup);\n\n [this._updateClickDiv, this._disposeClickDiv] = this.createClickDiv(viewer);\n this.addAxisBoxToViewer(this._axisGroup, this._layoutConfig.position!);\n\n MetricsLogger.trackCreateTool('AxisViewTool');\n }\n\n public dispose(): void {\n super.dispose();\n this._viewer.removeUiObject(this._axisGroup);\n this._disposeClickDiv();\n }\n\n private createClickDiv(viewer: Cognite3DViewer) {\n const canvasElement = viewer.domElement.querySelector('canvas');\n if (canvasElement === null) {\n throw new Error('Could not find canvas');\n }\n const divElement = document.createElement('div');\n divElement.style.position = 'absolute';\n divElement.style.height = `${this._layoutConfig.size}px`;\n divElement.style.width = `${this._layoutConfig.size}px`;\n divElement.style.zIndex = '1';\n\n let xMouse = 0;\n let yMouse = 0;\n\n divElement.addEventListener('mousedown', event => {\n const mouseDownEvent = new MouseEvent('mousedown', {\n clientX: event.clientX,\n clientY: event.clientY,\n button: event.button\n });\n xMouse = event.clientX;\n yMouse = event.clientY;\n viewer.renderer.domElement.dispatchEvent(mouseDownEvent);\n });\n\n divElement.addEventListener('mousemove', event => {\n const mouseMoveEvent = new MouseEvent('mousemove', {\n clientX: event.clientX,\n clientY: event.clientY,\n button: event.button\n });\n viewer.renderer.domElement.dispatchEvent(mouseMoveEvent);\n });\n\n divElement.addEventListener('contextmenu', event => event.preventDefault());\n\n divElement.addEventListener('mouseup', event => {\n const mouseUpEvent = new MouseEvent('mouseup', {\n clientX: event.clientX,\n clientY: event.clientY,\n button: event.button\n });\n\n const rect = viewer.domElement.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n if (Math.abs(xMouse - event.clientX) + Math.abs(yMouse - event.clientY) <= 10 && !this.handleClick(x, y, rect)) {\n viewer.renderer.domElement.dispatchEvent(mouseUpEvent);\n }\n });\n\n viewer.domElement.appendChild(divElement);\n\n return [\n () => {\n divElement.style.left = `${this._screenPosition.x}px`;\n divElement.style.bottom = `${this._screenPosition.y}px`;\n },\n () => {\n viewer.domElement.removeChild(divElement);\n }\n ];\n }\n\n private addAxisBoxToViewer(axisGroup: THREE.Group, position: AbsolutePosition | RelativePosition) {\n const size = this._layoutConfig.size;\n\n if (isAbsolute(position)) {\n this._screenPosition.x = position.xAbsolute;\n this._screenPosition.y = position.yAbsolute;\n } else {\n switch (position.corner) {\n case Corner.BottomRight:\n this._screenPosition.y = position.padding.y;\n\n this._dynamicUpdatePosition = () => {\n this._screenPosition.x = this._viewer.renderer.domElement.clientWidth - position.padding.x - size;\n };\n break;\n\n case Corner.TopRight:\n this._dynamicUpdatePosition = () => {\n this._screenPosition.x = this._viewer.renderer.domElement.clientWidth - position.padding.x - size;\n this._screenPosition.y = this._viewer.renderer.domElement.clientHeight - position.padding.y - size;\n };\n break;\n\n case Corner.TopLeft:\n this._screenPosition.x = position.padding.x;\n this._dynamicUpdatePosition = () => {\n this._screenPosition.y = this._viewer.renderer.domElement.clientHeight - position.padding.y - size;\n };\n break;\n\n case Corner.BottomLeft:\n this._screenPosition.x = position.padding.x;\n this._screenPosition.y = position.padding.y;\n break;\n default:\n throw new Error(`Unknown corner position for Axis Cross: Corner = ${position.corner}`);\n }\n this._dynamicUpdatePosition();\n }\n\n this._viewer.addUiObject(axisGroup, this._screenPosition, new THREE.Vector2(size, size));\n\n function isAbsolute(position: AbsolutePosition | RelativePosition): position is AbsolutePosition {\n return (\n (position as AbsolutePosition).xAbsolute !== undefined && (position as AbsolutePosition).yAbsolute !== undefined\n );\n }\n }\n\n private handleClick(xScreenPos: number, yScreenPos: number, boundingRect: DOMRect): boolean {\n const xNdc = (2 * (xScreenPos - this._screenPosition.x)) / this._layoutConfig.size - 1;\n const yNdc = (2 * (boundingRect.height - yScreenPos - this._screenPosition.y)) / this._layoutConfig.size - 1;\n this._raycaster.setFromCamera({ x: xNdc, y: yNdc }, this._raycastCamera);\n const rayOrigin = new THREE.Vector3(xNdc, yNdc, 1);\n const rayDirection = new THREE.Vector3(0, 0, -1).normalize();\n this._raycaster.set(rayOrigin, rayDirection);\n\n const intersects = this._raycaster.intersectObjects(this._interactiveObjects);\n\n if (!(intersects.length > 0)) return false;\n\n const targetPosition = intersects[0].object.position.clone().normalize();\n const targetUp = (intersects[0].object.userData.upVector as THREE.Vector3).clone();\n\n this.moveCameraTo(this._viewer.getCamera(), this._viewer.cameraControls, targetPosition, targetUp);\n\n return true;\n }\n\n private createAxisCross(axisGroup: THREE.Group) {\n const interactiveObjects = this.createBoxFaces();\n axisGroup.add(...interactiveObjects);\n\n const compass = this.createCompass();\n axisGroup.add(compass);\n\n this.setupTransformOnRender(axisGroup);\n\n return interactiveObjects;\n }\n\n private setupTransformOnRender(axisGroup: THREE.Group) {\n axisGroup.children[0].onBeforeRender = () => {\n this._dynamicUpdatePosition();\n axisGroup.quaternion.copy(this._viewer.getCamera().quaternion).invert();\n axisGroup.updateMatrixWorld();\n this._updateClickDiv();\n };\n }\n\n private createBoxFaces() {\n const facesConfig = this._layoutConfig.faces;\n\n const posXFace = this.createBoxFace(new THREE.Vector3(1, 0, 0), facesConfig.xPositiveFace!);\n const negXFace = this.createBoxFace(new THREE.Vector3(-1, 0, 0), facesConfig.xNegativeFace!);\n\n const posYFace = this.createBoxFace(\n new THREE.Vector3(0, 1, 0),\n facesConfig.yPositiveFace!,\n new THREE.Vector3(0, 0, -1)\n );\n const negYFace = this.createBoxFace(\n new THREE.Vector3(0, -1, 0),\n facesConfig.yNegativeFace!,\n new THREE.Vector3(0, 0, 1)\n );\n\n const posZFace = this.createBoxFace(new THREE.Vector3(0, 0, 1), facesConfig.zPositiveFace!);\n const negZFace = this.createBoxFace(new THREE.Vector3(0, 0, -1), facesConfig.zNegativeFace!);\n\n return [posXFace, negXFace, posYFace, negYFace, posZFace, negZFace];\n }\n\n private createCompass() {\n const compassPlaneGeometry = new THREE.PlaneGeometry(2.1, 2.1, 1, 1);\n const compass = new THREE.Mesh(\n compassPlaneGeometry,\n new THREE.MeshBasicMaterial({\n map: this.createCompassTexture(),\n side: THREE.DoubleSide,\n transparent: true\n })\n );\n\n const x = Math.sin(this._layoutConfig.compass.labelDelta!);\n const z = Math.cos(this._layoutConfig.compass.labelDelta!);\n\n compass.position.y = -0.5;\n compass.up.copy(new THREE.Vector3(x, 0, z));\n compass.lookAt(0, 0, 0);\n\n return compass;\n }\n\n private createCompassTexture() {\n const compassLayout = this._layoutConfig.compass;\n const textureSize = this._layoutConfig.size;\n\n const canvas = document.createElement('canvas');\n canvas.width = textureSize;\n canvas.height = textureSize;\n const context = canvas.getContext('2d')!;\n\n const halfSize = textureSize / 2;\n const radius = halfSize - halfSize / 4;\n\n const tickWidth = textureSize / 32;\n const tickSpace = textureSize / 8;\n\n context.strokeStyle = compassLayout.tickColor!.getStyle();\n context.lineWidth = textureSize / 16;\n context.setLineDash([tickWidth, tickSpace]);\n context.beginPath();\n context.arc(halfSize, halfSize, radius, 0, 2 * Math.PI);\n context.stroke();\n\n if (compassLayout.ringLabel && compassLayout.ringLabel.length > 0) {\n const fontSize = compassLayout.fontSize ?? textureSize / 5;\n context.font = `bold ${fontSize}px Arial`;\n context.textAlign = 'center';\n context.fillStyle = compassLayout.fontColor!.getStyle();\n context.fillText(compassLayout.ringLabel, halfSize, halfSize * (1 / 4) + fontSize / 3);\n }\n\n return new THREE.CanvasTexture(canvas);\n }\n\n private getFaceTexture(faceConfig: AxisBoxFaceConfig, size: number) {\n const textureSize = size / 2;\n\n const canvas = document.createElement('canvas');\n canvas.width = textureSize;\n canvas.height = textureSize;\n\n const context = canvas.getContext('2d')!;\n context.fillStyle = faceConfig.outlineColor!.getStyle();\n context.fillRect(0, 0, textureSize, textureSize);\n context.fillStyle = faceConfig.faceColor!.getStyle();\n\n const outlineSize = faceConfig.outlineSize ?? textureSize / 32;\n context.fillRect(outlineSize, outlineSize, textureSize - outlineSize * 2, textureSize - outlineSize * 2);\n context.fill();\n\n if (faceConfig.label !== '') {\n const fontSize = faceConfig.fontSize ?? textureSize / 3;\n context.font = `bold ${fontSize}px Arial`;\n context.textAlign = 'center';\n context.fillStyle = faceConfig.fontColor!.getStyle();\n context.fillText(faceConfig.label!, textureSize / 2, textureSize / 2 + fontSize / 3);\n }\n\n return new THREE.CanvasTexture(canvas);\n }\n\n private createBoxFace(position: THREE.Vector3, faceConfig: AxisBoxFaceConfig, upVector = new THREE.Vector3(0, 1, 0)) {\n const face = new THREE.Mesh(\n this._boxFaceGeometry,\n new THREE.MeshBasicMaterial({ map: this.getFaceTexture(faceConfig, this._layoutConfig.size) })\n );\n\n face.position.copy(position.multiplyScalar(0.5 * this._boxFaceGeometry.parameters.width));\n face.lookAt(position.multiplyScalar(2));\n\n face.userData.upVector = upVector;\n\n return face;\n }\n\n private moveCameraTo(\n camera: THREE.PerspectiveCamera,\n cameraControls: ComboControls,\n targetAxis: THREE.Vector3,\n targetUpAxis: THREE.Vector3\n ) {\n const currentCameraPosition = camera.position.clone();\n const cameraTarget = cameraControls.getState().target;\n\n const targetRelativeStartPosition = currentCameraPosition.clone().sub(cameraTarget);\n const radius = targetRelativeStartPosition.length();\n\n const normalizedFrom = targetRelativeStartPosition.clone().normalize();\n\n const omega = Math.acos(normalizedFrom.dot(targetAxis));\n\n const from = { t: 0 };\n const to = { t: 1 };\n\n const animation = new TWEEN.Tween(from);\n\n const forward = targetAxis.clone();\n\n const fromRotation = camera.quaternion.clone();\n const toRotation = new THREE.Quaternion().setFromRotationMatrix(\n new THREE.Matrix4().makeBasis(targetUpAxis.clone().cross(forward), targetUpAxis, forward)\n );\n\n const epsilon = 1e-6;\n\n if (fromRotation.angleTo(toRotation) < epsilon) {\n return;\n }\n\n const tmpPosition = new THREE.Vector3();\n const tmpRotation = new THREE.Quaternion();\n let cachedCameraControlsEnabled: boolean;\n const tween = animation\n .to(to, this._layoutConfig.animationSpeed)\n .onUpdate(() => {\n tmpPosition\n .copy(normalizedFrom)\n .multiplyScalar(Math.sin((1 - from.t) * omega) / Math.sin(omega))\n .add(targetAxis.clone().multiplyScalar(Math.sin(from.t * omega) / Math.sin(omega)));\n\n tmpPosition.multiplyScalar(radius);\n tmpPosition.add(cameraTarget);\n\n tmpRotation.slerpQuaternions(fromRotation, toRotation, from.t);\n\n camera.position.copy(tmpPosition);\n camera.setRotationFromQuaternion(tmpRotation);\n })\n .start(TWEEN.now())\n .onStart(() => {\n cachedCameraControlsEnabled = cameraControls.enabled;\n cameraControls.enabled = false;\n })\n .onComplete(() => {\n cameraControls.setState(camera.position, cameraTarget);\n cameraControls.enabled = cachedCameraControlsEnabled;\n });\n tween.update(TWEEN.now());\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Supported map Providers Bing, Here & Mapbox\n */\nexport enum MapProviders {\n BingMap = 'BingMap',\n HereMap = 'HereMap',\n MapboxMap = 'MapboxMap',\n OpenStreetMap = 'OpenStreetMap'\n}\n\n/**\n * Map data for Mapbox\n */\nexport enum MapboxMode {\n /**\n * Access the map data using a map style. For details see https://docs.mapbox.com/api/maps/styles/\n */\n Style = 100,\n /**\n * Access the map data using a map id or Tileset id. For details see https://docs.mapbox.com/help/glossary/tileset-id/\n */\n Map_Id = 101\n}\n\n/**\n * Mapbox Map Style, these are pre-defined styles using map/tileset id, created in Mapbox Studio style editor.\n * This is used when MapboxMode.Style is used for mode.\n */\nexport enum MapboxStyle {\n Streets = 'mapbox/streets-v10',\n Outdoor = 'mapbox/outdoors-v10',\n Light = 'mapbox/light-v9',\n Dark = 'mapbox/dark-v9',\n Satellite = 'mapbox/satellite-v9',\n Satellite_Streets = 'mapbox/satellite-streets-v10',\n Navigation_Day = 'mapbox/navigation-preview-day-v4',\n Navigation_Night = 'mapbox/navigation-preview-night-v4',\n Navigation_Guide_Day = 'mapbox/navigation-guidance-day-v4',\n Navigation_Guide_Night = 'mapbox/navigation-guidance-night-v4'\n}\n\n/**\n * A map/tileset ID is a unique identifier given to every tileset, used when MapboxMode.Map_Id is choosen for mode.\n */\nexport enum MapboxId {\n Streets = 'mapbox.mapbox-streets-v7',\n Satellite = 'mapbox.satellite',\n Terrain = 'mapbox.mapbox-terrain-v2',\n Traffic = 'mapbox.mapbox-traffic-v1',\n TerrainRGB = 'mapbox.terrain-rgb'\n}\n\n/**\n * Mapbox Map image tile format\n */\nexport enum MapboxImageFormat {\n PNG = 'png',\n PNG32 = 'png32',\n PNG64 = 'png64',\n PNG128 = 'png128',\n PNG256 = 'png256',\n JPG70 = 'jpg70',\n JPG80 = 'jpg80',\n JPG90 = 'jpg90',\n PNGRAW = 'pngraw'\n}\n\n/**\n * Bing Map View (aerial, road, bird's eye view of the map)\n */\nexport enum BingMapType {\n Aerial = 'a',\n Road = 'r',\n Aerial_Labels = 'h',\n Oblique = 'o',\n Oblique_Labels = 'b'\n}\n\n/**\n * Bing Map Tile Image formats\n */\nexport enum BingMapImageFormat {\n GIF = 'gif',\n JPEG = 'jpeg',\n PNG = 'png'\n}\n\n/**\n * Here Map types\n */\nexport enum HereMapType {\n Aerial = 'aerial',\n Base = 'base',\n Pano = 'pano',\n Traffic = 'traffic'\n}\n\n/**\n * Here Map View Scheme like day, night, satellite, terrain\n */\nexport enum HereMapScheme {\n Day = 'normal.day',\n Night = 'normal.night',\n Terrain = 'terrain.day',\n Satellite = 'satellite.day'\n}\n\n/**\n * Here Map Tiles Image Format\n */\nexport enum HereMapImageFormat {\n PNG = 'png',\n PNG8 = 'png8',\n JPG = 'jpg'\n}\n\nexport type BingMapConfig = {\n provider: MapProviders.BingMap;\n /**\n * Bing Map API Key\n */\n APIKey: string;\n /**\n * The type of the map used.\n */\n type?: BingMapType;\n};\n\nexport type HereMapConfig = {\n provider: MapProviders.HereMap;\n /**\n * Here map API Key\n */\n APIKey: string;\n /**\n * Service application code token.\n */\n appCode?: string;\n /**\n * The type of maps to be used.\n */\n style?: HereMapType;\n /**\n * Specifies the view scheme\n */\n scheme?: string;\n /**\n * Map image tile format\n */\n imageFormat?: HereMapImageFormat;\n /**\n Returned tile map image size.\n The following sizes are supported:\n - 256\n - 512\n - 128 (deprecated, although usage is still accepted)\n */\n size?: number;\n};\n\nexport type OpenStreetMapConfig = {\n provider: MapProviders.OpenStreetMap;\n};\n\nexport type MapboxConfig = {\n provider: MapProviders.MapboxMap;\n /**\n * Mapbox API Key\n */\n APIKey: string;\n /**\n * Map style or map ID if the mode is set to MAP_ID\n */\n id: string;\n /**\n Map tile access mode\n - MapboxMode.STYLE\n - MapboxMode.MAP_ID\n */\n mode?: MapboxMode;\n /**\n * Map image tile format\n */\n tileFormat?: MapboxImageFormat;\n /**\n * Flag to indicate if should use high resolution tiles\n */\n useHDPI?: boolean;\n};\n\n/**\n * Maps Configuration of {@link GeomapTool}.\n */\nexport type MapConfig = {\n /**\n * Latitude, Longitude position\n */\n latlong: LatLongPosition;\n} & (BingMapConfig | HereMapConfig | MapboxConfig | OpenStreetMapConfig);\n\n/**\n * Latitude, Longitude position.\n */\nexport type LatLongPosition = {\n latitude: number;\n longitude: number;\n};\n","/*!\n * Copyright 2021 Cognite AS\n */\n// To overcome \"implicitly has an 'any' type\" and \"unused variable reference\" error in the geo-three library\n// @ts-ignore\nimport * as GEOTHREE from 'geo-three';\nimport { Cognite3DViewer } from '@reveal/core';\nimport { LatLongPosition, MapConfig, MapProviders } from './MapConfig';\n\nexport class Geomap {\n private readonly _viewer: Cognite3DViewer;\n private readonly _map: GEOTHREE.MapView;\n private _intervalId: any = 0;\n private readonly _onCameraChange = this.handleCameraChange.bind(this);\n\n constructor(viewer: Cognite3DViewer, mapConfig: MapConfig) {\n this._viewer = viewer;\n const mapProvider = this.getMapProvider(mapConfig);\n this._map = new GEOTHREE.MapView(GEOTHREE.MapView.PLANAR, mapProvider, mapProvider);\n this._viewer.addObject3D(this._map);\n\n const coords = GEOTHREE.UnitsUtils.datumsToSpherical(mapConfig.latlong.latitude, mapConfig.latlong.longitude);\n const bound = this._viewer.models[0].getModelBoundingBox();\n this._map.position.set(-coords.x, bound.min.y, coords.y);\n this._map.updateMatrixWorld(true);\n this.requestRedraw(10000);\n this._viewer.on('cameraChange', this._onCameraChange);\n }\n\n private requestRedraw(timeOut: number) {\n if (this._intervalId == 0) {\n this._intervalId = setInterval(() => {\n this._viewer.requestRedraw();\n }, 100);\n\n setTimeout(() => {\n clearInterval(this._intervalId);\n this._intervalId = 0;\n }, timeOut);\n }\n }\n\n private getMapProvider(mapConfig: MapConfig) {\n let mapProvider: GEOTHREE.MapProvider;\n switch (mapConfig.provider) {\n case MapProviders.BingMap:\n mapProvider = new GEOTHREE.BingMapsProvider(mapConfig.APIKey, mapConfig.type);\n break;\n case MapProviders.HereMap:\n mapProvider = new GEOTHREE.HereMapsProvider(\n mapConfig.APIKey,\n mapConfig.appCode,\n mapConfig.style,\n mapConfig.scheme,\n mapConfig.imageFormat,\n mapConfig.size\n );\n break;\n case MapProviders.MapboxMap:\n mapProvider = new GEOTHREE.MapBoxProvider(mapConfig.APIKey, mapConfig.id, mapConfig.mode, mapConfig.tileFormat);\n break;\n case MapProviders.OpenStreetMap:\n mapProvider = new GEOTHREE.OpenStreetMapsProvider();\n break;\n\n default:\n throw new Error('Unsupported map provider');\n }\n\n return mapProvider;\n }\n\n public latLongToWorldCoordinates(latLong: LatLongPosition): { x: number; y: number } {\n return GEOTHREE.UnitsUtils.datumsToSpherical(latLong.latitude, latLong.longitude);\n }\n\n private handleCameraChange() {\n this.requestRedraw(1000);\n }\n\n public dispose(): void {\n this._viewer.removeObject3D(this._map);\n this._viewer.off('cameraChange', this._onCameraChange);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { Cognite3DViewerToolBase } from '../Cognite3DViewerToolBase';\nimport { LatLongPosition, MapConfig } from './MapConfig';\nimport { Geomap } from './Geomap';\n\nimport { Cognite3DViewer } from '@reveal/core';\nimport { MetricsLogger } from '@reveal/metrics';\n\n/**\n * The `GeomapTool` is a geolocation for the models and allow the user to place them on the maps.\n * @version New since 2.1.\n */\nexport class GeomapTool extends Cognite3DViewerToolBase {\n private readonly _viewer: Cognite3DViewer;\n private readonly _maps: Geomap;\n\n constructor(viewer: Cognite3DViewer, config: MapConfig) {\n super();\n\n this._viewer = viewer;\n this._maps = new Geomap(this._viewer, config);\n\n MetricsLogger.trackCreateTool('AxisViewTool');\n }\n\n /**\n * Converts Latitude & Longitude into Vector2 World coordinates on the Map\n * @param latLong Latitude & Longitude\n */\n public latLongToWorldCoordinates(latLong: LatLongPosition): { x: number; y: number } {\n return this._maps.latLongToWorldCoordinates(latLong);\n }\n\n public dispose(): void {\n super.dispose();\n this._maps.dispose();\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { NodeCollectionBase, NodeAppearance } from '@reveal/core/src';\nimport { Cognite3DModel } from '@reveal/core';\nimport { MetricsLogger } from '@reveal/metrics';\n\n/**\n * Timeline Key Frames contains parameters to access Nodes, Styles for the Timeline\n */\nexport class Keyframe {\n private readonly _date: Date;\n private readonly _model: Cognite3DModel;\n private readonly _nodeCollectionAndAppearance: { nodes: NodeCollectionBase; nodeAppearance: NodeAppearance }[] = [];\n\n constructor(model: Cognite3DModel, date: Date) {\n this._model = model;\n this._date = date;\n }\n\n /**\n * Get date of the Keyframe\n * @returns date\n */\n public getKeyframeDate(): Date {\n return this._date;\n }\n\n /**\n * Assigns the styles for the node set for the model for this Keyframe\n */\n public activate(): void {\n this._nodeCollectionAndAppearance.forEach((node, _index) => {\n this._model.assignStyledNodeCollection(node.nodes, node.nodeAppearance);\n });\n }\n\n /**\n * Removes the style for the model\n */\n public deactivate(): void {\n this._nodeCollectionAndAppearance.forEach((node, _index) => {\n this._model.unassignStyledNodeCollection(node.nodes);\n });\n }\n\n /**\n * Add node & style to the collection\n * @param nodeCollection Node set to apply the Styles\n * @param nodeAppearance Style to assign to the node collection\n */\n public assignStyledNodeCollection(nodeCollection: NodeCollectionBase, nodeAppearance: NodeAppearance): void {\n MetricsLogger.trackCadModelStyled(nodeCollection.classToken, nodeAppearance);\n\n const index = this._nodeCollectionAndAppearance.findIndex(x => x.nodes === nodeCollection);\n if (index !== -1) {\n throw new Error(\n 'Node collection as already been assigned, use updateStyledNodeCollection() to update the appearance'\n );\n }\n\n this._nodeCollectionAndAppearance.push({ nodes: nodeCollection, nodeAppearance });\n }\n\n /**\n * Remove Node & Style for this keyframe's nodeCollection and nodeAppearance\n * @param nodeCollection Nodes to be unassign from node collection\n */\n public unassignStyledNodeCollection(nodeCollection: NodeCollectionBase): void {\n const index = this._nodeCollectionAndAppearance.findIndex(x => x.nodes === nodeCollection);\n if (index === -1) {\n throw new Error('Node collection has not been assigned to model');\n }\n this._nodeCollectionAndAppearance.splice(index, 1);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport TWEEN from '@tweenjs/tween.js';\n\nimport { Cognite3DModel } from '@reveal/core';\nimport { Cognite3DViewerToolBase } from '../Cognite3DViewerToolBase';\nimport { Keyframe } from './Keyframe';\nimport { TimelineDateUpdateDelegate } from './types';\nimport { EventTrigger, assertNever } from '@reveal/core/utilities';\n\n/**\n * Tool to applying styles to nodes based on date to play them over in Timeline\n */\nexport class TimelineTool extends Cognite3DViewerToolBase {\n private readonly _model: Cognite3DModel;\n private readonly _keyframes: Keyframe[];\n private _playback: TWEEN.Tween | undefined = undefined;\n private readonly _events = { dateChanged: new EventTrigger<TimelineDateUpdateDelegate>() };\n\n constructor(cadModel: Cognite3DModel) {\n super();\n\n this._model = cadModel;\n this._keyframes = new Array<Keyframe>();\n }\n\n /**\n * Subscribe to the Date changed event\n * @param event `dateChanged` event\n * @param listener Listen to Timeline date Update during Playback\n */\n public subscribe(event: 'dateChanged', listener: TimelineDateUpdateDelegate): void {\n switch (event) {\n case 'dateChanged':\n this._events.dateChanged.subscribe(listener);\n break;\n default:\n assertNever(event, `Unsupported event: '${event}'`);\n }\n }\n\n /**\n * Unsubscribe to the Date changed event\n * @param event `dateChanged` event\n * @param listener Remove Listen to Timeline date Update\n */\n public unsubscribe(event: 'dateChanged', listener: TimelineDateUpdateDelegate): void {\n switch (event) {\n case 'dateChanged':\n this._events.dateChanged.unsubscribe(listener);\n break;\n default:\n assertNever(event, `Unsupported event: '${event}'`);\n }\n }\n\n /**\n * Create Key frame for the Timeline\n * @param date - date value by Date.now() since January 1, 1970\n */\n public createKeyframe(date: Date): Keyframe {\n const keyframe = new Keyframe(this._model, date);\n this._keyframes.push(keyframe);\n this.sortKeyframesByDates();\n\n return keyframe;\n }\n\n /**\n * Returns the keyframe at the date given, or undefined if not found.\n * @param date\n * @returns\n */\n public getKeyframeByDate(date: Date): Keyframe | undefined {\n return this._keyframes.find(candidate => candidate.getKeyframeDate() === date);\n }\n\n /**\n * Removes the Keyframe from the timeline. Does nothing if the keyframe isn't part of the timeline.\n * @param keyframe - Keyframe to be removed from the timeline\n */\n public removeKeyframe(keyframe: Keyframe): void {\n const index = this._keyframes.findIndex(obj => obj === keyframe);\n\n if (index > -1) {\n this._keyframes.splice(index, 1);\n }\n }\n\n /**\n * Removes the Keyframe from the Timeline\n * @param date - Date of the Keyframe to be removed from the Timeline\n */\n public removeKeyframeByDate(date: Date): void {\n const index = this._keyframes.findIndex(obj => obj.getKeyframeDate() === date);\n\n if (index > -1) {\n this._keyframes.splice(index, 1);\n }\n }\n\n /**\n * Starts playback of Timeline\n * @param startDate - Keyframe date to start the Playback of Keyframes\n * @param endDate - Keyframe date to stop the Playback of Keyframes\n * @param totalDurationInMilliSeconds - Number of milliseconds for all Keyframe within startDate & endDate to be rendered\n */\n public play(startDate: Date, endDate: Date, totalDurationInMilliSeconds: number): void {\n this.stop();\n\n const playState = { dateInMs: startDate.getTime() };\n const to = { dateInMs: endDate.getTime() };\n const tween = new TWEEN.Tween(playState).to(to, totalDurationInMilliSeconds);\n let currentKeyframeIndex = -1;\n tween.onUpdate(() => {\n const date = new Date(playState.dateInMs);\n\n // Forward active keyframe to last keyframe that is before current date\n const prevIndex = currentKeyframeIndex;\n while (\n currentKeyframeIndex < this._keyframes.length - 1 &&\n this._keyframes[currentKeyframeIndex + 1].getKeyframeDate().getTime() <= date.getTime()\n ) {\n currentKeyframeIndex++;\n }\n\n if (currentKeyframeIndex !== prevIndex) {\n if (prevIndex !== -1) {\n this._keyframes[prevIndex].deactivate();\n }\n this._keyframes[currentKeyframeIndex].activate();\n }\n\n this._events.dateChanged.fire({\n date: date,\n activeKeyframe: this._keyframes[currentKeyframeIndex],\n startDate: startDate,\n endDate: endDate\n });\n });\n\n this._playback = tween;\n tween.start();\n }\n\n /**\n * Stops any ongoing playback\n */\n public stop(): void {\n if (this._playback !== undefined) {\n this._playback.stop();\n this._playback = undefined;\n }\n }\n\n /**\n * Pause any ongoing playback\n */\n public pause(): void {\n if (this._playback !== undefined && this._playback.isPlaying()) {\n this._playback.pause();\n }\n }\n\n /**\n * Resume any paused playback\n */\n public resume(): void {\n if (this._playback !== undefined && this._playback.isPaused()) {\n this._playback.resume();\n }\n }\n\n /**\n * Provides all Keyframes in the Timeline\n * @returns All Keyframes in Timeline\n */\n public getAllKeyframes(): Keyframe[] {\n return this._keyframes.slice();\n }\n\n public dispose(): void {\n super.dispose();\n this._events.dateChanged.unsubscribeAll();\n }\n\n /**\n * Sort the Timeline Keyframe by their Date\n */\n private sortKeyframesByDates() {\n if (this._keyframes.length > 1) {\n this._keyframes.sort((a: Keyframe, b: Keyframe) => {\n return a.getKeyframeDate().getTime() - b.getKeyframeDate().getTime();\n });\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\nimport { Cognite3DViewer, Cognite3DModel } from '@reveal/core';\nimport { LevelOfDetail, SectorNode } from '@reveal/core/cad';\nimport { assertNever } from '@reveal/core/utilities';\n\nimport { Cognite3DViewerToolBase } from './Cognite3DViewerToolBase';\n\nexport type DebugLoadedSectorsToolOptions = {\n showSimpleSectors?: boolean;\n showDetailedSectors?: boolean;\n showDiscardedSectors?: boolean;\n colorBy?: 'depth' | 'lod' | 'loadedTimestamp' | 'random';\n leafsOnly?: boolean;\n sectorPathFilterRegex?: string;\n};\n\nexport class DebugLoadedSectorsTool extends Cognite3DViewerToolBase {\n private readonly _boundingBoxes = new THREE.Group();\n private readonly _viewer: Cognite3DViewer;\n private _options: Required<DebugLoadedSectorsToolOptions>;\n private _model?: Cognite3DModel;\n\n constructor(viewer: Cognite3DViewer, options: DebugLoadedSectorsToolOptions = {}) {\n super();\n this._viewer = viewer;\n this._viewer.addObject3D(this._boundingBoxes);\n this._options = {} as any; // Force - it's set in setOptions\n this.setOptions(options);\n }\n\n setOptions(options: DebugLoadedSectorsToolOptions): void {\n this._options = {\n showDetailedSectors: true,\n showDiscardedSectors: false,\n showSimpleSectors: true,\n colorBy: 'lod',\n leafsOnly: false,\n sectorPathFilterRegex: '.*',\n ...options\n };\n }\n\n dispose(): void {\n this._viewer.removeObject3D(this._boundingBoxes);\n }\n\n showSectorBoundingBoxes(model: Cognite3DModel): void {\n this._model = model;\n this.updateBoundingBoxes();\n }\n\n private updateBoundingBoxes() {\n this._boundingBoxes.clear();\n if (this._model === undefined) {\n return;\n }\n this._model.getModelTransformation(this._boundingBoxes.matrix);\n const shouldShowLod: boolean[] = [];\n shouldShowLod[LevelOfDetail.Discarded] = this._options.showDiscardedSectors;\n shouldShowLod[LevelOfDetail.Simple] = this._options.showSimpleSectors;\n shouldShowLod[LevelOfDetail.Detailed] = this._options.showDetailedSectors;\n\n const selectedSectorNodes: SectorNode[] = [];\n this._model.cadNode.traverse(node => {\n if (isSectorNode(node)) {\n const sectorNode = node as SectorNode;\n\n if (\n this.isSectorAcceptedByCurrentFilter(sectorNode) &&\n shouldShowLod[sectorNode.levelOfDetail] &&\n (!this._options.leafsOnly || isLeaf(sectorNode))\n ) {\n selectedSectorNodes.push(sectorNode);\n }\n }\n });\n\n selectedSectorNodes.forEach(sectorNode => {\n const bboxNode = this.createBboxNodeFor(sectorNode, selectedSectorNodes);\n this._boundingBoxes.add(bboxNode);\n });\n this._boundingBoxes.updateMatrixWorld(true);\n\n this._viewer.requestRedraw();\n }\n\n private isSectorAcceptedByCurrentFilter(node: SectorNode): boolean {\n const accepted = new RegExp(this._options.sectorPathFilterRegex).test(node.sectorPath);\n return accepted;\n }\n\n private createBboxNodeFor(node: SectorNode, allSelectedNodes: SectorNode[]) {\n const options = this._options;\n function determineColor() {\n switch (options.colorBy) {\n case 'depth': {\n const s = Math.min(1.0, node.depth / 8);\n return new THREE.Color(Colors.green).lerpHSL(Colors.red, s);\n }\n case 'lod': {\n switch (node.levelOfDetail) {\n case LevelOfDetail.Simple:\n return Colors.yellow;\n case LevelOfDetail.Detailed:\n return Colors.green;\n case LevelOfDetail.Discarded:\n return Colors.red;\n default:\n assertNever(node.levelOfDetail);\n }\n }\n case 'loadedTimestamp': {\n // Note! Horribly slow since we do this for every sector, but since this is a debug tool\n // we consider it OK\n const nodesByTimestamp = [...allSelectedNodes].sort((a, b) => a.updatedTimestamp - b.updatedTimestamp);\n const indexOfNode = nodesByTimestamp.findIndex(x => x === node);\n const s = (nodesByTimestamp.length - 1 - indexOfNode) / Math.max(nodesByTimestamp.length - 1, 1);\n return new THREE.Color(Colors.green).lerpHSL(Colors.red, s);\n }\n\n case 'random':\n return new THREE.Color().setHSL(Math.random(), 1.0, 0.5);\n\n default:\n assertNever(options.colorBy);\n }\n }\n const color = determineColor();\n return new THREE.Box3Helper(node.bounds, color);\n }\n}\n\nconst Colors = {\n green: new THREE.Color('#00ff00'),\n yellow: new THREE.Color('yellow'),\n red: new THREE.Color('red')\n};\n\nfunction isSectorNode(node: THREE.Object3D) {\n return node.name.match(/^Sector \\d+$/);\n}\n\nfunction isLeaf(node: SectorNode) {\n return !node.children.some(x => isSectorNode(x));\n}\n"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap","webpack:///external \"three\"","webpack:///./packages/utilities/src/objectTraversal.ts","webpack:///./packages/utilities/src/transformCameraConfiguration.ts","webpack:///./packages/utilities/src/RandomColors.ts","webpack:///./packages/utilities/src/events/clickOrTouchEventOffset.ts","webpack:///./packages/utilities/src/events/EventTrigger.ts","webpack:///./packages/utilities/src/events/InputHandler.ts","webpack:///./packages/utilities/src/assertNever.ts","webpack:///./packages/utilities/src/NumericRange.ts","webpack:///./packages/utilities/src/determinePowerOfTwoDimensions.ts","webpack:///./packages/utilities/src/indexset/IntermediateIndexNode.ts","webpack:///./packages/utilities/src/indexset/LeafIndexNode.ts","webpack:///./packages/utilities/src/indexset/IndexSet.ts","webpack:///./packages/utilities/src/packFloat.ts","webpack:///./packages/utilities/src/datastructures/DynamicDefragmentedBuffer.ts","webpack:///./packages/utilities/src/three/AutoDisposeGroup.ts","webpack:///./packages/utilities/src/three/BoundingBoxLOD.ts","webpack:///./packages/utilities/src/three/getBox3CornerPoints.ts","webpack:///./packages/utilities/src/isMobileOrTablet.ts","webpack:///./packages/utilities/src/WebGLRendererStateHelper.ts","webpack:///./packages/utilities/src/revealEnv.ts","webpack:///./packages/utilities/src/workers/WorkerPool.ts","webpack:///./packages/utilities/src/networking/isTheSameDomain.ts","webpack:///./packages/utilities/src/cache/MemoryRequestCache.ts","webpack:///./packages/utilities/src/cache/MostFrequentlyUsedCache.ts","webpack:///./packages/utilities/src/disposeAttributeArrayOnUpload.ts","webpack:///./packages/cad-parsers/src/utilities/SectorScene.ts","webpack:///./packages/cad-parsers/src/metadata/parsers/CadMetadataParserV8.ts","webpack:///./packages/cad-parsers/src/metadata/CadMetadataParser.ts","webpack:///./packages/cad-parsers/src/utilities/types.ts","webpack:///./packages/cad-parsers/src/metadata/CadModelMetadataRepository.ts","webpack:///./packages/cad-parsers/src/cad/LevelOfDetail.ts","webpack:///./packages/cad-parsers/src/utilities/SectorSceneFactory.ts","webpack:///./packages/cad-parsers/src/sector/SectorNode.ts","webpack:///./packages/cad-parsers/src/sector/RootSectorNode.ts","webpack:///./packages/cad-parsers/src/cad/CadSectorParser.ts","webpack:///./packages/cad-parsers/src/utilities/computeBoundingBoxFromAttributes.ts","webpack:///./packages/cad-parsers/src/cad/filterPrimitives.ts","webpack:///./packages/cad-parsers/src/cad/filterInstanceMesh.ts","webpack:///./packages/cad-parsers/src/utilities/float32BufferToMatrix.ts","webpack:///./packages/cad-parsers/src/cad/primitiveGeometries.ts","webpack:///./packages/cad-parsers/src/cad/triangleMeshes.ts","webpack:///./packages/modeldata-api/src/CdfModelDataProvider.ts","webpack:///./packages/modeldata-api/src/CdfModelIdentifier.ts","webpack:///./packages/modeldata-api/src/types.ts","webpack:///./packages/modeldata-api/src/applyDefaultModelTransformation.ts","webpack:///./packages/modeldata-api/src/Model3DOutputList.ts","webpack:///./packages/modeldata-api/src/CdfModelMetadataProvider.ts","webpack:///./packages/modeldata-api/src/CdfModelOutputsProvider.ts","webpack:///./packages/modeldata-api/src/utilities.ts","webpack:///./packages/modeldata-api/src/LocalModelDataProvider.ts","webpack:///./packages/modeldata-api/src/LocalModelIdentifier.ts","webpack:///./packages/modeldata-api/src/LocalModelMetadataProvider.ts","webpack:///external \"assert\"","webpack:///./packages/metrics/src/MetricsLogger.ts","webpack:///./packages/logger/src/Log.ts","webpack:///./packages/logger/index.ts","webpack:///external \"@tweenjs/tween.js\"","webpack:///external \"mixpanel-browser\"","webpack:///./core/src/utilities/worldToViewport.ts","webpack:///external \"lodash/debounce\"","webpack:///external \"lodash/cloneDeep\"","webpack:///external \"lodash/range\"","webpack:///external \"geo-three\"","webpack:///external \"@cognite/sdk-core\"","webpack:///./core/src/utilities/index.ts","webpack:///./core/src/utilities/BoundingBoxClipper.ts","webpack:///external \"comlink\"","webpack:///external \"loglevel\"","webpack:///external \"skmeans\"","webpack:///external \"lodash/merge\"","webpack:///./packages/tools/src/Cognite3DViewerToolBase.ts","webpack:///./packages/tools/src/HtmlOverlay/BucketGrid2D.ts","webpack:///./packages/tools/src/HtmlOverlay/HtmlOverlayTool.ts","webpack:///./packages/tools/src/ExplodedViewTool.ts","webpack:///./packages/tools/src/DebugCameraTool.ts","webpack:///./packages/tools/src/AxisView/types.ts","webpack:///./packages/tools/src/AxisView/AxisViewTool.ts","webpack:///./packages/tools/src/Geomap/MapConfig.ts","webpack:///./packages/tools/src/Geomap/Geomap.ts","webpack:///./packages/tools/src/Geomap/GeomapTool.ts","webpack:///./packages/tools/src/Timeline/Keyframe.ts","webpack:///./packages/tools/src/Timeline/TimelineTool.ts","webpack:///./packages/tools/src/DebugLoadedSectorsTool.ts"],"names":["root","factory","exports","module","define","amd","a","i","self","this","installedModules","__webpack_require__","moduleId","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","require","traverseDepthFirst","visitor","children","length","transformCameraConfiguration","cameraConfiguration","modelMatrix","undefined","position","target","applyMatrix4","colorIndex","color","_colors","newColor","generateRandomColor","set","Math","floor","g","b","colorRGB","hue","random","saturation","lightness","setHSL","clickOrTouchEventOffset","ev","rect","getBoundingClientRect","MouseEvent","offsetX","clientX","left","offsetY","clientY","top","changedTouches","touch","Map","EventTrigger","_listeners","listener","push","index","indexOf","splice","args","forEach","domElement","_events","click","hover","onHoverCallback","e","fire","setupEventListeners","event","callback","subscribe","assertNever","unsubscribe","disposeOfAllEventListeners","pointerDown","pointerDownTimestamp","validClick","startOffset","onUp","handleClickEvent","removeEventListener","addEventListener","onDown","timeStamp","clickDuration","hasMovedDuringClick","abs","x","y","maxMoveDistance","maxClickDuration","isProperClick","eventList","eventType","keys","unsubscribeAll","message","Error","NumericRange","from","count","toInclusive","Array","values","other","range","intersects","createFromInterval","max","min","action","determinePowerOfTwoDimensions","elementCount","width","ceilToPowerOfTwo","sqrt","height","log2","log","v","pow","ceil","right","maxSubtreeDepth","r0","r1","balance","traverse","contains","intersectsOrCoinciding","newNode","addRange","fromIndexNodesAndBalance","canUnionLeft","canUnionRight","newLeft","leftRange","soak","newRight","rightRange","unioned","union","newThis","soakedRange","nodeToReturn","leftSubTreeSize","rightSubTreeSize","rotateSmallerRight","rotateRight","rotateSmallerLeft","rotateLeft","clone","node","isInside","hasIntersectionWith","leftRes","rightRes","unionRange","nextRoot","begin","endInclusive","rootNode","isNumericRange","add","removeRange","ranges","forEachRange","result","num","arr","toIndexArray","Set","originalRanges","toRangeArray","newRanges","otherSet","leftBoundRange","rightBoundRange","invertedRanges","st","packFloatInto","f","targetBuffer","offset","F","Sign","step","Exponent","Mantissa","exp2","mod","edge","DynamicDefragmentedBuffer","initialSize","type","_numFilled","_batchIdCounter","_batchMap","_type","minimalPowerOfTwo","_buffer","array","isReallocated","newSize","allocateNewBuffer","batchId","createBatch","bufferIsReallocated","batch","copyWithin","buffer","_currentTail","prev","next","currentBatch","delete","newBuffer","emptyGeometry","_isDisposed","_referenceCount","ensureNotDisposed","dispose","meshes","filter","map","mesh","geometry","updateVars","camPos","bounds","boundingBox","super","_activeLevel","_levels","isLOD","autoUpdate","_boundingBox","copy","distance","sort","visible","camera","updateCurrentLevel","levels","matrixWorld","cameraZoom","zoom","setFromMatrixPosition","distanceToCamera","distanceToPoint","findIndex","getBox3CornerPoints","box","z","isMobileOrTablet","check","navigator","userAgent","vendor","window","opera","test","substr","renderer","_originalState","_renderer","alpha","clearColor","getClearColor","clearAlpha","getClearAlpha","setClearColor","size","getSize","setSize","enabled","localClippingEnabled","autoClear","renderTarget","getRenderTarget","setRenderTarget","revealEnv","publicPath","workerList","numberOfWorkers","determineNumberOfWorkers","newWorker","worker","createWorker","activeJobCount","messageIdCounter","async","actualWorkerVersion","getVersion","minWorkerVersion","majorMin","minorMin","patchMin","split","parseInt","majorWorker","minorWorker","patchWorker","errorMessage","checkWorkerVersion","catch","error","workerObjUrl","URL","revokeObjectURL","_defaultPool","workerUrl","options","url1","url2","location","origin","isRelative","url","match","constructedURLs","startsWith","host","console","isTheSameDomain","Worker","blob","Blob","JSON","stringify","createObjectURL","work","targetWorker","reduce","bestWorker","candidate","hardwareConcurrency","TimestampedContainer","_value","_lastAccessTime","Date","now","MemoryRequestCache","maxElementsInCache","removeCallback","defaultCleanupCount","_data","_maxElementsInCache","_defaultCleanupCount","_removeCallback","id","has","data","isFull","cleanCache","insert","allResults","entries","lastAccessTime","entry","pop","remove","clear","MostFrequentlyUsedCache","capacity","disposeCallback","_cache","_retrieves","_capacity","_disposeCallback","retrieveCount","ensureWithinCapacity","keysForRemoval","retrivalCount","slice","disposeAttributeArrayOnUpload","version","maxTreeIndex","unit","sectorsById","sectors","sectorId","accepted","containsPoint","intersectsBox","allBounds","corners","toArray","numClusters","clusters","clusterCounts","idxs","fill","clusterBounds","_","biggestCluster","idx","cluster","expandByPoint","intersectingBounds","merged","projectionMatrix","inverseCameraModelMatrix","frustumMatrix","multiplyMatrices","frustum","setFromProjectionMatrix","parseCadMetadataV8","metadata","parentIds","sector","facesFile","quadSize","coverageFactors","xy","yz","xz","recursiveCoverageFactors","fileName","downloadSize","indexFile","determineFacesFile","bb","min_x","min_y","min_z","max_x","max_y","max_z","path","depth","estimatedDrawCallCount","estimatedRenderCost","estimatedTriangleCount","createSectorMetadata","parentId","rootSector","populateCoverageFactorsFromAnchestors","validFacesFileSection","hasDummyFacesFileSection","child","parsedJson","WellKnownDistanceToMeterConversionFactors","modelMetadataProvider","modelDataProvider","cadMetadataParser","blobFileName","_currentModelIdentifier","_modelMetadataProvider","_modelDataProvider","_cadSceneParser","_blobFileName","modelIdentifier","blobBaseUrlPromise","getModelUri","modelMatrixPromise","getModelMatrix","modelCameraPromise","getModelCamera","blobBaseUrl","json","getJsonFile","scene","parse","conversionFactor","makeScale","multiply","createScaleToMetersModelMatrix","inverseModelMatrix","invert","modelBaseUrl","geometryClipBox","LevelOfDetail","sectorPath","_lod","Discarded","_updatedTimestamp","determineSectorDepth","_group","geomtryGroup","levelOfDetail","resetGeometry","reference","updateMatrixWorld","dereference","modelMetadata","modelBounds","sectorNodeMap","buildScene","parent","sectorGroup","matrixAutoUpdate","setModelTransformation","matrix","out","workerPool","defaultPool","parseDetailed","parseSimple","parseCtm","quadsArrayBuffer","postWorkToAvailable","parseQuads","sectorArrayBuffer","parseSector","ctmArrayBuffer","computeBoundingBoxFromCenterAndRadiusAttributesVars","centerA","centerB","sphere","computeBoundingBoxFromVertexAttributesVars","vertex1","vertex2","vertex3","vertex4","computeBoundingBoxFromInstanceMatrixAttributesVars","instanceMatrix","computeBoundingBoxFromEllipseAttributesVars","center","filterPrimitivesOutsideClipBox","attributesByteValues","attributes","clipBox","getBoundsOfElementsCallback","elementSize","attributeFloatValues","Float32Array","instanceBbox","filteredByteValues","Uint8Array","filteredCount","elementValues","subarray","filterPrimitivesOutsideClipBoxByBaseBoundsAndInstanceMatrix","baseBox","instanceMatrixAttribute","outBox","elementIndex","baseBoundingBox","BYTES_PER_ELEMENT","computeBoundingBoxFromInstanceMatrixAttributes","filterPrimitivesOutsideClipBoxByCenterAndRadius","radiusAattributeName","radiusBattributeName","centerAattribute","centerBattribute","radiusAattribute","radiusBattribute","readAttribute","attribute","radiusA","radiusB","getBoundingBox","computeBoundingBoxFromCenterAndRadiusAttributes","filterPrimitivesOutsideClipBoxByVertices","vertex1attribute","vertex2attribute","vertex3attribute","vertex4attribute","vertex1Attribute","vertex2Attribute","vertex3Attribute","vertex4Attribute","setFromPoints","computeBoundingBoxFromVertexAttributes","filterPrimitivesOutsideClipBoxByEllipse","radius1AttributeName","radius2AttributeName","centerAttribute","horizontalRadiusAttribute","verticalRadiusAttribute","heightAttribute","radius1Attribute","radius2Attribute","radius1","radius2","extent","setFromCenterAndSize","computeBoundingBoxFromEllipseAttributes","filterInstanceMeshVars","baseBounds","instanceBounds","filterInstanceMesh","vertices","indices","instanceMesh","makeEmpty","j","triangleOffset","triangleCount","v0","v1","v2","filteredOffset","instanceCount","treeIndices","filteredInstanceMatrices","instanceMatrices","filteredTreeIndices","filteredColors","indexOffset","elementInstanceMatrix","elementColor","colors","elementTreeIndex","boxGeometry","boxGeometryBoundingBox","getIndex","getAttribute","normal","computeBoundingBox","quadGeometry","quadGeometryBoundingBox","trapeziumGeometry","trapeziumGeometryBoundingBox","Uint16Array","setFromArray","coneGeometry","coneGeometryBoundingBox","positions","torusLodGeometries","transformFunc","u","PI","tubularSegments","radialSegments","segmentsX","segmentsY","segmentsXInv","segmentsYInv","generatePlane3D","nutGeometry","nutGeometryBoundingBox","makeRotationX","createTriangleMeshes","triangleMeshes","material","filteredTriangleMeshes","isTriangleMeshWithinArgs","isTriangleMeshWithin","onUpload","setIndex","setAttribute","boundingSphere","getBoundingSphere","obj","fileId","userData","CdfModelDataProvider","client","authenticationPromise","authenticate","getDefaultRequestHeaders","baseUrl","headers","Accept","fetchWithRetry","method","arrayBuffer","input","retries","response","fetch","status","err","CdfModelIdentifier","modelId","revisionId","modelFormat","revealInternalId","String","File3dFormat","cadFromCdfToThreeMatrix","applyDefaultModelTransformation","format","RevealCadModel","premultiply","EptPointCloud","Model3DOutputList","outputs","outputFormat","supportedVersions","candidates","_client","toString","model","revisions3D","retrieve","rotation","makeRotationFromEuler","mostRecentOutput","getOutputs","findMostRecentOutput","directoryId","blobId","getBaseUrl","getRequestPath","project","params","items","fetchWithStatusCheck","ok","body","LocalModelIdentifier","localPath","Promise","resolve","VERSION","MIXPANEL_TOKEN","applicationId","eventProps","init","disable_cookie","disable_persistence","ip","property_blacklist","reset","identify","_sessionProps","application","sessionId","replace","innerTrackEvent","logMetrics","globalThis","revealMetricsLogger","metricsLogger","eventName","combined","track","toolName","trackEvent","nodeCollectionClassToken","appearance","style","stack","worldToViewportVars","renderSize","worldToNormalizedViewportCoordinates","position3D","worldToViewportCoordinates","canvas","canvasWidth","canvasHeight","round","BoundingBoxClipper","_clippingPlanes","_box","updatePlanes","setFromNormalAndCoplanarPoint","minX","maxX","minY","maxY","minZ","maxZ","_disposedEvent","_disposed","handler","dimensions","_removedElements","_dimensions","_cells","_bounds","element","cell","cellsIntersecting","visitedElements","candidateElement","dimX","dimY","relativeBoundsMinX","relativeBoundsMaxX","relativeBoundsMinY","relativeBoundsMaxY","clamp","minI","maxI","minJ","maxJ","viewer","_htmlOverlays","_compositeOverlays","_preallocatedVariables","camNormal","point","nearPlane","farPlane","position2D","_onSceneRenderedHandler","onSceneRendered","_onViewerDisposedHandler","onViewerDisposed","_options","_viewer","on","scheduleUpdate","forceUpdate","trackCreateTool","getCamera","info","off","htmlElement","viewerDomElement","visibility","appendChild","getComputedStyle","removeChild","state","overlays","cleanupClusterElements","updateNewElementSizes","viewerCamera","viewerRenderer","getWorldPosition","getWorldDirection","addScaledVector","near","far","positionUpdatedCallback","insideCameraPlanes","distanceTo","clusterElements","commitDOMChanges","clientRect","offsetLeft","offsetTop","opacity","transition","fadeIn","fadeOut","clusteringOptions","clusterByOverlapInScreenSpace","createClusterElementCallback","canvasBounds","bottom","canvasSize","grid","elementBounds","createElementBounds","clusterMidpoint","removeOverlappingElements","midpoint","divideScalar","compositeElement","addComposite","treeIndex","cadModel","_cadModel","_rootTreeIndex","preloadBoundingBoxData","_treeBoundingBoxdata","then","expandRadius","expandData","all","direction","transform","resetNodeTransformByTreeIndex","setPosition","setNodeTransformByTreeIndex","rootTreeIndexBoundingBox","getBoundingBoxByTreeIndex","rootBoundingBox","getCenter","subTreeBoundingBoxes","getSubtreeTreeIndices","subTreeIndices","subTreeIndex","subTreeIndexBoundingBoxCenter","rootCenter","subTreeCenters","subVectors","payloads","payload","hideCameraHelper","_cameraHelper","addObject3D","removeObject3D","Corner","defaultAxisBoxCompassConfig","ringLabel","labelDelta","fontSize","fontColor","tickColor","defaultFaceConfig","label","outlineSize","outlineColor","faceColor","defaultAxisBoxConfig","corner","BottomRight","padding","animationSpeed","faces","xPositiveFace","xNegativeFace","yPositiveFace","yNegativeFace","zPositiveFace","zNegativeFace","compass","config","_dynamicUpdatePosition","_updateClickDiv","_screenPosition","_boxFaceGeometry","_raycastCamera","_raycaster","_layoutConfig","_axisGroup","_interactiveObjects","createAxisCross","_disposeClickDiv","createClickDiv","addAxisBoxToViewer","removeUiObject","querySelector","divElement","document","createElement","zIndex","xMouse","yMouse","mouseDownEvent","button","dispatchEvent","mouseMoveEvent","preventDefault","mouseUpEvent","handleClick","axisGroup","xAbsolute","yAbsolute","isAbsolute","clientWidth","TopRight","clientHeight","TopLeft","BottomLeft","addUiObject","xScreenPos","yScreenPos","boundingRect","xNdc","yNdc","setFromCamera","rayOrigin","rayDirection","normalize","intersectObjects","targetPosition","targetUp","upVector","moveCameraTo","cameraControls","interactiveObjects","createBoxFaces","createCompass","setupTransformOnRender","onBeforeRender","quaternion","facesConfig","createBoxFace","compassPlaneGeometry","createCompassTexture","side","transparent","sin","cos","up","lookAt","compassLayout","textureSize","context","getContext","halfSize","radius","tickWidth","tickSpace","strokeStyle","getStyle","lineWidth","setLineDash","beginPath","arc","stroke","font","textAlign","fillStyle","fillText","faceConfig","fillRect","face","getFaceTexture","multiplyScalar","parameters","targetAxis","targetUpAxis","currentCameraPosition","cameraTarget","getState","targetRelativeStartPosition","sub","normalizedFrom","omega","acos","dot","animation","Tween","forward","fromRotation","toRotation","setFromRotationMatrix","makeBasis","cross","angleTo","tmpPosition","tmpRotation","cachedCameraControlsEnabled","to","onUpdate","slerpQuaternions","setRotationFromQuaternion","start","onStart","onComplete","setState","update","MapProviders","MapboxMode","MapboxStyle","MapboxId","MapboxImageFormat","BingMapType","BingMapImageFormat","HereMapType","HereMapScheme","HereMapImageFormat","mapConfig","_intervalId","_onCameraChange","handleCameraChange","mapProvider","getMapProvider","_map","PLANAR","coords","datumsToSpherical","latlong","latitude","longitude","bound","models","getModelBoundingBox","requestRedraw","timeOut","setInterval","setTimeout","clearInterval","provider","BingMap","APIKey","HereMap","appCode","scheme","imageFormat","MapboxMap","tileFormat","OpenStreetMap","latLong","_maps","latLongToWorldCoordinates","date","_nodeCollectionAndAppearance","_model","_date","_index","assignStyledNodeCollection","nodes","nodeAppearance","unassignStyledNodeCollection","nodeCollection","trackCadModelStyled","classToken","_playback","dateChanged","_keyframes","keyframe","sortKeyframesByDates","find","getKeyframeDate","startDate","endDate","totalDurationInMilliSeconds","stop","playState","dateInMs","getTime","tween","currentKeyframeIndex","prevIndex","deactivate","activate","activeKeyframe","isPlaying","pause","isPaused","resume","_boundingBoxes","setOptions","showDetailedSectors","showDiscardedSectors","showSimpleSectors","colorBy","leafsOnly","sectorPathFilterRegex","updateBoundingBoxes","getModelTransformation","shouldShowLod","Simple","Detailed","selectedSectorNodes","cadNode","isSectorNode","sectorNode","isSectorAcceptedByCurrentFilter","some","isLeaf","bboxNode","createBboxNodeFor","RegExp","allSelectedNodes","Colors","green","lerpHSL","red","yellow","nodesByTimestamp","updatedTimestamp","indexOfNode","determineColor"],"mappings":"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","file":"tools.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})((typeof self !== 'undefined' ? self : this), function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"https://apps-cdn.cogniteapp.com/@cognite/reveal-parser-worker/1.3.0/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 65);\n","module.exports = require(\"three\");","/*!\n * Copyright 2021 Cognite AS\n */\n\ninterface WithChildren<T> {\n readonly children: T[];\n}\n\nexport function traverseDepthFirst<T extends WithChildren<T>>(root: T, visitor: (element: T) => boolean): void {\n if (!visitor(root)) {\n return;\n }\n\n for (let i = 0; i < root.children.length; i++) {\n traverseDepthFirst(root.children[i], visitor);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\nimport { CameraConfiguration } from './CameraConfiguration';\n\nexport function transformCameraConfiguration(\n cameraConfiguration: CameraConfiguration | undefined,\n modelMatrix: THREE.Matrix4\n): CameraConfiguration | undefined {\n if (cameraConfiguration === undefined) {\n return undefined;\n }\n\n const { position, target } = cameraConfiguration;\n position.applyMatrix4(modelMatrix);\n target.applyMatrix4(modelMatrix);\n return {\n position,\n target\n };\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\n/**\n * Utility class for creating reasonable visible colors. Mainly meant for use\n * in debugging.\n */\nexport class RandomColors {\n private static readonly _colors: Map<number, THREE.Color> = new Map();\n\n /**\n * Returns a color as a THREE.Color.\n * @param colorIndex\n * @returns\n */\n static color(colorIndex: number): THREE.Color {\n const color = RandomColors._colors.get(colorIndex);\n if (color !== undefined) {\n return color;\n }\n\n const newColor = RandomColors.generateRandomColor();\n RandomColors._colors.set(colorIndex, newColor);\n return newColor;\n }\n\n /**\n * Returns color as RGB components between 0 and 255.\n * @param colorIndex Return\n * @returns\n */\n static colorRGB(colorIndex: number): [number, number, number] {\n const c = RandomColors.color(colorIndex);\n return [Math.floor(c.r * 255), Math.floor(c.g * 255), Math.floor(c.b * 255)];\n }\n\n /**\n * Returns a color string suitable for usage in CSS styles.\n * @param colorIndex\n * @returns\n */\n static colorCSS(colorIndex: number): string {\n const [r, g, b] = RandomColors.colorRGB(colorIndex);\n return `rgb(${r}, ${g}, ${b})`;\n }\n\n /**\n * Returns a random color with reasonable lightness and saturation\n * to make the color easily distinguishable from other colors.\n */\n static generateRandomColor(): THREE.Color {\n const hue = Math.random();\n const saturation = 0.4 + Math.random() * 0.6;\n const lightness = 0.3 + 0.4 * Math.random();\n return new THREE.Color().setHSL(hue, saturation, lightness);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Determines clicked or touched coordinate as offset\n * @param ev An MouseEvent or TouchEvent.\n * @param target HTML element to find coordinates relative to.\n * @returns A struct containing coordinates relative to the HTML element provided.\n */\nexport function clickOrTouchEventOffset(\n ev: MouseEvent | TouchEvent,\n target: HTMLElement\n): { offsetX: number; offsetY: number } {\n const rect = target.getBoundingClientRect();\n\n if (ev instanceof MouseEvent) {\n return {\n offsetX: ev.clientX - rect.left,\n offsetY: ev.clientY - rect.top\n };\n } else if (ev.changedTouches.length > 0) {\n const touch = ev.changedTouches[0];\n return {\n offsetX: touch.clientX - rect.left,\n offsetY: touch.clientY - rect.top\n };\n }\n\n // Invalid event\n return {\n offsetX: -1,\n offsetY: -1\n };\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Subscribable event source.\n */\nexport class EventTrigger<TListener extends (...args: any[]) => void> {\n private readonly _listeners: TListener[] = [];\n\n subscribe(listener: TListener): void {\n this._listeners.push(listener);\n }\n\n unsubscribe(listener: TListener): void {\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n unsubscribeAll(): void {\n this._listeners.splice(0);\n }\n\n fire(...args: Parameters<TListener>): void {\n this._listeners.forEach(listener => listener(...args));\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { clickOrTouchEventOffset } from './clickOrTouchEventOffset';\nimport { EventTrigger } from './EventTrigger';\nimport debounce from 'lodash/debounce';\nimport { assertNever } from '@reveal/utilities';\nimport { Vector2 } from 'three';\n\ntype PointerEventDelegate = (event: { offsetX: number; offsetY: number }) => void;\n\nexport type EventCollection = { [eventName: string]: EventTrigger<(...args: any[]) => void> };\n\nexport class InputHandler {\n private readonly domElement: HTMLElement;\n private static readonly maxMoveDistance = 8;\n private static readonly maxClickDuration = 250;\n\n private readonly _events = {\n click: new EventTrigger<PointerEventDelegate>(),\n hover: new EventTrigger<PointerEventDelegate>()\n };\n\n constructor(domElement: HTMLElement) {\n this.domElement = domElement;\n\n this.setupEventListeners();\n }\n /**\n * @example\n * ```js\n * const onClick = (event) => { console.log(event.offsetX, event.offsetY) };\n * viewer.on('click', onClick);\n * ```\n */\n on(event: 'click' | 'hover', callback: PointerEventDelegate): void {\n switch (event) {\n case 'click':\n this._events.click.subscribe(callback as PointerEventDelegate);\n break;\n\n case 'hover':\n this._events.hover.subscribe(callback as PointerEventDelegate);\n break;\n default:\n assertNever(event);\n }\n }\n\n off(event: 'click' | 'hover', callback: PointerEventDelegate): void {\n switch (event) {\n case 'click':\n this._events.click.unsubscribe(callback as PointerEventDelegate);\n break;\n\n case 'hover':\n this._events.hover.unsubscribe(callback as PointerEventDelegate);\n break;\n default:\n assertNever(event);\n }\n }\n\n dispose(): void {\n disposeOfAllEventListeners(this._events);\n }\n\n private setupEventListeners() {\n const { domElement } = this;\n\n let pointerDown = false;\n let pointerDownTimestamp = 0;\n let validClick = false;\n\n const startOffset = new Vector2();\n\n const onUp = (e: MouseEvent | TouchEvent) => {\n this.handleClickEvent(e, startOffset, pointerDown, validClick, pointerDownTimestamp);\n\n pointerDown = false;\n validClick = false;\n\n // up\n domElement.removeEventListener('mouseup', onUp);\n domElement.removeEventListener('touchend', onUp);\n\n // add back onHover\n domElement.addEventListener('mousemove', this.onHoverCallback);\n };\n\n const onDown = (e: MouseEvent | TouchEvent) => {\n pointerDown = true;\n validClick = true;\n pointerDownTimestamp = e.timeStamp;\n\n const { offsetX, offsetY } = clickOrTouchEventOffset(e, domElement);\n startOffset.set(offsetX, offsetY);\n\n // up\n domElement.addEventListener('mouseup', onUp);\n domElement.addEventListener('touchend', onUp);\n\n // no more onHover\n domElement.removeEventListener('mousemove', this.onHoverCallback);\n };\n\n // down\n domElement.addEventListener('mousedown', onDown);\n domElement.addEventListener('touchstart', onDown);\n\n // on hover callback\n domElement.addEventListener('mousemove', this.onHoverCallback);\n }\n\n private isProperClick(\n e: MouseEvent | TouchEvent,\n startOffset: Vector2,\n pointerDown: boolean,\n validClick: boolean,\n pointerDownTimestamp: number\n ) {\n const { offsetX, offsetY } = clickOrTouchEventOffset(e, this.domElement);\n const clickDuration = e.timeStamp - pointerDownTimestamp;\n\n const hasMovedDuringClick =\n Math.abs(offsetX - startOffset.x) + Math.abs(offsetY - startOffset.y) > InputHandler.maxMoveDistance;\n\n const isProperClick =\n pointerDown && validClick && clickDuration < InputHandler.maxClickDuration && !hasMovedDuringClick;\n\n return isProperClick;\n }\n\n private handleClickEvent(\n e: MouseEvent | TouchEvent,\n startOffset: Vector2,\n pointerDown: boolean,\n validClick: boolean,\n pointerDownTimestamp: number\n ) {\n const isProperClick = this.isProperClick(e, startOffset, pointerDown, validClick, pointerDownTimestamp);\n\n if (isProperClick) {\n this._events.click.fire(clickOrTouchEventOffset(e, this.domElement));\n }\n }\n\n private readonly onHoverCallback = debounce((e: MouseEvent) => {\n this._events.hover.fire(clickOrTouchEventOffset(e, this.domElement));\n }, 100);\n}\n\n/**\n * Method for deleting all external events that are associated with current instance of a class.\n */\nexport function disposeOfAllEventListeners(eventList: EventCollection): void {\n for (const eventType of Object.keys(eventList)) {\n eventList[eventType].unsubscribeAll();\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * See https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#union-exhaustiveness-checking\n */\nexport function assertNever(x: never, message?: string): never {\n throw new Error(message || 'Unexpected object: ' + x);\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nexport class NumericRange {\n readonly from: number;\n readonly count: number;\n readonly toInclusive: number;\n\n constructor(from: number, count: number) {\n if (count < 0) {\n throw new Error('Range cannot have negative number of elements');\n }\n\n this.from = from;\n this.count = count;\n this.toInclusive = from + count - 1;\n }\n\n static createFromInterval(from: number, toInclusive: number): NumericRange {\n return new NumericRange(from, toInclusive - from + 1);\n }\n\n *values(): Generator<number> {\n for (let i = this.from; i <= this.toInclusive; ++i) {\n yield i;\n }\n }\n\n toArray(): number[] {\n return Array.from(this.values());\n }\n\n equal(other: NumericRange): boolean {\n return this.from === other.from && this.count === other.count;\n }\n\n contains(value: number): boolean {\n return value >= this.from && value <= this.toInclusive;\n }\n\n intersects(range: NumericRange): boolean {\n return this.from <= range.toInclusive && this.toInclusive >= range.from;\n }\n\n intersectsOrCoinciding(range: NumericRange): boolean {\n return this.from <= range.toInclusive + 1 && this.toInclusive + 1 >= range.from;\n }\n\n intersectionWith(range: NumericRange): NumericRange | undefined {\n if (!this.intersects(range)) {\n return undefined;\n } else {\n return NumericRange.createFromInterval(\n Math.max(this.from, range.from),\n Math.min(this.toInclusive, range.toInclusive)\n );\n }\n }\n\n isInside(range: NumericRange): boolean {\n return this.from >= range.from && this.toInclusive <= range.toInclusive;\n }\n\n union(range: NumericRange): NumericRange {\n return NumericRange.createFromInterval(\n Math.min(this.from, range.from),\n Math.max(this.toInclusive, range.toInclusive)\n );\n }\n\n forEach(action: (value: number) => void): void {\n for (let i = this.from; i <= this.toInclusive; ++i) {\n action(i);\n }\n }\n\n toString(): string {\n return '(' + this.from + ', ' + this.toInclusive + ')';\n }\n\n static isNumericRange(value: any): value is NumericRange {\n if (!value) return false;\n\n const range = value as NumericRange;\n return range.from !== undefined && range.count !== undefined && range.toInclusive !== undefined;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Computes minimal power-of-two width and height that holds at least the number of elements provided.\n * This is useful to compute texture sizes.\n */\nexport function determinePowerOfTwoDimensions(elementCount: number): { width: number; height: number } {\n const width = Math.max(1, ceilToPowerOfTwo(Math.sqrt(elementCount)));\n const height = Math.max(1, ceilToPowerOfTwo(elementCount / width));\n return { width, height };\n}\n\nconst log2 = Math.log(2);\nfunction ceilToPowerOfTwo(v: number): number {\n return Math.pow(2, Math.ceil(Math.log(v) / log2));\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { IndexNode } from './IndexSet';\nimport { LeafIndexNode } from './LeafIndexNode';\nimport { NumericRange } from '../NumericRange';\nimport assert from 'assert';\n\nexport class IntermediateIndexNode {\n readonly range: NumericRange;\n readonly maxSubtreeDepth: number;\n readonly left: IndexNode;\n readonly right: IndexNode;\n readonly count: number;\n\n constructor(left: IndexNode, right: IndexNode) {\n this.left = left;\n this.right = right;\n\n this.maxSubtreeDepth = Math.max(this.left.maxSubtreeDepth, this.right.maxSubtreeDepth) + 1;\n this.range = NumericRange.createFromInterval(this.left.range.from, this.right.range.toInclusive);\n this.count = this.left.count + this.right.count;\n }\n\n static fromIndexNodesAndBalance(r0: IndexNode, r1: IndexNode): IntermediateIndexNode {\n if (r0.range.from > r1.range.toInclusive + 1) {\n return new IntermediateIndexNode(r1, r0).balance();\n } else if (r0.range.toInclusive + 1 < r1.range.from) {\n return new IntermediateIndexNode(r0, r1).balance();\n } else {\n // Help, overlapping nodes! There is an error somewhere!\n assert(false, 'Internal error in IndexSet: Overlapping nodes');\n }\n }\n\n traverse(visitor: (range: NumericRange) => void): void {\n // Note! The actual ranges are kept in leafs, so we do not visit \"this\"\n this.left.traverse(visitor);\n this.right.traverse(visitor);\n }\n\n contains(index: number): boolean {\n if (!this.range.contains(index)) {\n return false;\n }\n\n return this.left.contains(index) || this.right.contains(index);\n }\n\n addRange(range: NumericRange): IndexNode {\n const canUnionThis = range.intersectsOrCoinciding(this.range);\n\n if (!canUnionThis) {\n // The range is either entirely above or below the range of this node\n if (range.from < this.range.from) {\n const newNode = this.left.addRange(range);\n return IntermediateIndexNode.fromIndexNodesAndBalance(newNode, this.right);\n } else {\n const newNode = this.right.addRange(range);\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left, newNode);\n }\n }\n\n const canUnionLeft = range.intersectsOrCoinciding(this.left.range);\n const canUnionRight = range.intersectsOrCoinciding(this.right.range);\n\n if (canUnionLeft && canUnionRight) {\n // Range intersects both subtrees...\n const [newLeft, leftRange] = this.left.soak(range);\n const [newRight, rightRange] = this.right.soak(range);\n\n const unioned = leftRange.union(rightRange);\n\n if (newLeft === undefined && newRight === undefined) {\n return new LeafIndexNode(unioned);\n } else if (newLeft === undefined && newRight !== undefined) {\n // Last term is added to please compiler\n return newRight.addRange(unioned);\n } else if (newRight === undefined && newLeft !== undefined) {\n // ---\"---\n return newLeft.addRange(unioned);\n }\n\n // We have guaranteed that newLeft and newRight is defined\n const newNode = IntermediateIndexNode.fromIndexNodesAndBalance(newLeft!, newRight!);\n\n return newNode.addRange(unioned);\n } else if (canUnionLeft) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left.addRange(range), this.right);\n } else if (canUnionRight) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left, this.right.addRange(range));\n } else {\n // Range lies between ranges of left and right subtree,\n // add to smallest\n if (this.left.maxSubtreeDepth < this.right.maxSubtreeDepth) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left.addRange(range), this.right);\n } else {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left, this.right.addRange(range));\n }\n }\n }\n\n removeRange(range: NumericRange): IndexNode | undefined {\n // If input range does not intersect with this range, return\n if (!range.intersects(this.range)) {\n return this;\n }\n\n const [newThis, soakedRange] = this.soak(range);\n\n let leftRange: NumericRange | undefined = undefined;\n let rightRange: NumericRange | undefined = undefined;\n\n // If soakedRange extends to either the left or right to the\n // numeric range, we take the ranges extending out and insert anew.\n if (soakedRange.from < range.from) {\n leftRange = NumericRange.createFromInterval(soakedRange.from, range.from - 1);\n }\n\n if (soakedRange.toInclusive > range.toInclusive) {\n rightRange = NumericRange.createFromInterval(range.toInclusive + 1, soakedRange.toInclusive);\n }\n\n if (newThis === undefined) {\n // If all ranges in this was soaked up, create new node with\n // non-empty left and right ranges\n if (leftRange !== undefined && rightRange !== undefined) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(\n new LeafIndexNode(leftRange),\n new LeafIndexNode(rightRange)\n );\n } else if (leftRange != undefined) {\n return new LeafIndexNode(leftRange);\n } else if (rightRange != undefined) {\n return new LeafIndexNode(rightRange);\n } else {\n return undefined;\n }\n } else {\n // Add non-empty left- and right ranges\n let nodeToReturn = newThis;\n\n if (leftRange !== undefined) {\n nodeToReturn = nodeToReturn.addRange(leftRange);\n }\n\n if (rightRange !== undefined) {\n nodeToReturn = nodeToReturn.addRange(rightRange);\n }\n\n return nodeToReturn;\n }\n }\n\n balance(): IntermediateIndexNode {\n const leftSubTreeSize = this.left.maxSubtreeDepth;\n const rightSubTreeSize = this.right.maxSubtreeDepth;\n\n if (rightSubTreeSize + 2 <= leftSubTreeSize) {\n // Left side too deep\n const newLeft = (this.left as IntermediateIndexNode).rotateSmallerRight();\n const newNode = new IntermediateIndexNode(newLeft, this.right).rotateRight().balance();\n return newNode;\n } else if (leftSubTreeSize + 2 <= rightSubTreeSize) {\n // Right side too deep\n const newRight = (this.right as IntermediateIndexNode).rotateSmallerLeft();\n const newNode = new IntermediateIndexNode(this.left, newRight).rotateLeft().balance();\n return newNode;\n }\n\n return this;\n }\n\n clone(): IntermediateIndexNode {\n return IntermediateIndexNode.fromIndexNodesAndBalance(this.left.clone(), this.right.clone());\n }\n\n hasIntersectionWith(node: IndexNode): boolean {\n if (!node.range.intersects(this.range)) {\n return false;\n }\n\n // Make sure containing range is the \"this\"\n if (this.range.isInside(node.range)) {\n return node.hasIntersectionWith(this);\n }\n\n // Here, we know this range is not contained within node range\n if (this.left.range.intersects(node.range) && this.left.hasIntersectionWith(node)) {\n return true;\n }\n\n if (this.right.range.intersects(node.range) && this.right.hasIntersectionWith(node)) {\n return true;\n }\n\n return false;\n }\n\n /*\n * Utilities\n */\n // Soak up/ delete numeric range touching the input range,\n // returning union of soaked ranges and input range\n // This operation is used as a substep when adding a range - the range\n // is first used to \"soak\" up all touching ranges in the tree, since these must be part of a\n // common union range at the end of the insertion. In the end, the range, unioned with\n // all its soaked ranges in the tree, is inserted normally.\n soak(range: NumericRange): [IndexNode | undefined, NumericRange] {\n let [leftRes, leftRange]: [IndexNode | undefined, NumericRange] = [this.left, range];\n let [rightRes, rightRange]: [IndexNode | undefined, NumericRange] = [this.right, range];\n\n // Both subtrees are inside range, soak up everything\n if (this.right.range.isInside(range) && this.left.range.isInside(range)) {\n return [undefined, range];\n }\n\n // Compute what's left on the left, and the soaked-up range\n if (this.left.range.intersectsOrCoinciding(range)) {\n [leftRes, leftRange] = this.left.soak(range);\n }\n\n // Compute what's left on the right, and the soaked-up range\n if (this.right.range.intersectsOrCoinciding(range)) {\n [rightRes, rightRange] = this.right.soak(range);\n }\n\n // The two soaked-up ranges must touch (they both contain the argument range)\n const unionRange = leftRange.union(rightRange);\n\n if (rightRes == undefined) {\n return [leftRes, unionRange];\n } else if (leftRes == undefined) {\n return [rightRes, unionRange];\n } else {\n const newNode = IntermediateIndexNode.fromIndexNodesAndBalance(leftRes, rightRes);\n return [newNode, unionRange];\n }\n }\n\n /*\n * Rotations\n */\n rotateRight(): IntermediateIndexNode {\n if (!('right' in this.left)) {\n // Left node is leaf node. Abort rotation\n return this;\n }\n\n return new IntermediateIndexNode(\n (this.left as IntermediateIndexNode).left,\n new IntermediateIndexNode((this.left as IntermediateIndexNode).right, this.right)\n );\n }\n\n rotateLeft(): IntermediateIndexNode {\n if (!('left' in this.right)) {\n // Left node is leaf node. Abort rotation\n return this;\n }\n\n return new IntermediateIndexNode(\n new IntermediateIndexNode(this.left, (this.right as IntermediateIndexNode).left),\n (this.right as IntermediateIndexNode).right\n );\n }\n\n // Rotate so that smaller subtree is on left\n rotateSmallerLeft(): IntermediateIndexNode {\n if (this.left.maxSubtreeDepth > this.right.maxSubtreeDepth) {\n // If left subtree depth is larger, it must be of type IntermediateIndexNode\n let nextRoot = this.rotateRight() as IntermediateIndexNode;\n nextRoot = nextRoot.rotateSmallerLeft();\n return nextRoot;\n }\n\n return this;\n }\n\n // Rotate so that smaller subtree is on right\n rotateSmallerRight(): IntermediateIndexNode {\n if (this.right.maxSubtreeDepth > this.left.maxSubtreeDepth) {\n // If left subtree depth is larger, it must be of type IntermediateIndexNode\n let nextRoot = this.rotateLeft() as IntermediateIndexNode;\n nextRoot = nextRoot.rotateSmallerRight();\n return nextRoot;\n }\n\n return this;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS../NumericRange\n */\nimport { IntermediateIndexNode } from './IntermediateIndexNode';\nimport { IndexNode } from './IndexSet';\nimport { NumericRange } from '../NumericRange';\n\nexport class LeafIndexNode {\n readonly range: NumericRange;\n readonly count: number;\n readonly maxSubtreeDepth: number;\n\n static fromInterval(begin: number, endInclusive: number): LeafIndexNode {\n return new LeafIndexNode(NumericRange.createFromInterval(begin, endInclusive));\n }\n\n constructor(range: NumericRange) {\n this.range = range;\n this.maxSubtreeDepth = 0;\n this.count = range.count;\n }\n\n traverse(visitor: (range: NumericRange) => void): void {\n visitor(this.range);\n }\n\n contains(index: number): boolean {\n return this.range.contains(index);\n }\n\n addRange(range: NumericRange): IndexNode {\n if (this.range.intersectsOrCoinciding(range)) {\n // Create union range\n return new LeafIndexNode(this.range.union(range));\n }\n\n return IntermediateIndexNode.fromIndexNodesAndBalance(this, new LeafIndexNode(range));\n }\n\n removeRange(range: NumericRange): IndexNode | undefined {\n if (!range.intersects(this.range)) {\n return this;\n }\n\n if (this.range.isInside(range)) {\n return undefined;\n }\n\n let leftRange: NumericRange | undefined = undefined;\n let rightRange: NumericRange | undefined = undefined;\n\n if (this.range.from < range.from) {\n leftRange = NumericRange.createFromInterval(this.range.from, range.from - 1);\n }\n\n if (this.range.toInclusive > range.toInclusive) {\n rightRange = NumericRange.createFromInterval(range.toInclusive + 1, this.range.toInclusive);\n }\n\n if (leftRange != undefined && rightRange != undefined) {\n return IntermediateIndexNode.fromIndexNodesAndBalance(\n new LeafIndexNode(leftRange),\n new LeafIndexNode(rightRange)\n );\n } else if (leftRange != undefined) {\n return new LeafIndexNode(leftRange);\n } else if (rightRange != undefined) {\n return new LeafIndexNode(rightRange);\n } else {\n return undefined;\n }\n }\n\n hasIntersectionWith(node: IndexNode): boolean {\n return node.range.intersects(this.range);\n }\n\n soak(range: NumericRange): [IndexNode | undefined, NumericRange] {\n if (this.range.intersectsOrCoinciding(range)) {\n return [undefined, this.range.union(range)];\n } else {\n return [this, range];\n }\n }\n\n clone(): LeafIndexNode {\n return new LeafIndexNode(this.range);\n }\n}\n","/*\n * Copyright 2021 Cognite AS\n */\nimport { IntermediateIndexNode } from './IntermediateIndexNode';\nimport { LeafIndexNode } from './LeafIndexNode';\nimport { NumericRange } from '../NumericRange';\n\nexport type IndexNode = IntermediateIndexNode | LeafIndexNode;\n\nexport class IndexSet {\n rootNode?: IndexNode;\n\n constructor(values?: Iterable<number>);\n constructor(values?: NumericRange);\n constructor(values?: Iterable<number> | NumericRange) {\n if (values == undefined) {\n this.rootNode = undefined;\n } else if (NumericRange.isNumericRange(values)) {\n this.addRange(values);\n } else {\n for (const index of values) {\n this.add(index);\n }\n }\n }\n\n forEachRange(visitor: (range: NumericRange) => void): void {\n if (this.rootNode) {\n this.rootNode.traverse(visitor);\n }\n }\n\n add(index: number): void {\n const range = new NumericRange(index, 1);\n\n this.addRange(range);\n }\n\n addRange(range: NumericRange): void {\n if (this.rootNode) {\n this.rootNode = this.rootNode.addRange(range);\n } else {\n this.rootNode = new LeafIndexNode(range);\n }\n }\n\n remove(index: number): void {\n const range = new NumericRange(index, 1);\n this.removeRange(range);\n }\n\n removeRange(range: NumericRange): void {\n if (this.rootNode) {\n this.rootNode = this.rootNode.removeRange(range);\n }\n\n // Do nothing if root is empty\n }\n\n contains(index: number): boolean {\n if (this.rootNode) {\n return this.rootNode.contains(index);\n }\n\n return false;\n }\n\n get count(): number {\n if (this.rootNode) {\n return this.rootNode.count;\n }\n\n return 0;\n }\n\n toRangeArray(): NumericRange[] {\n const ranges: NumericRange[] = [];\n this.forEachRange(range => {\n ranges.push(range);\n });\n return ranges;\n }\n\n toIndexArray(): number[] {\n const result: number[] = [];\n\n if (this.rootNode) {\n this.forEachRange(range => {\n range.forEach(num => {\n result.push(num);\n });\n });\n }\n\n return result;\n }\n\n toPlainSet(): Set<number> {\n const arr: number[] = this.toIndexArray();\n const st = new Set(arr);\n return st;\n }\n\n // NB: Assumes that this.ranges() are in order from left to right\n invertedRanges(): NumericRange[] {\n const originalRanges = this.toRangeArray();\n\n const newRanges: NumericRange[] = [];\n\n for (let i = 0; i < originalRanges.length - 1; i++) {\n if (originalRanges[i].toInclusive + 1 >= originalRanges[i + 1].from) {\n // Should not happen, but let's be safe\n continue;\n }\n newRanges.push(\n NumericRange.createFromInterval(originalRanges[i].toInclusive + 1, originalRanges[i + 1].from - 1)\n );\n }\n\n return newRanges;\n }\n\n unionWith(otherSet: IndexSet): IndexSet {\n if (this.rootNode) {\n otherSet.forEachRange(range => {\n this.rootNode = this.rootNode!.addRange(range);\n });\n } else {\n this.rootNode = otherSet.rootNode;\n }\n\n return this;\n }\n\n differenceWith(otherSet: IndexSet): IndexSet {\n if (this.rootNode) {\n otherSet.forEachRange(range => {\n this.rootNode = this.rootNode?.removeRange(range);\n });\n }\n\n return this;\n }\n\n hasIntersectionWith(otherSet: IndexSet | Set<number>): boolean {\n if (otherSet instanceof IndexSet) {\n if (this.rootNode === undefined || otherSet.rootNode === undefined) {\n return false;\n }\n\n return this.rootNode.hasIntersectionWith(otherSet.rootNode);\n } else {\n for (const index of otherSet) {\n if (this.contains(index)) {\n return true;\n }\n }\n\n return false;\n }\n }\n\n intersectWith(otherSet: IndexSet): IndexSet {\n if (this.rootNode && otherSet.rootNode) {\n // Tackle endpoints\n // Remove left bounds outside input set\n if (this.rootNode.range.from < otherSet.rootNode.range.from) {\n const leftBoundRange = NumericRange.createFromInterval(\n this.rootNode.range.from,\n otherSet.rootNode.range.from - 1\n );\n this.rootNode = this.rootNode.removeRange(leftBoundRange);\n\n if (!this.rootNode) {\n return this;\n }\n }\n\n // Remove right bounds outside input set\n if (this.rootNode.range.toInclusive > otherSet.rootNode.range.toInclusive) {\n const rightBoundRange = NumericRange.createFromInterval(\n otherSet.rootNode.range.toInclusive + 1,\n this.rootNode.range.toInclusive\n );\n this.rootNode = this.rootNode.removeRange(rightBoundRange);\n }\n\n // Invert otherSet ranges and remove them\n const invRanges = otherSet.invertedRanges();\n\n invRanges.forEach(range => {\n if (this.rootNode) {\n this.rootNode = this.rootNode.removeRange(range);\n }\n });\n } else if (this.rootNode) {\n // Otherset is empty, set this to empty as well\n this.rootNode = undefined;\n }\n return this;\n }\n\n clear(): void {\n this.rootNode = undefined;\n }\n\n clone(): IndexSet {\n const st: IndexSet = new IndexSet();\n\n if (this.rootNode) {\n st.rootNode = this.rootNode.clone();\n }\n\n return st;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n// https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float @ Arjan\n\nexport function packFloat(f: number): [number, number, number, number] {\n const F = abs(f);\n if (F == 0) {\n return [0, 0, 0, 0];\n }\n const Sign = step(0.0, -f);\n let Exponent = floor(log2(F));\n\n const Mantissa = F / exp2(Exponent);\n\n if (Mantissa < 1) Exponent -= 1;\n\n Exponent += 127;\n\n const rgba: [number, number, number, number] = [\n 128.0 * Sign + floor(Exponent * exp2(-1.0)),\n 128.0 * mod(Exponent, 2.0) + mod(floor(Mantissa * 128.0), 128.0),\n floor(mod(floor(Mantissa * exp2(23.0 - 8.0)), exp2(8.0))),\n floor(exp2(23.0) * mod(Mantissa, exp2(-15.0)))\n ];\n return rgba;\n}\n\nexport function packFloatInto(f: number, targetBuffer: Uint8ClampedArray, offset: number): void {\n const F = abs(f);\n if (F == 0) {\n return;\n }\n const Sign = step(0.0, -f);\n let Exponent = floor(log2(F));\n\n const Mantissa = F / exp2(Exponent);\n\n if (Mantissa < 1) Exponent -= 1;\n\n Exponent += 127;\n\n targetBuffer[offset] = 128.0 * Sign + floor(Exponent * exp2(-1.0));\n targetBuffer[offset + 1] = 128.0 * mod(Exponent, 2.0) + mod(floor(Mantissa * 128.0), 128.0);\n targetBuffer[offset + 2] = floor(mod(floor(Mantissa * exp2(23.0 - 8.0)), exp2(8.0)));\n targetBuffer[offset + 3] = floor(exp2(23.0) * mod(Mantissa, exp2(-15.0)));\n}\n\nexport function unpackFloat4(packedFloat: [number, number, number, number]): number {\n const [r, g, b, a] = packedFloat;\n const sign = 1.0 - step(128.0, r) * 2.0;\n const exponent = 2.0 * mod(r, 128.0) + step(128.0, g) - 127.0;\n if (exponent == -127) return 0;\n const mantissa = mod(g, 128.0) * 65536.0 + b * 256.0 + a + 8388608.0;\n return sign * exp2(exponent - 23.0) * mantissa;\n}\n\nfunction step(edge: number, x: number): number {\n return x < edge ? 0.0 : 1.0;\n}\n\nfunction exp2(x: number) {\n return Math.pow(2, x);\n}\n\nfunction mod(x: number, y: number) {\n return x - y * floor(x / y);\n}\n\nfunction floor(x: number) {\n return Math.floor(x);\n}\n\nfunction log2(x: number) {\n return Math.log(x) / Math.log(2);\n}\n\nfunction abs(x: number) {\n return Math.abs(x);\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { TypedArray } from '../types';\n\ntype Batch = {\n from: number;\n count: number;\n prev: Batch | undefined;\n next: Batch | undefined;\n};\n\nexport class DynamicDefragmentedBuffer<T extends TypedArray> {\n public get length(): number {\n return this._numFilled;\n }\n\n public get buffer(): T {\n return this._buffer;\n }\n\n private _buffer: T;\n private _numFilled: number;\n private readonly _type: new (length: number) => T;\n\n private readonly _batchMap: Map<number, Batch>;\n private _currentTail: Batch | undefined;\n\n private _batchIdCounter: number;\n\n constructor(initialSize: number, type: new (length: number) => T) {\n this._numFilled = 0;\n this._batchIdCounter = 0;\n this._batchMap = new Map<number, Batch>();\n\n this._type = type;\n\n const minimalPowerOfTwo = Math.pow(2, Math.ceil(Math.log2(initialSize)));\n this._buffer = new type(minimalPowerOfTwo);\n }\n\n public add(array: T): { batchId: number; bufferIsReallocated: boolean } {\n let isReallocated = false;\n if (this._numFilled + array.length > this._buffer.length) {\n const newSize = Math.pow(2, Math.ceil(Math.log2(this._numFilled + array.length)));\n this.allocateNewBuffer(newSize);\n isReallocated = true;\n }\n\n this._buffer.set(array, this._numFilled);\n\n const batchId = this.createBatch(array);\n\n this._numFilled += array.length;\n\n return { batchId: batchId, bufferIsReallocated: isReallocated };\n }\n\n public remove(batchId: number): void {\n const batch = this._batchMap.get(batchId);\n\n if (!batch) {\n throw new Error('batch does not exist in buffer');\n }\n\n this._buffer.copyWithin(batch.from, batch.from + batch.count, this.buffer.length);\n\n this._numFilled -= batch.count;\n\n if (this._currentTail === batch) {\n this._currentTail = batch.prev;\n }\n\n const prev = batch.prev;\n const next = batch.next;\n\n if (prev) {\n prev.next = next;\n }\n\n if (next) {\n next.prev = prev;\n }\n\n let currentBatch = next;\n\n while (currentBatch) {\n currentBatch.from -= batch.count;\n currentBatch = currentBatch.next;\n }\n\n this._batchMap.delete(batchId);\n }\n\n private createBatch(array: T) {\n const batch: Batch = {\n from: this._numFilled,\n count: array.length,\n prev: this._currentTail,\n next: undefined\n };\n\n if (this._currentTail) {\n this._currentTail.next = batch;\n }\n\n this._currentTail = batch;\n\n const batchId = this._batchIdCounter;\n this._batchIdCounter++;\n\n this._batchMap.set(batchId, batch);\n return batchId;\n }\n\n private allocateNewBuffer(newSize: number): void {\n const newBuffer = new this._type(newSize);\n newBuffer.set(this._buffer);\n\n this._buffer = newBuffer;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nconst emptyGeometry = new THREE.BufferGeometry();\n\n/**\n * Referenced count implementation of THREE.Group that\n * automatically disposes all geometries contained in meshes that\n * are direct children of the group.\n */\nexport class AutoDisposeGroup extends THREE.Group {\n private _isDisposed = false;\n private _referenceCount = 0;\n\n reference(): void {\n this.ensureNotDisposed();\n this._referenceCount++;\n }\n\n dereference(): void {\n this.ensureNotDisposed();\n if (this._referenceCount === 0) {\n throw new Error('No references');\n }\n if (--this._referenceCount === 0) {\n this.dispose();\n }\n }\n\n private dispose(): void {\n this.ensureNotDisposed();\n this._isDisposed = true;\n const meshes: THREE.Mesh[] = this.children.filter(x => x instanceof THREE.Mesh).map(x => x as THREE.Mesh);\n for (const mesh of meshes) {\n if (mesh.geometry !== undefined) {\n mesh.geometry.dispose();\n // // NOTE: Forcefully creating a new reference here to make sure\n // // there are no lingering references to the large geometry buffer\n mesh.geometry = emptyGeometry;\n }\n }\n }\n\n private ensureNotDisposed() {\n if (this._isDisposed) {\n throw new Error('Already disposed/dereferenced');\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\n// For BoundingBoxLOD.update()\nconst updateVars = {\n camPos: new THREE.Vector3(),\n bounds: new THREE.Box3()\n};\n\n/**\n * Class similar to THREE.LOD except that it doesn't use `matrixWorld` to determine distance to camera, but a\n * bounding box.\n */\nexport class BoundingBoxLOD extends THREE.Object3D {\n private readonly _boundingBox: THREE.Box3;\n private _activeLevel = 0;\n private readonly _levels: { distance: number; object: THREE.Object3D }[] = [];\n\n // Note! isLOD and autoUpdate is used by WebGLRenderer to perform automatic update of LOD\n // level before rendering\n public readonly isLOD = true;\n public readonly autoUpdate = true;\n\n constructor(boundingBox: THREE.Box3) {\n super();\n this._boundingBox = boundingBox.clone();\n this.type = 'BoundingBoxLOD';\n }\n\n setBoundingBox(boundingBox: THREE.Box3): void {\n this._boundingBox.copy(boundingBox);\n }\n\n addLevel(object: THREE.Object3D, distance: number = 0): void {\n this._levels.push({ object, distance: Math.abs(distance) });\n this._levels.sort((a, b) => b.distance - a.distance);\n object.visible = false;\n this.add(object);\n }\n\n /**\n * Returns the index of the current active LOD. 0 means highest detail.\n */\n getCurrentLevel(): number {\n return this._levels.length > 0 ? this._levels.length - this._activeLevel - 1 : 0;\n }\n\n /**\n * Update selected LOD level based on distance to camera.\n */\n update(camera: THREE.Camera): void {\n this.updateCurrentLevel(camera);\n }\n\n private updateCurrentLevel(camera: THREE.Camera) {\n const levels = this._levels;\n const { camPos, bounds } = updateVars;\n bounds.copy(this._boundingBox).applyMatrix4(this.matrixWorld);\n const cameraZoom = camera instanceof THREE.PerspectiveCamera ? camera.zoom : 1.0;\n\n if (levels.length > 0) {\n camPos.setFromMatrixPosition(camera.matrixWorld);\n const distanceToCamera = bounds.distanceToPoint(camPos) / cameraZoom;\n\n levels[this._activeLevel].object.visible = false;\n this._activeLevel = levels.findIndex(p => distanceToCamera >= p.distance);\n this._activeLevel = this._activeLevel >= 0 ? this._activeLevel : levels.length - 1;\n levels[this._activeLevel].object.visible = true;\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\nexport function getBox3CornerPoints(box: THREE.Box3): THREE.Vector3[] {\n return [\n new THREE.Vector3(box.min.x, box.min.y, box.min.z), // 000\n new THREE.Vector3(box.min.x, box.min.y, box.max.z), // 001\n new THREE.Vector3(box.min.x, box.max.y, box.min.z), // 010\n new THREE.Vector3(box.min.x, box.max.y, box.max.z), // 011\n new THREE.Vector3(box.max.x, box.min.y, box.min.z), // 100\n new THREE.Vector3(box.max.x, box.min.y, box.max.z), // 101\n new THREE.Vector3(box.max.x, box.max.y, box.min.z), // 110\n new THREE.Vector3(box.max.x, box.max.y, box.max.z) // 111\n ];\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nexport function isMobileOrTablet(): boolean {\n // https://stackoverflow.com/a/11381730/167251\n let check = false;\n (a => {\n if (\n /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(\n a\n ) ||\n /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(\n a.substr(0, 4)\n )\n ) {\n check = true;\n }\n })(navigator.userAgent || navigator.vendor || (window as any).opera);\n return check;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\ntype WebGLRendererState = {\n autoClear?: boolean;\n clearColor?: THREE.Color | string | number;\n clearAlpha?: number;\n size?: THREE.Vector2;\n localClippingEnabled?: boolean;\n renderTarget?: THREE.RenderTarget | null;\n};\n\nexport class WebGLRendererStateHelper {\n private _originalState: WebGLRendererState = {};\n private readonly _renderer: THREE.WebGLRenderer;\n\n constructor(renderer: THREE.WebGLRenderer) {\n this._renderer = renderer;\n this._originalState = {};\n }\n\n setClearColor(color: THREE.Color | number | string, alpha?: number): void {\n this._originalState = {\n clearColor: this._renderer.getClearColor(new THREE.Color()),\n clearAlpha: this._renderer.getClearAlpha(),\n ...this._originalState\n };\n this._renderer.setClearColor(color, alpha);\n }\n\n setSize(width: number, height: number): void {\n this._originalState = { size: this._renderer.getSize(new THREE.Vector2()), ...this._originalState };\n this._renderer.setSize(width, height);\n }\n\n set localClippingEnabled(enabled: boolean) {\n this._originalState = { localClippingEnabled: this._renderer.localClippingEnabled, ...this._originalState };\n this._renderer.localClippingEnabled = enabled;\n }\n\n set autoClear(enabled: boolean) {\n this._originalState = { autoClear: this._renderer.autoClear, ...this._originalState };\n this._renderer.autoClear = enabled;\n }\n\n setRenderTarget(renderTarget: THREE.RenderTarget | null): void {\n this._originalState = { renderTarget: this._renderer.getRenderTarget(), ...this._originalState };\n this._renderer.setRenderTarget(renderTarget);\n }\n\n resetState(): void {\n if (this._originalState.autoClear !== undefined) {\n this._renderer.autoClear = this._originalState.autoClear;\n }\n if (this._originalState.clearColor !== undefined) {\n this._renderer.setClearColor(this._originalState.clearColor, this._originalState.clearAlpha);\n }\n if (this._originalState.localClippingEnabled !== undefined) {\n this._renderer.localClippingEnabled = this._originalState.localClippingEnabled;\n }\n if (this._originalState.size !== undefined) {\n this._renderer.setSize(this._originalState.size.width, this._originalState.size.height);\n }\n if (this._originalState.renderTarget !== undefined) {\n this._renderer.setRenderTarget(this._originalState.renderTarget);\n }\n\n this._originalState = {};\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Used to specify custom url for worker/wasm files\n * in cases when you need the latest local files or CDN is blocked by CSP.\n */\nexport const revealEnv = {\n publicPath: ''\n};\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { wrap } from 'comlink';\nimport { RevealParserWorker } from '@cognite/reveal-parser-worker';\nimport { revealEnv } from '../revealEnv';\nimport { isTheSameDomain } from '../networking/isTheSameDomain';\n\nimport log from '@reveal/logger';\n\ntype WorkDelegate<T> = (worker: RevealParserWorker) => Promise<T>;\n\ninterface PooledWorker {\n // The worker returned by Comlink.wrap is not strictly speaking a RevealParserWorker,\n // but it should expose the same functions\n worker: RevealParserWorker;\n activeJobCount: number;\n messageIdCounter: number;\n}\n\nexport class WorkerPool {\n static get defaultPool(): WorkerPool {\n WorkerPool._defaultPool = WorkerPool._defaultPool || new WorkerPool();\n return WorkerPool._defaultPool;\n }\n\n private static _defaultPool: WorkerPool | undefined;\n\n private readonly workerList: PooledWorker[] = [];\n\n private workerObjUrl?: string;\n\n constructor() {\n const numberOfWorkers = this.determineNumberOfWorkers();\n\n for (let i = 0; i < numberOfWorkers; i++) {\n const newWorker = {\n // NOTE: As of Comlink 4.2.0 we need to go through unknown before RevealParserWorker\n // Please feel free to remove `as unknown` if possible.\n worker: wrap(this.createWorker()) as unknown as RevealParserWorker,\n activeJobCount: 0,\n messageIdCounter: 0\n };\n this.workerList.push(newWorker);\n }\n\n if (process.env.NODE_ENV !== 'test') {\n checkWorkerVersion(this.workerList[0].worker).catch(x => log.error(x));\n }\n\n if (this.workerObjUrl) {\n URL.revokeObjectURL(this.workerObjUrl);\n }\n }\n\n // Used to construct workers with or without importScripts usage to overcome CORS.\n // When publicPath is not set we need to fetch worker from CDN (perform cross-origin request)\n // and that's possible only with importScripts.\n // If publicPath is set and points on the same domain, we use it normally.\n private createWorker() {\n const workerUrl = (revealEnv.publicPath || __webpack_public_path__) + 'reveal.parser.worker.js';\n const options = { name: `reveal.parser #${this.workerList.length}` };\n\n if (isTheSameDomain(workerUrl)) {\n return new Worker(workerUrl, options);\n }\n\n if (!this.workerObjUrl) {\n const blob = new Blob([`importScripts(${JSON.stringify(workerUrl)});`], {\n type: 'text/javascript'\n });\n this.workerObjUrl = URL.createObjectURL(blob);\n }\n\n return new Worker(this.workerObjUrl, options);\n }\n\n async postWorkToAvailable<T>(work: WorkDelegate<T>): Promise<T> {\n const targetWorker = this.workerList.reduce((bestWorker, candidate) => {\n if (bestWorker.activeJobCount > candidate.activeJobCount) {\n return candidate;\n }\n return bestWorker;\n }, this.workerList[0]);\n\n targetWorker.activeJobCount += 1;\n const result = await (async () => {\n try {\n return await work(targetWorker.worker);\n } finally {\n targetWorker.activeJobCount -= 1;\n }\n })();\n\n return result;\n }\n\n // TODO j-bjorne 16-04-2020: Send in constructor instead\n private determineNumberOfWorkers() {\n // Use between 2-4 workers, depending on hardware\n return Math.max(2, Math.min(4, window.navigator.hardwareConcurrency || 2));\n }\n}\n\nexport async function checkWorkerVersion(worker: RevealParserWorker): Promise<void> {\n let actualWorkerVersion: string;\n try {\n actualWorkerVersion = await worker.getVersion();\n } catch (e) {\n // versions below 1.1.1 do not have getVersion method\n // notice also you cannot use 'in' operator on worker object\n // because it's merely a proxy-wrapper over postmessage('methodname')\n // so `'getVersion' in worker` - will be always false\n actualWorkerVersion = '1.1.0';\n }\n const minWorkerVersion = process.env.WORKER_VERSION;\n\n const [majorMin, minorMin, patchMin] = minWorkerVersion.split('.').map(i => parseInt(i, 10));\n const [majorWorker, minorWorker, patchWorker] = actualWorkerVersion.split('.').map(i => parseInt(i, 10));\n\n const errorMessage = `Update your local copy of @cognite/reveal-parser-worker. Required version is ${minWorkerVersion}. Received ${actualWorkerVersion}.`;\n\n if (majorMin !== majorWorker) {\n throw new Error(errorMessage);\n }\n if (minorWorker < minorMin) {\n throw new Error(errorMessage);\n }\n if (minorWorker === minorMin && patchWorker < patchMin) {\n throw new Error(errorMessage);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Use to determine if the strings that represent urls\n * are pointing on different domains.\n * @param url1\n * @param url2 Optional. Default is `location.origin`. If provided then it must be\n * absolute url to avoid comparison between two relative urls.\n */\nexport function isTheSameDomain(url1: string, url2: string = location.origin): boolean {\n const isRelative = (url: string) => {\n if (url.match(/^.*\\/\\//)) {\n return false; // starts with protocol - means absolute url, e.g. https://foo.bar/baz\n }\n return true;\n };\n\n if (isRelative(url2)) {\n throw new Error(`isTheSameDomain: the second argument must be an absolute url or omitted. Received ${url2}`);\n }\n\n if (isRelative(url1)) {\n return true;\n }\n\n try {\n // url that starts with '//' considered invalid for URL constructor\n // but browsers usually work just fine with them when it comes to links\n // and we just need to compare origins here anyway\n const urls = [url1, url2].map(url => (url.startsWith('//') ? 'https:' + url : url));\n\n const constructedURLs = urls.map(url => new URL(url));\n return constructedURLs[0].host === constructedURLs[1].host;\n } catch (e) {\n console.error(`can not create URLs for ${url1} and ${url2}`, e);\n return false;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { RequestCache } from './RequestCache';\n\nclass TimestampedContainer<T> {\n private _lastAccessTime: number;\n private readonly _value: T;\n\n constructor(value: T) {\n this._value = value;\n this._lastAccessTime = Date.now();\n }\n\n get value() {\n this.touch();\n return this._value;\n }\n\n get lastAccessTime() {\n return this._lastAccessTime;\n }\n\n private touch() {\n this._lastAccessTime = Date.now();\n }\n}\n\nexport interface MemoryRequestCacheOptions {\n maxElementsInCache?: number;\n}\n\nexport class MemoryRequestCache<Key, Data> implements RequestCache<Key, Data> {\n private readonly _maxElementsInCache: number;\n private readonly _data: Map<Key, TimestampedContainer<Data>>;\n private readonly _defaultCleanupCount: number;\n private readonly _removeCallback: ((value: Data) => void) | undefined;\n\n constructor(\n maxElementsInCache: number = 50,\n removeCallback?: (value: Data) => void,\n defaultCleanupCount: number = 10\n ) {\n this._data = new Map();\n this._maxElementsInCache = maxElementsInCache;\n this._defaultCleanupCount = defaultCleanupCount;\n this._removeCallback = removeCallback;\n }\n\n has(id: Key): boolean {\n return this._data.has(id);\n }\n\n forceInsert(id: Key, data: Data): void {\n if (this.isFull()) {\n this.cleanCache(this._defaultCleanupCount);\n }\n this.insert(id, data);\n }\n\n insert(id: Key, data: Data): void {\n if (this._data.size < this._maxElementsInCache) {\n this._data.set(id, new TimestampedContainer(data));\n } else {\n throw new Error('Cache full, please clean Cache and retry adding data');\n }\n }\n\n remove(id: Key): void {\n if (this._removeCallback !== undefined) {\n const value = this._data.get(id);\n if (value !== undefined) {\n this._removeCallback(value.value);\n }\n }\n this._data.delete(id);\n }\n\n get(id: Key): Data {\n const data = this._data.get(id);\n if (data !== undefined) {\n // Don't really like the touch for lastTime being hidden within a get function. Should we maybe make a\n // TimeConstrainedCache interface where the geter is called something like getAndUpdateTimestamp for clarity?\n return data.value;\n }\n throw new Error(`Cache element ${id} does not exist`);\n }\n\n isFull(): boolean {\n return !(this._data.size < this._maxElementsInCache);\n }\n\n cleanCache(count: number): void {\n const allResults = Array.from(this._data.entries());\n allResults.sort((left, right) => {\n return right[1].lastAccessTime - left[1].lastAccessTime;\n });\n for (let i = 0; i < count; i++) {\n const entry = allResults.pop();\n if (entry !== undefined) {\n this.remove(entry[0]);\n } else {\n return;\n }\n }\n }\n\n clear(): void {\n if (this._removeCallback !== undefined) {\n for (const value of this._data.values()) {\n this._removeCallback(value.value);\n }\n }\n this._data.clear();\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n/**\n * A cache that keeps values that is most frequently used (MFU) rather than a more common\n * least recently used (LRU) approach.\n */\nexport class MostFrequentlyUsedCache<TKey, TValue> {\n private readonly _capacity: number;\n private readonly _cache = new Map<TKey, TValue>();\n private readonly _retrieves = new Map<TKey, number>();\n private readonly _disposeCallback: ((value: TValue) => void) | undefined;\n\n constructor(capacity: number, disposeCallback?: (value: TValue) => void) {\n this._capacity = capacity;\n this._disposeCallback = disposeCallback;\n }\n\n get(key: TKey): TValue | undefined {\n const retrieveCount = this._retrieves.get(key) || 0;\n this._retrieves.set(key, retrieveCount + 1);\n return this._cache.get(key);\n }\n\n set(key: TKey, value: TValue): boolean {\n if (this._cache.has(key) || this._capacity < this._cache.size) {\n this._cache.set(key, value);\n return true;\n } else {\n // TODO 2020-12-05 larsmoa: Very inefficient way to set value.\n // We often set a value and discard it a moment later because its not\n // imporant. Fix this.\n this._cache.set(key, value);\n this.ensureWithinCapacity();\n return this._cache.has(key);\n }\n }\n\n remove(key: TKey): boolean {\n this._retrieves.delete(key);\n const value = this._cache.get(key);\n if (value !== undefined) {\n if (this._disposeCallback !== undefined) {\n this._disposeCallback(value);\n }\n this._cache.delete(key);\n return true;\n }\n return false;\n }\n\n clear(): void {\n if (this._disposeCallback !== undefined) {\n for (const value of this._cache.values()) {\n this._disposeCallback(value);\n }\n }\n this._retrieves.clear();\n this._cache.clear();\n }\n\n private ensureWithinCapacity(): void {\n if (this._capacity >= this._cache.size) return;\n const keys = Array.from(this._cache.keys());\n // Figure out what to remove\n const keysForRemoval = keys\n .map(x => ({ key: x, retrivalCount: this._retrieves.get(x) || 0 }))\n .sort((a, b) => a.retrivalCount - b.retrivalCount)\n .slice(0, this._cache.size - this._capacity)\n .map(x => x.key);\n\n for (const key of keysForRemoval) {\n this.remove(key);\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Handler for THREE.BufferAttribute.onUpload() that frees the underlying JS side array\n * of values after they have been uploaded to the GPU.\n *\n * @example\n * const geometry = new THREE.BufferGeometry();\n * const indices = new THREE.Uint32BufferAttribute(mesh.indices.buffer, 1).onUpload(disposeAttributeArrayOnUpload);\n * const vertices = new THREE.Float32BufferAttribute(mesh.vertices.buffer, 3).onUpload(disposeAttributeArrayOnUpload);\n * const colors = new THREE.Float32BufferAttribute(mesh.colors.buffer, 3).onUpload(disposeAttributeArrayOnUpload);\n * const treeIndices = new THREE.Float32BufferAttribute(mesh.treeIndices.buffer, 1).onUpload(disposeAttributeArrayOnUpload);\n */\nexport function disposeAttributeArrayOnUpload(this: { array: ArrayLike<number> }): void {\n (this.array as ArrayLike<number> | null) = null;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { traverseDepthFirst } from '@reveal/utilities';\nimport { SectorScene } from './types';\nimport { SectorMetadata } from '../metadata/types';\nimport skmeans from 'skmeans';\n\nexport class SectorSceneImpl implements SectorScene {\n readonly version: number;\n readonly maxTreeIndex: number;\n readonly root: SectorMetadata;\n readonly unit: string;\n private readonly sectors: Map<number, SectorMetadata>;\n\n constructor(\n version: number,\n maxTreeIndex: number,\n unit: string,\n root: SectorMetadata,\n sectorsById: Map<number, SectorMetadata>\n ) {\n this.version = version;\n this.maxTreeIndex = maxTreeIndex;\n this.root = root;\n this.sectors = sectorsById;\n this.unit = unit;\n }\n\n get sectorCount(): number {\n return this.sectors.size;\n }\n\n getSectorById(sectorId: number): SectorMetadata | undefined {\n return this.sectors.get(sectorId);\n }\n\n getAllSectors(): SectorMetadata[] {\n return [...this.sectors.values()];\n }\n\n getSectorsContainingPoint(p: THREE.Vector3): SectorMetadata[] {\n const accepted: SectorMetadata[] = [];\n traverseDepthFirst(this.root, x => {\n if (x.bounds.containsPoint(p)) {\n accepted.push(x);\n return true;\n }\n return false;\n });\n return accepted;\n }\n\n getSectorsIntersectingBox(b: THREE.Box3): SectorMetadata[] {\n const accepted: SectorMetadata[] = [];\n traverseDepthFirst(this.root, x => {\n if (x.bounds.intersectsBox(b)) {\n accepted.push(x);\n return true;\n }\n return false;\n });\n return accepted;\n }\n\n getBoundsOfMostGeometry(): THREE.Box3 {\n if (this.root.children.length === 0) {\n return this.root.bounds;\n }\n\n // Determine all corners of the bboxes\n const allBounds: THREE.Box3[] = [];\n const corners: number[][] = [];\n traverseDepthFirst(this.root, x => {\n if (x.children.length === 0) {\n corners.push(x.bounds.min.toArray(), x.bounds.max.toArray());\n allBounds.push(x.bounds, x.bounds);\n }\n return true;\n });\n // Cluster the corners into four groups and determine bounds of each cluster\n const numClusters = Math.min(corners.length, 4);\n const clusters = skmeans(corners, numClusters, 'kmpp', 10);\n const clusterCounts = new Array<number>(clusters.idxs.length).fill(0);\n const clusterBounds = clusterCounts.map(_ => new THREE.Box3());\n clusters.idxs.map(x => clusterCounts[x]++);\n const biggestCluster = clusterCounts.reduce(\n (max, count, idx) => {\n if (count > max.count) {\n max.count = count;\n max.idx = idx;\n }\n return max;\n },\n { count: 0, idx: -1 }\n ).idx;\n clusters.idxs.forEach((cluster, idx) => {\n clusterCounts[cluster]++;\n clusterBounds[cluster].expandByPoint(allBounds[idx].min);\n clusterBounds[cluster].expandByPoint(allBounds[idx].max);\n });\n\n const intersectingBounds = clusterBounds.filter((x, idx) => {\n if (idx !== biggestCluster && x.intersectsBox(clusterBounds[biggestCluster])) {\n return true;\n }\n return false;\n });\n if (intersectingBounds.length > 0) {\n // Overlapping clusters - assume it's because the model doesn't contain junk geometry\n const merged = clusterBounds[biggestCluster].clone();\n intersectingBounds.forEach(x => {\n merged.expandByPoint(x.min);\n merged.expandByPoint(x.max);\n });\n return merged;\n } else {\n // Create bounds of the biggest cluster - assume the smallest one is junk geometry\n return clusterBounds[biggestCluster];\n }\n }\n\n getSectorsIntersectingFrustum(\n projectionMatrix: THREE.Matrix4,\n inverseCameraModelMatrix: THREE.Matrix4\n ): SectorMetadata[] {\n const frustumMatrix = new THREE.Matrix4().multiplyMatrices(projectionMatrix, inverseCameraModelMatrix);\n const frustum = new THREE.Frustum().setFromProjectionMatrix(frustumMatrix);\n const accepted: SectorMetadata[] = [];\n traverseDepthFirst(this.root, x => {\n if (frustum.intersectsBox(x.bounds)) {\n accepted.push(x);\n return true;\n }\n return false;\n });\n return accepted;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { SectorMetadata, SectorMetadataFacesFileSection } from '../types';\nimport { SectorScene } from '../../utilities/types';\nimport { SectorSceneImpl } from '../../utilities/SectorScene';\n\nexport interface CadSectorMetadataV8 {\n readonly id: number;\n readonly parentId: number;\n readonly path: string;\n readonly depth: number;\n readonly estimatedDrawCallCount: number;\n readonly estimatedTriangleCount: number;\n\n readonly boundingBox: {\n readonly min: {\n x: number;\n y: number;\n z: number;\n };\n readonly max: {\n x: number;\n y: number;\n z: number;\n };\n };\n readonly indexFile: {\n readonly fileName: string;\n readonly peripheralFiles: string[];\n readonly downloadSize: number;\n };\n readonly facesFile: {\n readonly quadSize: number;\n readonly coverageFactors: {\n xy: number;\n yz: number;\n xz: number;\n };\n readonly recursiveCoverageFactors:\n | {\n xy: number;\n yz: number;\n xz: number;\n }\n | undefined;\n readonly fileName: string | null;\n readonly downloadSize: number;\n } | null;\n}\n\nexport interface CadMetadataV8 {\n readonly version: 8;\n readonly maxTreeIndex: number;\n readonly sectors: CadSectorMetadataV8[];\n readonly unit: string | null;\n\n // Available, but unused:\n // readonly projectId: number;\n // readonly modelId: number;\n // readonly revisionId: number;\n // readonly subRevisionId: number;\n}\n\nexport function parseCadMetadataV8(metadata: CadMetadataV8): SectorScene {\n // Create list of sectors and a map of child -> parent\n const sectorsById = new Map<number, SectorMetadata>();\n const parentIds: number[] = [];\n metadata.sectors.forEach(s => {\n const sector = createSectorMetadata(s);\n sectorsById.set(s.id, sector);\n parentIds[s.id] = s.parentId;\n });\n\n // Establish relationships between sectors\n for (const sector of sectorsById.values()) {\n const parentId = parentIds[sector.id];\n if (parentId === -1) {\n continue;\n }\n const parent = sectorsById.get(parentId)!;\n parent.children.push(sector);\n }\n\n const rootSector = sectorsById.get(0);\n if (!rootSector) {\n throw new Error('Root sector not found, must have ID 0');\n }\n // Check for missing facesFile-sections and provide coverage factors from parents when necessary\n populateCoverageFactorsFromAnchestors(rootSector, rootSector.facesFile);\n\n const unit = metadata.unit !== null ? metadata.unit : 'Meters';\n\n return new SectorSceneImpl(metadata.version, metadata.maxTreeIndex, unit, rootSector, sectorsById);\n}\n\nfunction createSectorMetadata(metadata: CadSectorMetadataV8): SectorMetadata {\n const facesFile = determineFacesFile(metadata);\n\n const bb = metadata.boundingBox;\n const min_x = bb.min.x;\n const min_y = bb.min.y;\n const min_z = bb.min.z;\n const max_x = bb.max.x;\n const max_y = bb.max.y;\n const max_z = bb.max.z;\n return {\n id: metadata.id,\n path: metadata.path,\n depth: metadata.depth,\n bounds: new THREE.Box3(new THREE.Vector3(min_x, min_y, min_z), new THREE.Vector3(max_x, max_y, max_z)),\n estimatedDrawCallCount: metadata.estimatedDrawCallCount,\n estimatedRenderCost: metadata.estimatedTriangleCount || 0,\n\n // I3D\n indexFile: { ...metadata.indexFile },\n // F3D\n facesFile,\n\n // Populated later\n children: []\n };\n}\n\nfunction determineFacesFile(metadata: CadSectorMetadataV8): SectorMetadataFacesFileSection {\n if (!metadata.facesFile) {\n return {\n quadSize: -1.0,\n coverageFactors: {\n xy: -1.0,\n yz: -1.0,\n xz: -1.0\n },\n recursiveCoverageFactors: {\n xy: -1.0,\n yz: -1.0,\n xz: -1.0\n },\n fileName: null,\n downloadSize: metadata.indexFile.downloadSize\n };\n }\n const facesFile = {\n ...metadata.facesFile,\n recursiveCoverageFactors: metadata.facesFile.recursiveCoverageFactors || metadata.facesFile.coverageFactors\n };\n return facesFile;\n}\n\nfunction hasDummyFacesFileSection(metadata: SectorMetadata): boolean {\n return metadata.facesFile.coverageFactors.xy === -1.0;\n}\n\nfunction populateCoverageFactorsFromAnchestors(\n sector: SectorMetadata,\n validFacesFileSection: SectorMetadataFacesFileSection\n) {\n if (hasDummyFacesFileSection(sector)) {\n sector.facesFile.coverageFactors.xy = validFacesFileSection.recursiveCoverageFactors.xy;\n sector.facesFile.coverageFactors.yz = validFacesFileSection.recursiveCoverageFactors.yz;\n sector.facesFile.coverageFactors.xz = validFacesFileSection.recursiveCoverageFactors.xz;\n sector.facesFile.recursiveCoverageFactors.xy = validFacesFileSection.recursiveCoverageFactors.xy;\n sector.facesFile.recursiveCoverageFactors.yz = validFacesFileSection.recursiveCoverageFactors.yz;\n sector.facesFile.recursiveCoverageFactors.xz = validFacesFileSection.recursiveCoverageFactors.xz;\n sector.children.forEach(child => populateCoverageFactorsFromAnchestors(child, validFacesFileSection));\n } else {\n sector.children.forEach(child => populateCoverageFactorsFromAnchestors(child, sector.facesFile));\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { parseCadMetadataV8 } from './parsers/CadMetadataParserV8';\nimport { SectorScene } from '../utilities/types';\n\ninterface VersionHeader {\n readonly version: number;\n}\n\nexport class CadMetadataParser {\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n public parse(parsedJson: any): SectorScene {\n const version = (parsedJson as VersionHeader).version;\n switch (version) {\n case 8:\n return parseCadMetadataV8(parsedJson);\n\n case undefined:\n throw new Error('Metadata must contain a \"version\"-field');\n\n default:\n throw new Error(`Version ${version} is not supported`);\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { SectorMetadata } from '../metadata/types';\n/**\n * Conversion factors from a given unit to meters.\n */\nexport const WellKnownDistanceToMeterConversionFactors = new Map<string, number>([\n ['Meters', 1.0],\n ['Centimeters', 0.01],\n ['Millimeters', 0.001],\n ['Micrometers', 1e-6],\n ['Kilometers', 1000],\n ['Feet', 0.3048],\n ['Inches', 0.0254],\n ['Yards', 0.9144],\n ['Miles', 1609.34],\n ['Mils', 0.0254 * 1e-3],\n ['Microinches', 0.0254 * 1e-6]\n]);\n\nexport interface SectorScene {\n readonly version: number;\n readonly maxTreeIndex: number;\n readonly root: SectorMetadata;\n readonly unit: string;\n\n readonly sectorCount: number;\n getSectorById(sectorId: number): SectorMetadata | undefined;\n getSectorsContainingPoint(p: THREE.Vector3): SectorMetadata[];\n getSectorsIntersectingBox(b: THREE.Box3): SectorMetadata[];\n\n /**\n * Returns bounds that contains \"most geometry\". This bounds is an\n * attempt to remove junk geometry from the bounds to allow e.g. setting\n * a good camera position.\n */\n getBoundsOfMostGeometry(): THREE.Box3;\n\n /**\n * Gets the sectors intersecting the frustum provided from the projection and inverse\n * camera matrix. Note that this function expects matrices in the the coordinate system\n * of the metadata. See below how to convert ThreeJS camera matrices to the correct format.\n *\n * @example Converting a ThreeJS camera to a frustum\n * ```\n * const cameraMatrixWorldInverse = camera.matrixWorldInverse;\n * const cameraProjectionMatrix = camera.projectionMatrix;\n *\n * const transformedCameraMatrixWorldInverse =\n * new THREE.Matrix4().multiplyMatrices(cameraMatrixWorldInverse, model.modelMatrix)\n *\n * const intersectingSectors = model.scene.getSectorsIntersectingFrustum(\n * cameraProjectionMatrix,\n * transformedCameraMatrixWorldInverse\n * );\n * ```\n * @param projectionMatrix\n * @param inverseCameraModelMatrix\n */\n getSectorsIntersectingFrustum(\n projectionMatrix: THREE.Matrix4,\n inverseCameraModelMatrix: THREE.Matrix4\n ): SectorMetadata[];\n getAllSectors(): SectorMetadata[];\n\n // Available, but not supported:\n // readonly projectId: number;\n // readonly modelId: number;\n // readonly revisionId: number;\n // readonly subRevisionId: number;\n // readonly unit: string | null;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { CadMetadataParser } from './CadMetadataParser';\n\nimport { SectorScene, WellKnownDistanceToMeterConversionFactors } from '../utilities/types';\nimport { CadModelMetadata } from './CadModelMetadata';\nimport { MetadataRepository } from './MetadataRepository';\nimport { transformCameraConfiguration } from '@reveal/utilities';\n\nimport { ModelDataProvider, ModelMetadataProvider, ModelIdentifier } from '@reveal/modeldata-api';\n\nexport class CadModelMetadataRepository implements MetadataRepository<Promise<CadModelMetadata>> {\n private readonly _modelMetadataProvider: ModelMetadataProvider;\n private readonly _modelDataProvider: ModelDataProvider;\n private readonly _cadSceneParser: CadMetadataParser;\n private readonly _blobFileName: string;\n private _currentModelIdentifier = 0;\n\n constructor(\n modelMetadataProvider: ModelMetadataProvider,\n modelDataProvider: ModelDataProvider,\n cadMetadataParser: CadMetadataParser,\n blobFileName: string = 'scene.json'\n ) {\n this._modelMetadataProvider = modelMetadataProvider;\n this._modelDataProvider = modelDataProvider;\n this._cadSceneParser = cadMetadataParser;\n this._blobFileName = blobFileName;\n }\n\n async loadData(modelIdentifier: ModelIdentifier): Promise<CadModelMetadata> {\n const blobBaseUrlPromise = this._modelMetadataProvider.getModelUri(modelIdentifier);\n const modelMatrixPromise = this._modelMetadataProvider.getModelMatrix(modelIdentifier);\n const modelCameraPromise = this._modelMetadataProvider.getModelCamera(modelIdentifier);\n\n const blobBaseUrl = await blobBaseUrlPromise;\n const json = await this._modelDataProvider.getJsonFile(blobBaseUrl, this._blobFileName);\n const scene: SectorScene = this._cadSceneParser.parse(json);\n const modelMatrix = createScaleToMetersModelMatrix(scene.unit, await modelMatrixPromise);\n const inverseModelMatrix = new THREE.Matrix4().copy(modelMatrix).invert();\n const cameraConfiguration = await modelCameraPromise;\n\n return {\n modelIdentifier: `${this._currentModelIdentifier++}`, // TODO 2021-10-03 larsmoa: Change to ModelIdentifier\n modelBaseUrl: blobBaseUrl,\n // Clip box is not loaded, it must be set elsewhere\n geometryClipBox: null,\n modelMatrix,\n inverseModelMatrix,\n cameraConfiguration: transformCameraConfiguration(cameraConfiguration, modelMatrix),\n scene\n };\n }\n}\n\nfunction createScaleToMetersModelMatrix(unit: string, modelMatrix: THREE.Matrix4): THREE.Matrix4 {\n const conversionFactor = WellKnownDistanceToMeterConversionFactors.get(unit);\n if (conversionFactor === undefined) {\n throw new Error(`Unknown model unit '${unit}'`);\n }\n\n const scaledModelMatrix = new THREE.Matrix4().makeScale(conversionFactor, conversionFactor, conversionFactor);\n return scaledModelMatrix.multiply(modelMatrix);\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nexport enum LevelOfDetail {\n Discarded,\n Simple,\n Detailed\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { SectorSceneImpl } from './SectorScene';\nimport { SectorMetadata } from '../metadata/types';\nimport { SectorScene } from './types';\n\nimport { traverseDepthFirst } from '@reveal/utilities';\n\nimport assert from 'assert';\n\n/**\n * Factory for creating instance of {@link SectorScene} based on\n * the version of the format provided.\n */\nexport class SectorSceneFactory {\n createSectorScene(version: number, maxTreeIndex: number, unit: string, root: SectorMetadata): SectorScene {\n assert(version === 8, 'Only version 8 is currently supported');\n\n const sectorsById: Map<number, SectorMetadata> = new Map();\n traverseDepthFirst(root, x => {\n sectorsById.set(x.id, x);\n return true;\n });\n return new SectorSceneImpl(version, maxTreeIndex, unit, root, sectorsById);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { AutoDisposeGroup } from '@reveal/utilities';\nimport { LevelOfDetail } from '../cad/LevelOfDetail';\n\nexport class SectorNode extends THREE.Group {\n public readonly sectorPath: string;\n public readonly sectorId: number;\n public readonly bounds: THREE.Box3;\n public readonly depth: number;\n\n private _group?: AutoDisposeGroup;\n private _lod = LevelOfDetail.Discarded;\n private _updatedTimestamp: number = Date.now();\n\n constructor(sectorId: number, sectorPath: string, bounds: THREE.Box3) {\n super();\n this.name = `Sector ${sectorPath} [id=${sectorId}]`;\n this.sectorId = sectorId;\n this.sectorPath = sectorPath;\n this.bounds = bounds;\n this.depth = determineSectorDepth(sectorPath);\n }\n\n get levelOfDetail(): LevelOfDetail {\n return this._lod;\n }\n\n get group(): THREE.Group | undefined {\n return this._group;\n }\n\n get updatedTimestamp(): number {\n return this._updatedTimestamp;\n }\n\n updateGeometry(geomtryGroup: AutoDisposeGroup | undefined, levelOfDetail: LevelOfDetail): void {\n this.resetGeometry();\n this._group = geomtryGroup;\n if (this._group !== undefined) {\n this._group.reference();\n }\n this._lod = levelOfDetail;\n this._updatedTimestamp = Date.now();\n this.visible = this._lod !== LevelOfDetail.Discarded;\n this.updateMatrixWorld(true);\n }\n\n resetGeometry(): void {\n if (this._group !== undefined) {\n this._group.dereference();\n this.remove(this._group);\n }\n\n this._group = undefined;\n this._lod = LevelOfDetail.Discarded;\n this._updatedTimestamp = Date.now();\n }\n}\n\nfunction determineSectorDepth(path: string): number {\n let depth = 0;\n for (let i = 0; i < path.length; ++i) {\n depth += path[i] === '/' ? 1 : 0;\n }\n return depth - 1;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { SectorNode } from './SectorNode';\nimport { SectorMetadata } from '../metadata/types';\nimport { CadModelMetadata } from '../metadata/CadModelMetadata';\n\nexport class RootSectorNode extends SectorNode {\n public readonly sectorNodeMap: Map<number, SectorNode>;\n\n constructor(modelMetadata: CadModelMetadata) {\n const modelBounds = modelMetadata.scene.root.bounds.clone();\n modelBounds.applyMatrix4(modelMetadata.modelMatrix);\n super(0, '/', modelBounds);\n\n const { scene, modelMatrix } = modelMetadata;\n this.sectorNodeMap = new Map();\n buildScene(scene.root, this, this.sectorNodeMap, modelMatrix);\n\n // Disable automatic update of matrices of the subtree as it\n // is quite time consuming. We trust that our owner keeps\n // our matrices updated.\n this.matrixAutoUpdate = false;\n this.setModelTransformation(modelMatrix);\n }\n\n setModelTransformation(matrix: THREE.Matrix4): void {\n this.matrix.copy(matrix);\n this.updateMatrixWorld(true);\n }\n\n getModelTransformation(out = new THREE.Matrix4()): THREE.Matrix4 {\n return out.copy(this.matrix);\n }\n}\n\nfunction buildScene(\n sector: SectorMetadata,\n parent: SectorNode,\n sectorNodeMap: Map<number, SectorNode>,\n modelMatrix: THREE.Matrix4\n) {\n const bounds = sector.bounds.clone();\n bounds.applyMatrix4(modelMatrix);\n const sectorGroup = new SectorNode(sector.id, sector.path, bounds);\n sectorGroup.name = `Sector ${sector.id}`;\n parent.add(sectorGroup);\n sectorGroup.matrixAutoUpdate = false;\n sectorGroup.updateMatrixWorld(true);\n\n sectorNodeMap.set(sector.id, sectorGroup);\n for (const child of sector.children) {\n buildScene(child, sectorGroup, sectorNodeMap, modelMatrix);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { WorkerPool } from '@reveal/utilities';\n\nimport { ParseSectorResult, ParseCtmResult, RevealParserWorker, SectorQuads } from '@cognite/reveal-parser-worker';\n\nexport class CadSectorParser {\n private readonly workerPool: WorkerPool;\n constructor(workerPool: WorkerPool = WorkerPool.defaultPool) {\n this.workerPool = workerPool;\n }\n\n parseI3D(data: Uint8Array): Promise<ParseSectorResult> {\n return this.parseDetailed(data);\n }\n\n parseF3D(data: Uint8Array): Promise<SectorQuads> {\n return this.parseSimple(data);\n }\n\n parseCTM(data: Uint8Array): Promise<ParseCtmResult> {\n return this.parseCtm(data);\n }\n\n private async parseSimple(quadsArrayBuffer: Uint8Array): Promise<SectorQuads> {\n return this.workerPool.postWorkToAvailable<SectorQuads>(async (worker: RevealParserWorker) =>\n worker.parseQuads(quadsArrayBuffer)\n );\n }\n\n private async parseDetailed(sectorArrayBuffer: Uint8Array): Promise<ParseSectorResult> {\n return this.workerPool.postWorkToAvailable(async (worker: RevealParserWorker) =>\n worker.parseSector(sectorArrayBuffer)\n );\n }\n\n private async parseCtm(ctmArrayBuffer: Uint8Array): Promise<ParseCtmResult> {\n return this.workerPool.postWorkToAvailable(async (worker: RevealParserWorker) => worker.parseCtm(ctmArrayBuffer));\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport { ParsePrimitiveAttribute } from '@cognite/reveal-parser-worker';\n\nconst computeBoundingBoxFromCenterAndRadiusAttributesVars = {\n centerA: new THREE.Vector3(),\n centerB: new THREE.Vector3(),\n sphere: new THREE.Sphere(),\n box: new THREE.Box3()\n};\n\nexport function computeBoundingBoxFromCenterAndRadiusAttributes(\n centerAattribute: ParsePrimitiveAttribute,\n centerBattribute: ParsePrimitiveAttribute,\n radiusAattribute: ParsePrimitiveAttribute,\n radiusBattribute: ParsePrimitiveAttribute,\n attributeFloatValues: Float32Array,\n elementSize: number,\n elementIndex: number,\n out: THREE.Box3\n): THREE.Box3 {\n const { centerA, centerB, sphere, box } = computeBoundingBoxFromCenterAndRadiusAttributesVars;\n\n function readAttribute(attribute: ParsePrimitiveAttribute, idx: number = 0): number {\n const offset = (elementIndex * elementSize + attribute.offset) / attributeFloatValues.BYTES_PER_ELEMENT;\n return attributeFloatValues[offset + idx];\n }\n\n centerA.set(\n readAttribute(centerAattribute, 0),\n readAttribute(centerAattribute, 1),\n readAttribute(centerAattribute, 2)\n );\n centerB.set(\n readAttribute(centerBattribute, 0),\n readAttribute(centerBattribute, 1),\n readAttribute(centerBattribute, 2)\n );\n const radiusA = readAttribute(radiusAattribute);\n const radiusB = readAttribute(radiusBattribute);\n\n // Note! Not the tighest fit we could make, works ok for now but could be improved by\n // using normal of each cap to determine exact end points of the top/bottom\n sphere.set(centerA, radiusA);\n sphere.getBoundingBox(out);\n sphere.set(centerB, radiusB);\n sphere.getBoundingBox(box);\n out.expandByPoint(box.min);\n out.expandByPoint(box.max);\n return out;\n}\n\nconst computeBoundingBoxFromVertexAttributesVars = {\n vertex1: new THREE.Vector3(),\n vertex2: new THREE.Vector3(),\n vertex3: new THREE.Vector3(),\n vertex4: new THREE.Vector3()\n};\n\nexport function computeBoundingBoxFromVertexAttributes(\n vertex1Attribute: ParsePrimitiveAttribute,\n vertex2Attribute: ParsePrimitiveAttribute,\n vertex3Attribute: ParsePrimitiveAttribute,\n vertex4Attribute: ParsePrimitiveAttribute,\n attributeFloatValues: Float32Array,\n elementSize: number,\n elementIndex: number,\n out: THREE.Box3\n): THREE.Box3 {\n const { vertex1, vertex2, vertex3, vertex4 } = computeBoundingBoxFromVertexAttributesVars;\n\n function readAttribute(attribute: ParsePrimitiveAttribute, idx: number = 0): number {\n const offset = (elementIndex * elementSize + attribute.offset) / attributeFloatValues.BYTES_PER_ELEMENT;\n return attributeFloatValues[offset + idx];\n }\n\n vertex1.set(\n readAttribute(vertex1Attribute, 0),\n readAttribute(vertex1Attribute, 1),\n readAttribute(vertex1Attribute, 2)\n );\n vertex2.set(\n readAttribute(vertex2Attribute, 0),\n readAttribute(vertex2Attribute, 1),\n readAttribute(vertex2Attribute, 2)\n );\n vertex3.set(\n readAttribute(vertex3Attribute, 0),\n readAttribute(vertex3Attribute, 1),\n readAttribute(vertex3Attribute, 2)\n );\n vertex4.set(\n readAttribute(vertex4Attribute, 0),\n readAttribute(vertex4Attribute, 1),\n readAttribute(vertex4Attribute, 2)\n );\n\n out.setFromPoints([vertex1, vertex2, vertex3, vertex4]);\n return out;\n}\n\nconst computeBoundingBoxFromInstanceMatrixAttributesVars = {\n instanceMatrix: new THREE.Matrix4()\n};\n\nexport function computeBoundingBoxFromInstanceMatrixAttributes(\n instanceMatrixAttribute: ParsePrimitiveAttribute,\n attributeFloatValues: Float32Array,\n elementSize: number,\n elementIndex: number,\n baseBoundingBox: THREE.Box3,\n out: THREE.Box3\n): THREE.Box3 {\n const { instanceMatrix } = computeBoundingBoxFromInstanceMatrixAttributesVars;\n\n const offset = (elementIndex * elementSize + instanceMatrixAttribute.offset) / attributeFloatValues.BYTES_PER_ELEMENT;\n // Note! set() accepts row-major, stored column-major\n instanceMatrix.set(\n attributeFloatValues[offset + 0],\n attributeFloatValues[offset + 4],\n attributeFloatValues[offset + 8],\n attributeFloatValues[offset + 12],\n\n attributeFloatValues[offset + 1],\n attributeFloatValues[offset + 5],\n attributeFloatValues[offset + 9],\n attributeFloatValues[offset + 13],\n\n attributeFloatValues[offset + 2],\n attributeFloatValues[offset + 6],\n attributeFloatValues[offset + 10],\n attributeFloatValues[offset + 14],\n\n attributeFloatValues[offset + 3],\n attributeFloatValues[offset + 7],\n attributeFloatValues[offset + 11],\n attributeFloatValues[offset + 15]\n );\n out.copy(baseBoundingBox).applyMatrix4(instanceMatrix);\n return out;\n}\n\nconst computeBoundingBoxFromEllipseAttributesVars = {\n center: new THREE.Vector3(),\n size: new THREE.Vector3()\n};\n\nexport function computeBoundingBoxFromEllipseAttributes(\n centerAttribute: ParsePrimitiveAttribute,\n radius1Attribute: ParsePrimitiveAttribute,\n radius2Attribute: ParsePrimitiveAttribute,\n heightAttribute: ParsePrimitiveAttribute,\n attributeFloatValues: Float32Array,\n elementSize: number,\n elementIndex: number,\n out: THREE.Box3\n): THREE.Box3 {\n const { center, size } = computeBoundingBoxFromEllipseAttributesVars;\n\n function readAttribute(attribute: ParsePrimitiveAttribute, idx: number = 0): number {\n const offset = (elementIndex * elementSize + attribute.offset) / attributeFloatValues.BYTES_PER_ELEMENT;\n return attributeFloatValues[offset + idx];\n }\n\n center.set(readAttribute(centerAttribute, 0), readAttribute(centerAttribute, 1), readAttribute(centerAttribute, 2));\n const radius1 = readAttribute(radius1Attribute);\n const radius2 = readAttribute(radius2Attribute);\n const height = readAttribute(heightAttribute);\n const extent = 2.0 * Math.max(radius1, radius2, height);\n size.set(extent, extent, extent);\n out.setFromCenterAndSize(center, size);\n return out;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { ParsePrimitiveAttribute } from '@cognite/reveal-parser-worker';\nimport assert from 'assert';\nimport {\n computeBoundingBoxFromCenterAndRadiusAttributes,\n computeBoundingBoxFromEllipseAttributes,\n computeBoundingBoxFromInstanceMatrixAttributes,\n computeBoundingBoxFromVertexAttributes\n} from '../utilities/computeBoundingBoxFromAttributes';\n\nfunction filterPrimitivesOutsideClipBox(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n clipBox: THREE.Box3,\n getBoundsOfElementsCallback: (\n index: number,\n elementSize: number,\n attributeFloatValues: Float32Array,\n outBox: THREE.Box3\n ) => void\n): Uint8Array {\n const elementSize = Array.from(attributes.values()).reduce((a, b) => Math.max(a, b.offset + b.size), 0);\n const elementCount = attributesByteValues.length / elementSize;\n const attributeFloatValues = new Float32Array(attributesByteValues.buffer);\n\n const instanceBbox = new THREE.Box3();\n\n const filteredByteValues = new Uint8Array(attributesByteValues.length);\n let filteredCount = 0;\n for (let i = 0; i < elementCount; ++i) {\n getBoundsOfElementsCallback(i, elementSize, attributeFloatValues, instanceBbox);\n\n if (clipBox.intersectsBox(instanceBbox)) {\n const elementValues = attributesByteValues.subarray(i * elementSize, (i + 1) * elementSize);\n filteredByteValues.set(elementValues, filteredCount * elementSize);\n filteredCount++;\n }\n }\n return filteredByteValues.slice(0, filteredCount * elementSize);\n}\n\nexport function filterPrimitivesOutsideClipBoxByBaseBoundsAndInstanceMatrix(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n baseBox: THREE.Box3,\n geometryClipBox: THREE.Box3 | null\n): Uint8Array {\n if (geometryClipBox === null) {\n return attributesByteValues;\n }\n const instanceMatrixAttribute = attributes.get('instanceMatrix');\n assert(instanceMatrixAttribute !== undefined);\n return filterPrimitivesOutsideClipBox(\n attributesByteValues,\n attributes,\n geometryClipBox,\n (index, elementSize, attributeFloatValues, outBox) => {\n computeBoundingBoxFromInstanceMatrixAttributes(\n instanceMatrixAttribute,\n attributeFloatValues,\n elementSize,\n index,\n baseBox,\n outBox\n );\n }\n );\n}\n\nexport function filterPrimitivesOutsideClipBoxByCenterAndRadius(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n geometryClipBox: THREE.Box3 | null,\n radiusAattributeName: string = 'radiusA',\n radiusBattributeName: string = 'radiusB'\n): Uint8Array {\n if (geometryClipBox === null) {\n return attributesByteValues;\n }\n\n const centerAattribute = attributes.get('centerA');\n const centerBattribute = attributes.get('centerB');\n const radiusAattribute = attributes.get(radiusAattributeName);\n const radiusBattribute = attributes.get(radiusBattributeName);\n assert(\n centerAattribute !== undefined &&\n centerBattribute !== undefined &&\n radiusAattribute !== undefined &&\n radiusBattribute !== undefined\n );\n return filterPrimitivesOutsideClipBox(\n attributesByteValues,\n attributes,\n geometryClipBox,\n (index, elementSize, attributeFloatValues, outBox) => {\n computeBoundingBoxFromCenterAndRadiusAttributes(\n centerAattribute,\n centerBattribute,\n radiusAattribute,\n radiusBattribute,\n attributeFloatValues,\n elementSize,\n index,\n outBox\n );\n }\n );\n}\n\nexport function filterPrimitivesOutsideClipBoxByVertices(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n geometryClipBox: THREE.Box3 | null\n): Uint8Array {\n if (geometryClipBox === null) {\n return attributesByteValues;\n }\n\n const vertex1attribute = attributes.get('vertex1');\n const vertex2attribute = attributes.get('vertex2');\n const vertex3attribute = attributes.get('vertex3');\n const vertex4attribute = attributes.get('vertex4');\n assert(\n vertex1attribute !== undefined &&\n vertex2attribute !== undefined &&\n vertex3attribute !== undefined &&\n vertex4attribute !== undefined\n );\n return filterPrimitivesOutsideClipBox(\n attributesByteValues,\n attributes,\n geometryClipBox,\n (index, elementSize, attributeFloatValues, outBox) => {\n computeBoundingBoxFromVertexAttributes(\n vertex1attribute,\n vertex2attribute,\n vertex3attribute,\n vertex4attribute,\n attributeFloatValues,\n elementSize,\n index,\n outBox\n );\n }\n );\n}\n\nexport function filterPrimitivesOutsideClipBoxByEllipse(\n attributesByteValues: Uint8Array,\n attributes: Map<string, ParsePrimitiveAttribute>,\n geometryClipBox: THREE.Box3 | null,\n radius1AttributeName: string = 'horizontalRadius',\n radius2AttributeName: string = 'verticalRadius'\n): Uint8Array {\n if (geometryClipBox === null) {\n return attributesByteValues;\n }\n const centerAttribute = attributes.get('center');\n const horizontalRadiusAttribute = attributes.get(radius1AttributeName);\n const verticalRadiusAttribute = attributes.get(radius2AttributeName);\n const heightAttribute = attributes.get('height');\n assert(\n centerAttribute !== undefined &&\n horizontalRadiusAttribute !== undefined &&\n verticalRadiusAttribute !== undefined &&\n heightAttribute !== undefined\n );\n return filterPrimitivesOutsideClipBox(\n attributesByteValues,\n attributes,\n geometryClipBox,\n (index, elementSize, attributeFloatValues, outBox) => {\n computeBoundingBoxFromEllipseAttributes(\n centerAttribute,\n horizontalRadiusAttribute,\n verticalRadiusAttribute,\n heightAttribute,\n attributeFloatValues,\n elementSize,\n index,\n outBox\n );\n }\n );\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport { InstancedMesh } from './types';\n\nimport { float32BufferToMatrix } from '../utilities/float32BufferToMatrix';\n\nconst filterInstanceMeshVars = {\n p: new THREE.Vector3(),\n instanceMatrix: new THREE.Matrix4(),\n baseBounds: new THREE.Box3(),\n instanceBounds: new THREE.Box3()\n};\n\nexport function filterInstanceMesh(\n vertices: Float32Array,\n indices: Uint32Array,\n instanceMesh: InstancedMesh,\n geometryClipBox: THREE.Box3 | null\n): InstancedMesh {\n if (geometryClipBox === null) {\n return instanceMesh;\n }\n const { p, instanceMatrix, baseBounds, instanceBounds } = filterInstanceMeshVars;\n\n // Determine base bounds\n baseBounds.makeEmpty();\n for (let j = instanceMesh.triangleOffset; j < instanceMesh.triangleOffset + instanceMesh.triangleCount; ++j) {\n const v0 = indices[3 * j + 0];\n const v1 = indices[3 * j + 1];\n const v2 = indices[3 * j + 2];\n p.set(vertices[v0 + 0], vertices[v0 + 1], vertices[v0 + 2]);\n baseBounds.expandByPoint(p);\n p.set(vertices[v1 + 0], vertices[v1 + 1], vertices[v1 + 2]);\n baseBounds.expandByPoint(p);\n p.set(vertices[v2 + 0], vertices[v2 + 1], vertices[v2 + 2]);\n baseBounds.expandByPoint(p);\n }\n\n let filteredOffset = 0;\n const instanceCount = instanceMesh.treeIndices.length;\n const filteredInstanceMatrices = new Float32Array(instanceMesh.instanceMatrices.length);\n const filteredTreeIndices = new Float32Array(instanceCount);\n const filteredColors = new Uint8Array(4 * instanceCount);\n for (let i = 0; i < instanceCount; ++i) {\n float32BufferToMatrix(instanceMesh.instanceMatrices, i, instanceMatrix);\n\n instanceBounds.copy(baseBounds).applyMatrix4(instanceMatrix);\n if (geometryClipBox.intersectsBox(instanceBounds)) {\n const elementInstanceMatrix = instanceMesh.instanceMatrices.subarray(16 * i, 16 * (i + 1));\n const elementColor = instanceMesh.colors.subarray(4 * i, 4 * (i + 1));\n const elementTreeIndex = instanceMesh.treeIndices[i];\n\n filteredInstanceMatrices.set(elementInstanceMatrix, 16 * filteredOffset);\n filteredColors.set(elementColor, 4 * filteredOffset);\n filteredTreeIndices[filteredOffset] = elementTreeIndex;\n\n filteredOffset++;\n }\n }\n\n if (instanceCount === filteredOffset) {\n return instanceMesh; // Unchanged\n }\n\n const filteredMesh: InstancedMesh = {\n triangleCount: instanceMesh.triangleCount,\n triangleOffset: instanceMesh.triangleOffset,\n instanceMatrices: filteredInstanceMatrices.slice(0, 16 * filteredOffset),\n colors: filteredColors.slice(0, 4 * filteredOffset),\n treeIndices: filteredTreeIndices.slice(0, filteredOffset)\n };\n return filteredMesh;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\n/**\n * Sets the elements of a matrix from a row-major\n * matrix stored in a Float32Array.\n * @param buffer\n * @param indexOffset\n * @param outMatrix\n */\nexport function float32BufferToMatrix(\n buffer: Float32Array,\n indexOffset: number,\n outMatrix: THREE.Matrix4\n): THREE.Matrix4 {\n outMatrix.set(\n buffer[indexOffset + 0],\n buffer[indexOffset + 4],\n buffer[indexOffset + 8],\n buffer[indexOffset + 12],\n\n buffer[indexOffset + 1],\n buffer[indexOffset + 5],\n buffer[indexOffset + 9],\n buffer[indexOffset + 13],\n\n buffer[indexOffset + 2],\n buffer[indexOffset + 6],\n buffer[indexOffset + 10],\n buffer[indexOffset + 14],\n\n buffer[indexOffset + 3],\n buffer[indexOffset + 7],\n buffer[indexOffset + 11],\n buffer[indexOffset + 15]\n );\n return outMatrix;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\n/**\n * Generate a three-dimensional plane geometry,\n * with an optional applied tranformation function (u, v) => [ x, y, z ]\n */\nfunction generatePlane3D(\n segmentsX: number,\n segmentsY: number,\n transformFunc: (u: number, v: number) => number[] = (u, v) => [u, v, 0]\n) {\n const vertices = [];\n const indices = [];\n\n const segmentsXInv = 1 / segmentsX;\n const segmentsYInv = 1 / segmentsY;\n for (let j = 0; j <= segmentsY; j++) {\n for (let i = 0; i <= segmentsX; i++) {\n // vertices\n const [x, y, z] = transformFunc(i * segmentsXInv, j * segmentsYInv);\n vertices.push(x || 0, y || 0, z || 0);\n }\n }\n\n for (let j = 1; j <= segmentsY; j++) {\n for (let i = 1; i <= segmentsX; i++) {\n // indices\n const a = (segmentsX + 1) * j + i - 1;\n const b = (segmentsX + 1) * (j - 1) + i - 1;\n const c = (segmentsX + 1) * (j - 1) + i;\n const d = (segmentsX + 1) * j + i;\n\n // faces\n indices.push(a, b, d);\n indices.push(b, c, d);\n }\n }\n\n return {\n index: new THREE.Uint16BufferAttribute(indices, 1),\n position: new THREE.Float32BufferAttribute(vertices, 3)\n };\n}\n\nexport const { boxGeometry, boxGeometryBoundingBox } = (() => {\n const geometry = new THREE.BoxBufferGeometry(1, 1, 1, 1, 1, 1);\n try {\n const result = {\n index: geometry.getIndex(),\n position: geometry.getAttribute('position'),\n normal: geometry.getAttribute('normal')\n };\n geometry.computeBoundingBox();\n return { boxGeometry: result, boxGeometryBoundingBox: geometry.boundingBox! };\n } finally {\n geometry.dispose();\n }\n})();\n\nexport const { quadGeometry, quadGeometryBoundingBox } = (() => {\n const geometry = new THREE.PlaneBufferGeometry(1, 1, 1, 1);\n try {\n const result = {\n index: geometry.getIndex(),\n position: geometry.getAttribute('position'),\n normal: geometry.getAttribute('normal')\n };\n geometry.computeBoundingBox();\n return { quadGeometry: result, quadGeometryBoundingBox: geometry.boundingBox! };\n } finally {\n geometry.dispose();\n }\n})();\n\nexport const { trapeziumGeometry, trapeziumGeometryBoundingBox } = (() => {\n const index = [0, 1, 3, 0, 3, 2];\n const position = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3];\n return {\n trapeziumGeometry: {\n index: new THREE.BufferAttribute(new Uint16Array(index), 1),\n position: new THREE.BufferAttribute(new Float32Array(position), 3)\n },\n trapeziumGeometryBoundingBox: new THREE.Box3().setFromArray(position)\n };\n})();\n\n// cone\nexport const { coneGeometry, coneGeometryBoundingBox } = (() => {\n const positions = [];\n positions.push(-1, 1, -1);\n positions.push(-1, -1, -1);\n positions.push(1, 1, -1);\n positions.push(1, -1, -1);\n positions.push(1, 1, 1);\n positions.push(1, -1, 1);\n\n const indices = new Uint16Array([1, 2, 0, 1, 3, 2, 3, 4, 2, 3, 5, 4]);\n return {\n coneGeometry: {\n index: new THREE.BufferAttribute(indices, 1),\n position: new THREE.BufferAttribute(new Float32Array(positions), 3)\n },\n coneGeometryBoundingBox: new THREE.Box3().setFromArray(positions)\n };\n})();\n\nexport const {\n torusLodGeometries\n // torusGeometryBoundingBox // Disabled due to error in bounding box computation\n} = (() => {\n const lods = [\n { tubularSegments: 9, radialSegments: 18 },\n { tubularSegments: 5, radialSegments: 12 },\n { tubularSegments: 4, radialSegments: 5 }\n ];\n const transformFunc = (u: number, v: number) => [u, v * 2.0 * Math.PI];\n const torusLodGeometries = lods.map(({ tubularSegments, radialSegments }) => {\n return generatePlane3D(radialSegments, tubularSegments, transformFunc);\n });\n\n return {\n torusLodGeometries\n // TODO 2021-12-10 hflatval: I believe this is wrong, torusLodGeometries are just planes near the origin\n // torusGeometryBoundingBox: new THREE.Box3().setFromArray(\n // torusLodGeometries[torusLodGeometries.length - 1].position.array\n // )\n };\n})();\n\nexport const { nutGeometry, nutGeometryBoundingBox } = (() => {\n const geometry = new THREE.CylinderBufferGeometry(0.5, 0.5, 1, 6);\n try {\n geometry.applyMatrix4(new THREE.Matrix4().makeRotationX(-Math.PI / 2));\n const result = {\n index: geometry.getIndex(),\n position: geometry.getAttribute('position'),\n normal: geometry.getAttribute('normal')\n };\n return { nutGeometry: result, nutGeometryBoundingBox: new THREE.Box3().setFromArray(result.position.array) };\n } finally {\n geometry.dispose();\n }\n})();\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { disposeAttributeArrayOnUpload } from '@reveal/utilities';\nimport { TriangleMesh } from '@reveal/cad-parsers';\n\nexport function createTriangleMeshes(\n triangleMeshes: TriangleMesh[],\n bounds: THREE.Box3,\n material: THREE.ShaderMaterial,\n geometryClipBox: THREE.Box3 | null\n): THREE.Mesh[] {\n const result: THREE.Mesh[] = [];\n\n const filteredTriangleMeshes = triangleMeshes.filter(mesh => {\n return geometryClipBox === null || isTriangleMeshWithin(mesh, geometryClipBox);\n });\n for (const mesh of filteredTriangleMeshes) {\n const geometry = new THREE.BufferGeometry();\n const indices = new THREE.Uint32BufferAttribute(mesh.indices.buffer, 1).onUpload(disposeAttributeArrayOnUpload);\n const vertices = new THREE.Float32BufferAttribute(mesh.vertices.buffer, 3).onUpload(disposeAttributeArrayOnUpload);\n const colors = new THREE.Uint8BufferAttribute(mesh.colors.buffer, 3).onUpload(disposeAttributeArrayOnUpload);\n\n const treeIndices = new THREE.Float32BufferAttribute(mesh.treeIndices.buffer, 1).onUpload(\n disposeAttributeArrayOnUpload\n );\n geometry.setIndex(indices);\n geometry.setAttribute('color', colors);\n geometry.setAttribute('position', vertices);\n geometry.setAttribute('treeIndex', treeIndices);\n geometry.boundingBox = bounds.clone();\n geometry.boundingSphere = new THREE.Sphere();\n bounds.getBoundingSphere(geometry.boundingSphere);\n\n const obj = new THREE.Mesh(geometry, material);\n obj.name = `Triangle mesh ${mesh.fileId}`;\n\n obj.userData.treeIndices = new Set(mesh.treeIndices);\n\n result.push(obj);\n }\n return result;\n}\n\nconst isTriangleMeshWithinArgs = {\n p: new THREE.Vector3(),\n box: new THREE.Box3()\n};\n\nfunction isTriangleMeshWithin(mesh: TriangleMesh, bounds: THREE.Box3): boolean {\n const { p, box } = isTriangleMeshWithinArgs;\n box.makeEmpty();\n for (let i = 0; i < mesh.vertices.length; i += 3) {\n p.set(mesh.vertices[i + 0], mesh.vertices[i + 1], mesh.vertices[i + 2]);\n box.expandByPoint(p);\n }\n return bounds.intersectsBox(box);\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { CogniteClient, HttpHeaders } from '@cognite/sdk';\n\nimport { ModelDataProvider } from './types';\n\n/**\n * Provides 3D V2 specific extensions for the standard CogniteClient used by Reveal.\n */\nexport class CdfModelDataProvider implements ModelDataProvider {\n private readonly client: CogniteClient;\n private authenticationPromise: Promise<boolean>;\n\n constructor(client: CogniteClient) {\n this.client = client;\n this.authenticationPromise = client.authenticate();\n }\n\n get headers(): HttpHeaders {\n return this.client.getDefaultRequestHeaders();\n }\n\n public async getBinaryFile(baseUrl: string, fileName: string): Promise<ArrayBuffer> {\n const url = `${baseUrl}/${fileName}`;\n const headers = {\n ...this.client.getDefaultRequestHeaders(),\n Accept: '*/*'\n };\n\n const response = await this.fetchWithRetry(url, { headers, method: 'GET' });\n return response.arrayBuffer();\n }\n\n async getJsonFile(baseUrl: string, fileName: string): Promise<any> {\n const response = await this.client.get(`${baseUrl}/${fileName}`);\n return response.data;\n }\n\n private async fetchWithRetry(input: RequestInfo, options: RequestInit, retries: number = 3) {\n let error: Error | undefined;\n for (let i = 0; i < retries; i++) {\n try {\n await this.authenticationPromise;\n\n const response = await fetch(input, options);\n\n // Authentication error\n if (response.status === 401) {\n this.authenticationPromise = this.client.authenticate();\n continue;\n }\n\n return response;\n } catch (err) {\n // Keep first error only\n if (error !== undefined) {\n error = err as Error;\n }\n }\n }\n throw error;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport { ModelIdentifier } from '..';\nimport { File3dFormat } from './types';\n\n/**\n * Identifies a 3D model stored in CDF by the combination of a modelId, a revisionId\n * and a format.\n */\nexport class CdfModelIdentifier implements ModelIdentifier {\n readonly revealInternalId: symbol;\n readonly modelFormat: File3dFormat;\n\n readonly modelId: number;\n readonly revisionId: number;\n\n constructor(modelId: number, revisionId: number, modelFormat: File3dFormat) {\n this.revealInternalId = Symbol(`${modelId}/${revisionId}[${modelFormat}]`);\n this.modelId = modelId;\n this.revisionId = revisionId;\n this.modelFormat = modelFormat;\n }\n\n public toString(): string {\n return `${CdfModelIdentifier.name} (${String(this.revealInternalId)} - ${this.modelFormat})`;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { HttpHeaders } from '@cognite/sdk-core';\nexport interface JsonFileProvider {\n getJsonFile(baseUrl: string, fileName: string): Promise<any>;\n}\n\nexport interface BinaryFileProvider {\n getBinaryFile(baseUrl: string, fileName: string): Promise<ArrayBuffer>;\n}\n\n/**\n * Provides data for 3D models.\n * @version New since 2.2\n */\nexport interface ModelDataProvider extends HttpHeadersProvider, JsonFileProvider, BinaryFileProvider {\n /**\n * Download and parse a JSON file and return the resulting struct.\n * @param baseUrl Base URL of the model.\n * @param fileName Filename of JSON file.\n */\n getJsonFile(baseUrl: string, fileName: string): Promise<any>;\n /**\n * Downloads a binary blob.\n * @param baseUrl Base URL of the model.\n * @param fileName Filename of binary file.\n */\n getBinaryFile(baseUrl: string, fileName: string): Promise<ArrayBuffer>;\n}\n\nexport interface HttpHeadersProvider {\n readonly headers: HttpHeaders;\n}\n\nexport enum File3dFormat {\n EptPointCloud = 'ept-pointcloud',\n RevealCadModel = 'reveal-directory',\n AnyFormat = 'all-outputs'\n}\n\nexport interface BlobOutputMetadata {\n blobId: number;\n format: File3dFormat | string;\n version: number;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { File3dFormat } from './types';\n\n// The below is equal to new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(-Math.PI / 2, 0, 0));\nconst cadFromCdfToThreeMatrix = new THREE.Matrix4().set(1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1);\n\nexport function applyDefaultModelTransformation(matrix: THREE.Matrix4, format: File3dFormat | string): void {\n switch (format) {\n case File3dFormat.RevealCadModel:\n matrix.premultiply(cadFromCdfToThreeMatrix);\n break;\n\n case File3dFormat.EptPointCloud:\n // No action, identity transform\n break;\n\n default:\n throw new Error(`Unknown model format '${format}`);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { BlobOutputMetadata, File3dFormat } from './types';\n\nexport class Model3DOutputList {\n public readonly modelId: number;\n public readonly revisionId: number;\n public readonly outputs: BlobOutputMetadata[];\n\n constructor(modelId: number, revisionId: number, outputs: BlobOutputMetadata[]) {\n this.modelId = modelId;\n this.revisionId = revisionId;\n this.outputs = outputs;\n }\n\n /**\n * Finds an output with a given format of the most recent version.\n *\n * @param outputFormat Format to find output for, either a well known format a custom format.\n * @param supportedVersions Optional list of supported version. If not provided all versions are considered.\n */\n public findMostRecentOutput(\n outputFormat: File3dFormat | string,\n supportedVersions?: number[]\n ): BlobOutputMetadata | undefined {\n const candidates = this.outputs.filter(\n x => x.format === outputFormat && (!supportedVersions || supportedVersions.indexOf(x.version) !== -1)\n );\n return candidates.length > 0\n ? candidates.reduce((left, right) => {\n return right.version > left.version ? right : left;\n })\n : undefined;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport { BlobOutputMetadata } from './types';\nimport { ModelMetadataProvider } from './ModelMetadataProvider';\n\nimport { applyDefaultModelTransformation } from './applyDefaultModelTransformation';\nimport { Model3DOutputList } from './Model3DOutputList';\n\nimport { CogniteClient } from '@cognite/sdk';\nimport { ItemsResponse } from '@cognite/sdk-core';\nimport { ModelIdentifier } from './ModelIdentifier';\nimport { CdfModelIdentifier } from './CdfModelIdentifier';\n\n// TODO 2020-06-25 larsmoa: Extend CogniteClient.files3d.retrieve() to support subpath instead of\n// using URLs directly. Also add support for listing outputs in the SDK.\nexport class CdfModelMetadataProvider implements ModelMetadataProvider {\n private readonly _client: CogniteClient;\n\n constructor(client: CogniteClient) {\n this._client = client;\n }\n\n public async getModelMatrix(modelIdentifier: ModelIdentifier): Promise<THREE.Matrix4> {\n if (!(modelIdentifier instanceof CdfModelIdentifier)) {\n throw new Error(`Model must be a ${CdfModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n const { modelId, revisionId, modelFormat } = modelIdentifier;\n const model = await this._client.revisions3D.retrieve(modelId, revisionId);\n\n const modelMatrix = new THREE.Matrix4();\n if (model.rotation) {\n modelMatrix.makeRotationFromEuler(new THREE.Euler(...model.rotation));\n }\n applyDefaultModelTransformation(modelMatrix, modelFormat);\n return modelMatrix;\n }\n\n public async getModelCamera(\n modelIdentifier: ModelIdentifier\n ): Promise<{ position: THREE.Vector3; target: THREE.Vector3 } | undefined> {\n if (!(modelIdentifier instanceof CdfModelIdentifier)) {\n throw new Error(`Model must be a ${CdfModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n const { modelId, revisionId } = modelIdentifier;\n const model = await this._client.revisions3D.retrieve(modelId, revisionId);\n if (model.camera && model.camera.position && model.camera.target) {\n const { position, target } = model.camera;\n return {\n position: new THREE.Vector3(position[0], position[1], position[2]),\n target: new THREE.Vector3(target[0], target[1], target[2])\n };\n }\n return undefined;\n }\n\n public async getModelUri(modelIdentifier: ModelIdentifier): Promise<string> {\n if (!(modelIdentifier instanceof CdfModelIdentifier)) {\n throw new Error(`Model must be a ${CdfModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n const { modelId, revisionId, modelFormat } = modelIdentifier;\n const outputs = await this.getOutputs(modelIdentifier);\n const mostRecentOutput = outputs.findMostRecentOutput(modelFormat);\n if (!mostRecentOutput) {\n throw new Error(\n `Model '${modelId}/${revisionId}' is not compatible with this version of Reveal, because no outputs for format '(${modelFormat})' was found. If this model works with a previous version of Reveal it must be reprocessed to support this version.`\n );\n }\n const directoryId = mostRecentOutput.blobId;\n return `${this._client.getBaseUrl()}${this.getRequestPath(directoryId)}`;\n }\n\n private async getOutputs(modelIdentifier: CdfModelIdentifier): Promise<Model3DOutputList> {\n const { modelId, revisionId, modelFormat } = modelIdentifier;\n const url = `/api/v1/projects/${this._client.project}/3d/models/${modelId}/revisions/${revisionId}/outputs`;\n const params = modelFormat !== undefined ? { params: { format: modelFormat } } : undefined;\n const response = await this._client.get<ItemsResponse<BlobOutputMetadata>>(url, params);\n if (response.status === 200) {\n return new Model3DOutputList(modelId, revisionId, response.data.items);\n }\n throw new Error(`Unexpected response ${response.status} (payload: '${response.data})`);\n }\n\n private getRequestPath(directoryId: number): string {\n return `/api/v1/projects/${this._client.project}/3d/files/${directoryId}`;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { CdfModelIdentifier } from './CdfModelIdentifier';\nimport { Model3DOutputList } from './Model3DOutputList';\nimport { BlobOutputMetadata } from './types';\n\nimport { CogniteClient } from '@cognite/sdk';\nimport { ItemsResponse } from '@cognite/sdk-core';\n\n/**\n * Helper class for getting the available 'outputs' from the Cognite\n * 3D processing pipeline for a given model.\n */\nexport class CdfModelOutputsProvider {\n private readonly _client: CogniteClient;\n\n constructor(client: CogniteClient) {\n this._client = client;\n }\n\n public async getOutputs(modelIdentifier: CdfModelIdentifier): Promise<Model3DOutputList> {\n const { modelId, revisionId, modelFormat } = modelIdentifier;\n const url = `/api/v1/projects/${this._client.project}/3d/models/${modelId}/revisions/${revisionId}/outputs`;\n const params = modelFormat !== undefined ? { params: { format: modelFormat } } : undefined;\n const response = await this._client.get<ItemsResponse<BlobOutputMetadata>>(url, params);\n if (response.status === 200) {\n return new Model3DOutputList(modelId, revisionId, response.data.items);\n }\n throw new Error(`Unexpected response ${response.status} (payload: '${response.data})`);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { Versioned3DFile } from '@cognite/sdk';\n\n// To avoid direct dependency on @cognite/sdk we use sdk-core here for HttpError.\n// that's why it's avoided https://github.com/cognitedata/cdf-hub/pull/687/files#r489204315\nimport { HttpError } from '@cognite/sdk-core';\n\nexport const supportedVersions = [8];\n\nexport function getNewestVersionedFile(files: Versioned3DFile[]): Versioned3DFile {\n return files\n .filter(file => supportedVersions.includes(file.version))\n .reduce((newestFile, file) => (file.version > newestFile.version ? file : newestFile), {\n fileId: -1,\n version: -1\n });\n}\n\nexport async function fetchWithStatusCheck(url: string): Promise<Response> {\n const response = await fetch(url);\n if (!response.ok) {\n const headers: { [key: string]: string } = {};\n response.headers.forEach((key, value) => {\n headers[key] = value;\n });\n throw new HttpError(response.status, response.body, headers);\n }\n return response;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { HttpHeaders } from '@cognite/sdk-core';\nimport { ModelDataProvider } from './types';\nimport { fetchWithStatusCheck } from './utilities';\n\nexport class LocalModelDataProvider implements ModelDataProvider {\n get headers(): HttpHeaders {\n return {};\n }\n\n async getBinaryFile(baseUrl: string, fileName: string): Promise<ArrayBuffer> {\n const response = await fetchWithStatusCheck(`${baseUrl}/${fileName}`);\n return response.arrayBuffer();\n }\n\n async getJsonFile(baseUrl: string, fileName: string): Promise<any> {\n const response = await fetchWithStatusCheck(`${baseUrl}/${fileName}`);\n return response.json();\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { ModelIdentifier } from './ModelIdentifier';\n\n/**\n * Identifies a 3D model by a URL. This implementation is used for testing\n * purposes.\n */\nexport class LocalModelIdentifier implements ModelIdentifier {\n readonly revealInternalId: symbol;\n readonly localPath: string;\n\n constructor(localPath: string) {\n this.revealInternalId = Symbol(localPath);\n this.localPath = localPath;\n }\n\n public toString(): string {\n return `${LocalModelIdentifier.name} (${this.localPath})`;\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\nimport { applyDefaultModelTransformation } from './applyDefaultModelTransformation';\nimport { LocalModelIdentifier } from './LocalModelIdentifier';\nimport { ModelIdentifier } from './ModelIdentifier';\nimport { ModelMetadataProvider } from './ModelMetadataProvider';\nimport { File3dFormat } from './types';\n\nexport class LocalModelMetadataProvider implements ModelMetadataProvider {\n getModelUri(modelIdentifier: ModelIdentifier): Promise<string> {\n if (!(modelIdentifier instanceof LocalModelIdentifier)) {\n throw new Error(`Model must be a ${LocalModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n return Promise.resolve(`${location.origin}/${modelIdentifier.localPath}`);\n }\n\n async getModelMatrix(modelIdentifier: ModelIdentifier): Promise<THREE.Matrix4> {\n if (!(modelIdentifier instanceof LocalModelIdentifier)) {\n throw new Error(`Model must be a ${LocalModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n const matrix = new THREE.Matrix4();\n applyDefaultModelTransformation(matrix, File3dFormat.RevealCadModel);\n return matrix;\n }\n\n getModelCamera(\n modelIdentifier: ModelIdentifier\n ): Promise<{ position: THREE.Vector3; target: THREE.Vector3 } | undefined> {\n if (!(modelIdentifier instanceof LocalModelIdentifier)) {\n throw new Error(`Model must be a ${LocalModelIdentifier.name}, but got ${modelIdentifier.toString()}`);\n }\n\n return Promise.resolve(undefined);\n }\n}\n","module.exports = require(\"assert\");","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport mixpanel from 'mixpanel-browser';\n\nimport log from '@reveal/logger';\n\nimport { TrackedEvents, EventProps } from './types';\n\n/**\n * Source: https://stackoverflow.com/a/2117523/167251\n */\nfunction generateUuidv4(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n const r = (Math.random() * 16) | 0,\n v = c == 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nconst { VERSION, MIXPANEL_TOKEN } = process.env;\n\n// Don't identify users in MixPanel to avoid GDPR problems\nconst mixpanelDistinctId = 'reveal-single-user';\n\nexport class MetricsLogger {\n _sessionProps: {\n VERSION: string;\n project: string;\n application: string;\n sessionId: string;\n };\n\n private constructor(project: string, applicationId: string, eventProps: EventProps) {\n // Even though mixpanel has an opt out property, the mixpanel object\n // used by Metrics is not available here, so we have our own way of opting out.\n\n mixpanel.init(MIXPANEL_TOKEN, {\n disable_cookie: true,\n disable_persistence: true,\n // Don't send IP which disables geolocation\n ip: false,\n // Avoid sending a bunch of properties that might help identifying a user\n property_blacklist: [\n // https://help.mixpanel.com/hc/en-us/articles/115004613766-Default-Properties-Collected-by-Mixpanel#profile-properties-javascript\n '$city',\n '$region',\n 'mp_country_code',\n '$geo_source',\n '$timezone',\n 'mp_lib',\n '$lib_version',\n '$device_id',\n '$user_id',\n '$current_url',\n '$screen_width',\n '$screen_height',\n '$referrer',\n '$referring_domain',\n '$initial_referrer',\n '$initial_referring_domain'\n ]\n });\n // Reset device ID (even if we don't send it)\n mixpanel.reset();\n\n mixpanel.identify(mixpanelDistinctId);\n\n this._sessionProps = {\n VERSION,\n project: 'unknown',\n application: 'unknown',\n // Use a random identifier because we want to don't track users over multiple sessions to not\n // violate GDPR.\n sessionId: generateUuidv4()\n };\n\n if (project) {\n this._sessionProps.project = project;\n }\n if (applicationId) {\n this._sessionProps.application = applicationId;\n }\n this.innerTrackEvent('init', eventProps);\n }\n\n static init(logMetrics: boolean, project: string, applicationId: string, eventProps: EventProps): void {\n if (globalThis.revealMetricsLogger === undefined && logMetrics) {\n const metricsLogger = new MetricsLogger(project, applicationId, eventProps);\n globalThis.revealMetricsLogger = { metricsLogger };\n }\n }\n\n private innerTrackEvent(eventName: TrackedEvents, eventProps: EventProps): void {\n const combined = { ...this._sessionProps, ...eventProps };\n mixpanel.track(eventName, combined);\n }\n\n static trackEvent(eventName: TrackedEvents, eventProps: EventProps): void {\n if (globalThis.revealMetricsLogger) {\n globalThis.revealMetricsLogger.metricsLogger.innerTrackEvent(eventName, eventProps);\n }\n }\n\n static trackCreateTool(toolName: string): void {\n MetricsLogger.trackEvent('toolCreated', { toolName });\n }\n\n static trackLoadModel(eventProps: EventProps, modelIdentifier: any): void {\n MetricsLogger.trackEvent('loadModel', { ...eventProps, modelIdentifier });\n }\n\n static trackCadModelStyled(nodeCollectionClassToken: string, appearance: any): void {\n MetricsLogger.trackEvent('cadModelStyleAssigned', { nodeCollectionClassToken, style: appearance });\n }\n\n static trackError(error: Error, eventProps: EventProps): void {\n log.error(error);\n\n this.trackEvent('error', {\n message: error.message,\n name: error.name,\n stack: error.stack,\n ...eventProps\n });\n }\n\n static trackCameraNavigation(eventProps: EventProps): void {\n MetricsLogger.trackEvent('cameraNavigated', eventProps);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n// This file is in place for future-proofing. We can change the implementation here if\n// we want to use something else than loglevel.\n\nimport * as log from 'loglevel';\nexport default log;\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport log from './src/Log';\nexport default log;\n","module.exports = require(\"@tweenjs/tween.js\");","module.exports = require(\"mixpanel-browser\");","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nconst worldToViewportVars = {\n renderSize: new THREE.Vector2(),\n position: new THREE.Vector3()\n};\n\n/**\n * Maps from 3D world coordinates to normalized screen coordinates\n * relative to the canvas being rendered to. X and Y will\n * be in range [0, 1]. Z is in range [-1, 1] if the coordinate\n * is inside the camera near and far planes.\n * @param camera Camera used to project point from 3D to NDC coordinates\n * @param position3D World position in 3D\n * @param out Optionally pre-allocated THREE.Vector3\n * @returns Relative screen coordinates in X, Y and Z in range [-1, 1] if point\n * is within near/far of camera.\n */\nexport function worldToNormalizedViewportCoordinates(\n camera: THREE.PerspectiveCamera,\n position3D: THREE.Vector3,\n out: THREE.Vector3 = new THREE.Vector3()\n): THREE.Vector3 {\n const { position } = worldToViewportVars;\n\n // map to normalized device coordinate (NDC) space\n position.copy(position3D);\n position.project(camera);\n\n // map to 2D screen space\n const x = (position.x + 1) / 2;\n const y = (-position.y + 1) / 2;\n\n return out.set(x, y, position.z);\n}\n\n/**\n * Maps from 3D world coordinates to screen coordinates\n * relative to the canvas. X and Y will be in absolute\n * coordinates (0,0 being the top left of the canvas). Z is\n * in range [-1, 1] if the coordinate\n * is inside the camera near and far planes.\n * @param renderer Renderer used to render the \"world\"\n * @param camera Camera used to project point from 3D to NDC coordinates\n * @param position3D World position in 3D\n * @param out Optionally pre-allocated THREE.Vector3\n * @returns Relative screen coordinates in X, Y and Z in range [-1, 1] if point\n * is within near/far of camera.\n */\nexport function worldToViewportCoordinates(\n renderer: THREE.WebGLRenderer,\n camera: THREE.PerspectiveCamera,\n position3D: THREE.Vector3,\n out: THREE.Vector3 = new THREE.Vector3()\n): THREE.Vector3 {\n worldToNormalizedViewportCoordinates(camera, position3D, out);\n\n const { renderSize } = worldToViewportVars;\n renderer.getSize(renderSize);\n\n const canvas = renderer.domElement;\n const { width: canvasWidth, height: canvasHeight } = canvas.getBoundingClientRect();\n\n out.x = Math.round(out.x * canvasWidth);\n out.y = Math.round(out.y * canvasHeight);\n return out;\n}\n","module.exports = require(\"lodash/debounce\");","module.exports = require(\"lodash/cloneDeep\");","module.exports = require(\"lodash/range\");","module.exports = require(\"geo-three\");","module.exports = require(\"@cognite/sdk-core\");","/*!\n * Copyright 2021 Cognite AS\n */\n\nexport { worldToViewportCoordinates, worldToNormalizedViewportCoordinates } from './worldToViewport';\nexport { BoundingBoxClipper } from './BoundingBoxClipper';\n\nexport { assertNever, EventTrigger } from '@reveal/utilities';\n\nexport { LoadingState } from '@reveal/cad-geometry-loaders';\n\nexport { LocalModelIdentifier, CdfModelIdentifier } from '@reveal/modeldata-api';\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nexport class BoundingBoxClipper {\n private readonly _box: THREE.Box3;\n private readonly _clippingPlanes: THREE.Plane[] = [\n new THREE.Plane(),\n new THREE.Plane(),\n new THREE.Plane(),\n new THREE.Plane(),\n new THREE.Plane(),\n new THREE.Plane()\n ];\n\n constructor(box?: THREE.Box3) {\n this._box = box || new THREE.Box3();\n this.updatePlanes();\n }\n\n set minX(x: number) {\n this._box.min.x = x;\n this.updatePlanes();\n }\n\n get minX(): number {\n return this._box.min.x;\n }\n\n set minY(y: number) {\n this._box.min.y = y;\n this.updatePlanes();\n }\n\n get minY(): number {\n return this._box.min.y;\n }\n\n set minZ(z: number) {\n this._box.min.z = z;\n this.updatePlanes();\n }\n\n get minZ(): number {\n return this._box.min.z;\n }\n\n set maxX(x: number) {\n this._box.max.x = x;\n this.updatePlanes();\n }\n\n get maxX(): number {\n return this._box.max.x;\n }\n\n set maxY(y: number) {\n this._box.max.y = y;\n this.updatePlanes();\n }\n\n get maxY(): number {\n return this._box.max.y;\n }\n\n set maxZ(z: number) {\n this._box.max.z = z;\n this.updatePlanes();\n }\n\n get maxZ(): number {\n return this._box.max.z;\n }\n\n private updatePlanes() {\n this._clippingPlanes[0].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(1, 0, 0),\n new THREE.Vector3(this.minX, 0, 0)\n );\n this._clippingPlanes[1].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(-1, 0, 0),\n new THREE.Vector3(this.maxX, 0, 0)\n );\n this._clippingPlanes[2].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(0, 1, 0),\n new THREE.Vector3(0, this.minY, 0)\n );\n this._clippingPlanes[3].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(0, -1, 0),\n new THREE.Vector3(0, this.maxY, 0)\n );\n this._clippingPlanes[4].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(0, 0, 1),\n new THREE.Vector3(0, 0, this.minZ)\n );\n this._clippingPlanes[5].setFromNormalAndCoplanarPoint(\n new THREE.Vector3(0, 0, -1),\n new THREE.Vector3(0, 0, this.maxZ)\n );\n }\n\n get clippingPlanes(): THREE.Plane[] {\n return this._clippingPlanes;\n }\n}\n","module.exports = require(\"comlink\");","module.exports = require(\"loglevel\");","module.exports = require(\"skmeans\");","module.exports = require(\"lodash/merge\");","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { assertNever, EventTrigger } from '@reveal/core/utilities';\n\n/**\n * Base class for tools attaching to a {@see Cognite3DViewer}.\n */\nexport abstract class Cognite3DViewerToolBase {\n private readonly _disposedEvent = new EventTrigger<() => void>();\n private _disposed = false;\n\n /**\n * Registers an event handler that is triggered when {@see Cognite3DViewerToolBase.dispose} is\n * called.\n * @param event\n * @param handler\n * @internal\n */\n on(event: 'disposed', handler: () => void): void {\n switch (event) {\n case 'disposed':\n this._disposedEvent.subscribe(handler);\n break;\n\n default:\n assertNever(event);\n }\n }\n\n /**\n * Unregisters an event handler for the 'disposed'-event.\n * @param event\n * @param handler\n */\n off(event: 'disposed', handler: () => void): void {\n switch (event) {\n case 'disposed':\n this._disposedEvent.unsubscribe(handler);\n break;\n\n default:\n assertNever(event);\n }\n }\n\n /**\n * Disposes the element and triggeres the 'disposed' event before clearing the list\n * of dipose-listeners.\n */\n dispose(): void {\n if (this._disposed) {\n throw new Error('Already disposed');\n }\n this._disposed = true;\n this._disposedEvent.fire();\n this._disposedEvent.unsubscribeAll();\n }\n\n /**\n * Throws an error if the instance has been disposed.\n */\n protected ensureNotDisposed(): void {\n if (this._disposed) {\n throw new Error('The tool has been disposed');\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport range from 'lodash/range';\n\ntype SimpleGrid2DElement<T> = {\n bounds: THREE.Box2;\n element: T;\n};\n\n/**\n * Data structure that splits a 2D region into cells where each cell can contain zero to many\n * elements. Elements can be stored in several cells. This data structure make overlap lookups\n * efficient.\n *\n * Note! This class is tailored for usage with {@link HtmlOverlayTool} and has a few restrictions\n * and assumptions associated with the usage. If used elsewhere, take care as to how this affects\n * performance and behaviour.\n */\nexport class BucketGrid2D<T> {\n private readonly _dimensions: [width: number, height: number];\n private readonly _bounds: THREE.Box2;\n private readonly _cells: SimpleGrid2DElement<T>[][];\n /**\n * Holds elements that has been removed from the collection using {@link removeOverlappingElements}.\n * This is used to avoid expensive re-allocations of cells when removing elements.\n */\n private readonly _removedElements = new Set<T>();\n\n constructor(bounds: THREE.Box2, dimensions: [width: number, height: number]) {\n this._dimensions = dimensions;\n this._cells = range(0, dimensions[0] * dimensions[1]).map(() => new Array<SimpleGrid2DElement<T>>());\n this._bounds = bounds;\n }\n\n insert(bounds: THREE.Box2, element: T): void {\n if (!this._bounds.intersectsBox(bounds)) {\n throw new Error('Element to be added must be partially inside grid');\n }\n if (this._removedElements.has(element)) {\n throw new Error('Re-adding previously taken elements is currently not supported');\n }\n\n for (const cell of this.cellsIntersecting(bounds)) {\n cell.push({ bounds, element });\n }\n }\n\n *overlappingElements(bounds: THREE.Box2): Generator<T> {\n if (!this._bounds.intersectsBox(bounds)) {\n return;\n }\n\n const visitedElements = new Set<T>();\n for (const cell of this.cellsIntersecting(bounds)) {\n for (const candidateElement of cell) {\n if (\n !visitedElements.has(candidateElement.element) &&\n !this._removedElements.has(candidateElement.element) &&\n bounds.intersectsBox(candidateElement.bounds)\n ) {\n visitedElements.add(candidateElement.element);\n yield candidateElement.element;\n }\n }\n }\n }\n\n *removeOverlappingElements(bounds: THREE.Box2): Generator<T> {\n if (!this._bounds.intersectsBox(bounds)) {\n return;\n }\n\n for (const cell of this.cellsIntersecting(bounds)) {\n for (let i = 0; i < cell.length; i++) {\n const candidateElement = cell[i];\n if (!this._removedElements.has(candidateElement.element) && bounds.intersectsBox(candidateElement.bounds)) {\n this._removedElements.add(candidateElement.element);\n yield candidateElement.element;\n }\n }\n }\n }\n\n private *cellsIntersecting(bounds: THREE.Box2): Generator<SimpleGrid2DElement<T>[]> {\n const { min, max } = this._bounds;\n const dimX = this._dimensions[0];\n const dimY = this._dimensions[1];\n const relativeBoundsMinX = (bounds.min.x - min.x) / (max.x - min.x);\n const relativeBoundsMaxX = (bounds.max.x - min.x) / (max.x - min.x);\n const relativeBoundsMinY = (bounds.min.y - min.y) / (max.y - min.y);\n const relativeBoundsMaxY = (bounds.max.y - min.y) / (max.y - min.y);\n\n const clamp = THREE.MathUtils.clamp;\n const minI = clamp(Math.floor(dimX * relativeBoundsMinX), 0, dimX - 1);\n const maxI = clamp(Math.floor(dimX * relativeBoundsMaxX), 0, dimX - 1);\n const minJ = clamp(Math.floor(dimY * relativeBoundsMinY), 0, dimY - 1);\n const maxJ = clamp(Math.floor(dimY * relativeBoundsMaxY), 0, dimY - 1);\n for (let j = minJ; j <= maxJ; ++j) {\n for (let i = minI; i <= maxI; ++i) {\n yield this._cells[j * dimX + i];\n }\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\nimport { Cognite3DViewerToolBase } from '../Cognite3DViewerToolBase';\nimport { BucketGrid2D } from './BucketGrid2D';\n\nimport { MetricsLogger } from '@reveal/metrics';\nimport { assertNever, worldToViewportCoordinates } from '@reveal/core/utilities';\nimport { Cognite3DViewer, DisposedDelegate, SceneRenderedDelegate } from '@reveal/core';\nimport debounce from 'lodash/debounce';\n\n/**\n * Callback that is triggered whenever the 2D position of an overlay is updated\n * in {@link HtmlOverlayTool}.\n */\nexport type HtmlOverlayPositionUpdatedDelegate = (\n element: HTMLElement,\n position2D: THREE.Vector2,\n position3D: THREE.Vector3,\n distanceToCamera: number,\n userData: any\n) => void;\n\n/**\n * Callback that is triggered when a set of overlays are clustered together in\n * {@link HtmlOverlayTool}.\n */\nexport type HtmlOverlayCreateClusterDelegate = (\n overlayElements: {\n htmlElement: HTMLElement;\n userData: any;\n }[]\n) => HTMLElement;\n\n/**\n * Options for an overlay added using {@link HtmlOverlayTool.add}.\n */\nexport type HtmlOverlayOptions = {\n /**\n * Callback that is triggered whenever the position of the overlay is updated. Optional.\n */\n positionUpdatedCallback?: HtmlOverlayPositionUpdatedDelegate;\n /**\n * Optional user specified data that is provided to the {@link HtmlOverlayCreateClusterDelegate} and\n * {@link HtmlOverlayPositionUpdatedDelegate}.\n */\n userData?: any;\n};\n\n/**\n * Controls how close overlay elements are clustered together.\n */\nexport type HtmlOverlayToolClusteringOptions = {\n /**\n * Currently only 'overlapInScreenSpace' is supported. In this mode,\n * overlays are clustered together into a single element as defined by\n * the {@link createClusterElementCallback} and hidden when they overlap\n * in screen space. The composite element is placed at the midpoint of\n * all clustered elements.\n *\n * Clustered elements are faded in/out using CSS styling `transition`,\n * `opacity` and `visibility`.\n */\n mode: 'overlapInScreenSpace';\n\n /**\n * Callback that is triggered when a set of overlays are clustered together\n * to create a \"composite\" element as a placeholder for the clustered elements.\n * Note that this callback will be triggered every frame for each cluster so it\n * must be performant.\n */\n createClusterElementCallback: HtmlOverlayCreateClusterDelegate;\n};\n\nexport type HtmlOverlayToolOptions = {\n clusteringOptions?: HtmlOverlayToolClusteringOptions;\n};\n\ntype HtmlOverlayElement = {\n position3D: THREE.Vector3;\n options: HtmlOverlayOptions;\n\n state: {\n visible: boolean;\n position2D: THREE.Vector2;\n width: number;\n height: number;\n };\n};\n\n/**\n * Manages HTMLoverlays for {@see Cognite3DViewer}. Attaches HTML elements to a\n * 3D position and updates its position/visibility as user moves the camera. This is\n * useful to create HTML overlays to highlight information about key positions in the 3D model.\n *\n * Attached elements *must* have CSS style 'position: absolute'. It's also recommended\n * in most cases to have styles 'pointer-events: none' and 'touch-action: none' to avoid\n * interfering with 3D navigation. Consider also applying 'transform: translate(-50%, -50%)'\n * to anchor the center of the element rather than the top-left corner. In some cases the\n * `zIndex`-attribute is necessary for the element to appear on top of the viewer.\n *\n * @example\n * ```js\n * const el = document.createElement('div');\n * el.style.position = 'absolute'; // Required!\n * // Anchor to center of element\n * el.style.transform = 'translate(-50%, -50%)';\n * // Avoid being target for events\n * el.style.pointerEvents = 'none;\n * el.style.touchAction = 'none';\n * // Render in front of other elements\n * el.style.zIndex = 10;\n *\n * el.style.color = 'red';\n * el.innerHtml = '<h1>Overlay</h1>';\n *\n * const overlayTool = new HtmlOverlayTool(viewer);\n * overlayTool.add(el, new THREE.Vector3(10, 10, 10));\n * // ...\n * overlayTool.remove(el);\n * // or, to remove all attached elements\n * overlayTool.clear();\n *\n * // detach the tool from the viewer\n * overlayTool.dispose();\n * ```\n */\nexport class HtmlOverlayTool extends Cognite3DViewerToolBase {\n private readonly _viewer: Cognite3DViewer;\n private readonly _options: HtmlOverlayToolOptions;\n private readonly _htmlOverlays: Map<HTMLElement, HtmlOverlayElement> = new Map();\n private readonly _compositeOverlays: HTMLElement[] = [];\n\n private readonly _onSceneRenderedHandler: SceneRenderedDelegate;\n private readonly _onViewerDisposedHandler: DisposedDelegate;\n // Allocate variables needed for processing once to avoid allocations\n private readonly _preallocatedVariables = {\n camPos: new THREE.Vector3(),\n camNormal: new THREE.Vector3(),\n point: new THREE.Vector3(),\n nearPlane: new THREE.Plane(),\n farPlane: new THREE.Plane(),\n position2D: new THREE.Vector2()\n };\n\n private readonly scheduleUpdate: () => void;\n\n private get viewerDomElement(): HTMLElement {\n return this._viewer.domElement;\n }\n\n private get viewerCamera(): THREE.PerspectiveCamera {\n return this._viewer.getCamera();\n }\n\n private get viewerRenderer(): THREE.WebGLRenderer {\n return this._viewer.renderer;\n }\n\n constructor(viewer: Cognite3DViewer, options?: HtmlOverlayToolOptions) {\n super();\n\n this._onSceneRenderedHandler = this.onSceneRendered.bind(this);\n this._onViewerDisposedHandler = this.onViewerDisposed.bind(this);\n this._options = options ?? {};\n this._viewer = viewer;\n this._viewer.on('sceneRendered', this._onSceneRenderedHandler);\n this._viewer.on('disposed', this._onViewerDisposedHandler);\n\n this.scheduleUpdate = debounce(() => this.forceUpdate(), 20);\n\n MetricsLogger.trackCreateTool('HtmlOverlayTool');\n }\n\n /**\n * Returns all added HTML elements along with their 3D positions.\n */\n get elements(): { element: HTMLElement; position3D: THREE.Vector3 }[] {\n return Array.from(this._htmlOverlays.entries()).map(([element, info]) => {\n return { element, position3D: info.position3D };\n });\n }\n\n /**\n * Removes all elements and detaches from the viewer.\n * @override\n */\n dispose(): void {\n this._viewer.off('sceneRendered', this._onSceneRenderedHandler);\n this._viewer.off('disposed', this._onViewerDisposedHandler);\n this.clear();\n super.dispose();\n }\n\n /**\n * Registers a HTML overlay that will be updated on rendering.\n *\n * @param htmlElement\n * @param position3D\n * @param options\n */\n add(htmlElement: HTMLElement, position3D: THREE.Vector3, options: HtmlOverlayOptions = {}): void {\n this.ensureNotDisposed();\n\n if (this.viewerDomElement.contains(htmlElement)) {\n throw new Error(`Element is already attached to viewer`);\n }\n\n htmlElement.style.visibility = 'hidden';\n\n // Note! Must be part of DOM tree before we do getComputedStyle(), so add before check\n this.viewerDomElement.appendChild(htmlElement);\n const style = getComputedStyle(htmlElement);\n if (style.position !== 'absolute') {\n this.viewerDomElement.removeChild(htmlElement);\n throw new Error(`htmlElement style must have a position of absolute. but was '${style.position}'`);\n }\n\n const element: HtmlOverlayElement = {\n position3D,\n options,\n state: {\n position2D: new THREE.Vector2(),\n width: -1,\n height: -1,\n visible: true\n }\n };\n this._htmlOverlays.set(htmlElement, element);\n\n this.scheduleUpdate();\n }\n\n /**\n * Removes a overlay and removes it from the DOM.\n * @param htmlElement\n */\n remove(htmlElement: HTMLElement): void {\n this.ensureNotDisposed();\n if (!this.viewerDomElement.contains(htmlElement) || !this._htmlOverlays.has(htmlElement)) {\n throw new Error(`Element is not attached to viewer`);\n }\n this.viewerDomElement.removeChild(htmlElement);\n this._htmlOverlays.delete(htmlElement);\n }\n\n /**\n * Removes all attached HTML overlay elements.\n */\n clear(): void {\n const overlays = Array.from(this._htmlOverlays.keys());\n for (const element of overlays) {\n this.remove(element);\n }\n this.forceUpdate();\n }\n\n /**\n * Updates positions of all overlays. This is automatically managed and there\n * shouldn't be any reason to trigger this unless the attached elements are\n * modified externally.\n *\n * Calling this function often might cause degraded performance.\n */\n forceUpdate(): void {\n this.ensureNotDisposed();\n this.cleanupClusterElements();\n if (this._htmlOverlays.size === 0) {\n return;\n }\n this.updateNewElementSizes();\n\n const camera = this.viewerCamera;\n const renderer = this.viewerRenderer;\n const { camPos, camNormal, point, nearPlane, farPlane, position2D } = this._preallocatedVariables;\n\n // Determine near/far plane to cull based on distance. Note! We don't cull outside the \"walls\"\n // of the frustum to allow HTML elements that are partially outside the edges. The HTML clipping\n // will fix this anyways\n camera.getWorldPosition(camPos);\n camera.getWorldDirection(camNormal);\n point.copy(camPos).addScaledVector(camNormal, camera.near);\n nearPlane.setFromNormalAndCoplanarPoint(camNormal, point);\n point.copy(camPos).addScaledVector(camNormal, camera.far);\n farPlane.setFromNormalAndCoplanarPoint(camNormal, point);\n\n this._htmlOverlays.forEach((element, htmlElement) => {\n const {\n position3D,\n options: { positionUpdatedCallback, userData },\n state\n } = element;\n\n const insideCameraPlanes =\n nearPlane.distanceToPoint(position3D) >= 0.0 && farPlane.distanceToPoint(position3D) <= 0.0;\n // TODO 2021-11-19 larsmoa: Replace worldToViewportCoordinates() with something that doesn't cause\n // canvas.getClientBoundingRect() to be called when PR #1700 is done.\n // https://github.com/cognitedata/reveal/pull/1700\n const { x, y } = worldToViewportCoordinates(renderer, camera, position3D);\n\n if (insideCameraPlanes) {\n state.position2D.set(x, y);\n state.visible = true;\n } else {\n // Outside frustum - hide point\n state.visible = false;\n }\n\n if (positionUpdatedCallback) {\n position2D.set(x, y);\n const distanceToCamera = camPos.distanceTo(position3D);\n positionUpdatedCallback(htmlElement, position2D, position3D, distanceToCamera, userData);\n }\n });\n this.clusterElements();\n this.commitDOMChanges();\n }\n\n /**\n * Update size of new elements. This is only done once as this causes\n * layout to be invalidated which is an expensive operation.\n */\n private updateNewElementSizes() {\n this._htmlOverlays.forEach((element, htmlElement) => {\n if (element.state.width === -1) {\n const clientRect = htmlElement.getBoundingClientRect();\n element.state.width = clientRect.width;\n element.state.height = clientRect.height;\n }\n });\n }\n\n private commitDOMChanges() {\n const canvas = this.viewerRenderer.domElement;\n // Compute once as updating styles below will cause (unnecessary)\n // recomputation which slows down the process\n const offsetLeft = canvas.offsetLeft;\n const offsetTop = canvas.offsetTop;\n\n this._htmlOverlays.forEach((element, htmlElement) => {\n const { state } = element;\n htmlElement.style.left = `${state.position2D.x + offsetLeft}px`;\n htmlElement.style.top = `${state.position2D.y + offsetTop}px`;\n\n if (state.visible && htmlElement.style.visibility !== 'visible') {\n fadeIn(htmlElement);\n } else if (!state.visible && htmlElement.style.visibility !== 'hidden') {\n fadeOut(htmlElement);\n }\n });\n\n this._compositeOverlays.forEach(htmlElement => {\n this.viewerDomElement.appendChild(htmlElement);\n });\n }\n\n private clusterElements() {\n const options = this._options.clusteringOptions;\n if (options === undefined) {\n return;\n }\n\n switch (options.mode) {\n case 'overlapInScreenSpace':\n this.clusterByOverlapInScreenSpace(options.createClusterElementCallback);\n break;\n\n default:\n assertNever(options.mode, `Unsupported clustering mode: '${options.mode}`);\n }\n }\n\n private cleanupClusterElements(): void {\n this._compositeOverlays.forEach(element => {\n this.viewerDomElement.removeChild(element);\n });\n this._compositeOverlays.splice(0);\n }\n\n private clusterByOverlapInScreenSpace(createClusterElementCallback: HtmlOverlayCreateClusterDelegate) {\n type Element = HtmlOverlayElement & { htmlElement: HTMLElement };\n\n const canvas = this.viewerRenderer.domElement;\n const canvasBounds = domRectToBox2(canvas.getBoundingClientRect());\n const canvasSize = canvasBounds.getSize(new THREE.Vector2());\n canvasBounds.set(new THREE.Vector2(0, 0), canvasSize);\n // Compute once as updating styles below will cause (unnecessary)\n // recomputation which slows down the process\n\n const grid = new BucketGrid2D<Element>(canvasBounds, [10, 10]);\n for (const [htmlElement, element] of this._htmlOverlays.entries()) {\n const { state } = element;\n const elementBounds = createElementBounds(element);\n if (!state.visible || !elementBounds.intersectsBox(canvasBounds)) {\n continue;\n }\n grid.insert(elementBounds, { htmlElement, ...element });\n }\n\n const elementBounds = new THREE.Box2();\n const clusterMidpoint = new THREE.Vector2();\n for (const element of this._htmlOverlays.values()) {\n const { state } = element;\n createElementBounds(element, elementBounds);\n if (!state.visible || !elementBounds.intersectsBox(canvasBounds)) {\n continue;\n }\n\n const cluster = Array.from(grid.removeOverlappingElements(elementBounds));\n if (cluster.length > 1) {\n const midpoint = cluster\n .reduce((position, element) => position.add(element.state.position2D), clusterMidpoint.set(0, 0))\n .divideScalar(cluster.length);\n const compositeElement = createClusterElementCallback(\n cluster.map(element => ({ htmlElement: element.htmlElement, userData: element.options.userData }))\n );\n // Hide all elements in cluster\n cluster.forEach(element => (element.state.visible = false));\n // ... and replace with a composite\n this.addComposite(compositeElement, midpoint);\n }\n }\n }\n\n private addComposite(htmlElement: HTMLElement, position: THREE.Vector2) {\n const canvas = this.viewerRenderer.domElement;\n htmlElement.style.visibility = 'visible';\n htmlElement.style.left = `${position.x + canvas.offsetLeft}px`;\n htmlElement.style.top = `${position.y + canvas.offsetTop}px`;\n this._compositeOverlays.push(htmlElement);\n }\n\n private onSceneRendered(): void {\n this.forceUpdate();\n }\n\n private onViewerDisposed(): void {\n this.dispose();\n }\n}\n\n/**\n * Hides an element and applies a CSS transition.\n */\nfunction fadeOut(htmlElement: HTMLElement) {\n // https://stackoverflow.com/a/4861306\n htmlElement.style.visibility = 'hidden';\n htmlElement.style.opacity = '0';\n htmlElement.style.transition = 'visibility 0s 0.2s, opacity 0.2s linear';\n}\n\n/**\n * Shows an element and applies a CSS transition.\n */\nfunction fadeIn(htmlElement: HTMLElement) {\n // https://stackoverflow.com/a/4861306\n htmlElement.style.visibility = 'visible';\n htmlElement.style.opacity = '1';\n htmlElement.style.transition = 'opacity 0.2s linear';\n}\n\nfunction domRectToBox2(rect: DOMRect, out?: THREE.Box2): THREE.Box2 {\n out = out ?? new THREE.Box2();\n out.min.set(rect.left, rect.top);\n out.max.set(rect.right, rect.bottom);\n return out;\n}\n\nfunction createElementBounds(element: HtmlOverlayElement, out?: THREE.Box2) {\n const { state } = element;\n out = out ?? new THREE.Box2();\n out.min.set(state.position2D.x, state.position2D.y);\n out.max.set(state.position2D.x + state.width, state.position2D.y + state.height);\n return out;\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\nimport { Cognite3DModel } from '@reveal/core';\nimport { Cognite3DViewerToolBase } from './Cognite3DViewerToolBase';\nimport { MetricsLogger } from '@reveal/metrics';\n\nexport class ExplodedViewTool extends Cognite3DViewerToolBase {\n private readonly _cadModel: Cognite3DModel;\n private _treeBoundingBoxdata!: Promise<{ treeIndex: number; direction: THREE.Vector3; transform: THREE.Matrix4 }[]>;\n private readonly _rootTreeIndex: number;\n\n public get readyPromise(): Promise<void> {\n return this._treeBoundingBoxdata.then();\n }\n\n constructor(treeIndex: number, cadModel: Cognite3DModel) {\n super();\n\n this._cadModel = cadModel;\n this._rootTreeIndex = treeIndex;\n\n this.preloadBoundingBoxData(cadModel, treeIndex);\n\n MetricsLogger.trackCreateTool('ExplodedViewTool');\n }\n\n public async expand(expandRadius: number): Promise<void> {\n const expandData = await this._treeBoundingBoxdata;\n\n await Promise.all(\n expandData.map(({ treeIndex, direction, transform }) => {\n if (expandRadius === 0) {\n this._cadModel.resetNodeTransformByTreeIndex(treeIndex);\n return Promise.resolve(0);\n }\n\n transform.setPosition(direction.x * expandRadius, direction.y * expandRadius, direction.z * expandRadius);\n\n return this._cadModel.setNodeTransformByTreeIndex(treeIndex, transform);\n })\n );\n }\n\n public reset(): void {\n this._cadModel.resetNodeTransformByTreeIndex(this._rootTreeIndex, true);\n }\n\n private preloadBoundingBoxData(cadModel: Cognite3DModel, treeIndex: number) {\n const rootTreeIndexBoundingBox = cadModel\n .getBoundingBoxByTreeIndex(treeIndex)\n .then(rootBoundingBox => rootBoundingBox.getCenter(new THREE.Vector3()));\n\n const subTreeBoundingBoxes = cadModel\n .getSubtreeTreeIndices(treeIndex)\n .then(subTreeIndices => {\n if (subTreeIndices.count > 1000) {\n throw new Error(`Subtree size of ${subTreeIndices.count} is too large (max size = 1000)`);\n }\n\n return subTreeIndices;\n })\n .then(subTreeIndices => {\n return Promise.all(\n subTreeIndices.toArray().map(async subTreeIndex => {\n // TODO 2021-06-09 larsmoa: We could make this a lot more efficient by\n // batching bounding box lookups together to one/a few API calls rather than\n // one per node\n const subTreeBox = await cadModel.getBoundingBoxByTreeIndex(subTreeIndex);\n return {\n subTreeIndex: subTreeIndex,\n subTreeIndexBoundingBoxCenter: subTreeBox.getCenter(new THREE.Vector3())\n };\n })\n );\n });\n\n this._treeBoundingBoxdata = Promise.all([rootTreeIndexBoundingBox, subTreeBoundingBoxes])\n .then(data => {\n const [rootCenter, subTreeCenters] = data;\n return subTreeCenters.map(({ subTreeIndex, subTreeIndexBoundingBoxCenter }) => {\n return {\n treeIndex: subTreeIndex,\n direction: new THREE.Vector3().subVectors(subTreeIndexBoundingBoxCenter, rootCenter),\n transform: new THREE.Matrix4()\n };\n });\n })\n .then(async payloads => {\n await Promise.all(\n payloads.map(payload => {\n return cadModel.setNodeTransformByTreeIndex(payload.treeIndex, payload.transform);\n })\n );\n return payloads;\n });\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport { Cognite3DViewer } from '@reveal/core';\nimport { DisposedDelegate } from './types';\n\nimport { Cognite3DViewerToolBase } from './Cognite3DViewerToolBase';\n\nexport class DebugCameraTool extends Cognite3DViewerToolBase {\n private readonly _viewer: Cognite3DViewer;\n private readonly _onViewerDisposedHandler: DisposedDelegate;\n private _cameraHelper?: THREE.CameraHelper;\n\n private get viewerCamera(): THREE.PerspectiveCamera {\n return this._viewer.getCamera();\n }\n\n constructor(viewer: Cognite3DViewer) {\n super();\n\n this._onViewerDisposedHandler = this.onViewerDisposed.bind(this);\n this._viewer = viewer;\n this._viewer.on('disposed', this._onViewerDisposedHandler);\n }\n\n /**\n * Removes all elements and detaches from the viewer.\n * @override\n */\n dispose(): void {\n this._viewer.off('disposed', this._onViewerDisposedHandler);\n super.dispose();\n }\n\n showCameraHelper(): void {\n this.hideCameraHelper();\n this._cameraHelper = new THREE.CameraHelper(this.viewerCamera.clone() as THREE.PerspectiveCamera);\n this._viewer.addObject3D(this._cameraHelper);\n }\n\n hideCameraHelper(): void {\n if (this._cameraHelper !== undefined) {\n this._viewer.removeObject3D(this._cameraHelper);\n this._cameraHelper = undefined;\n }\n }\n\n private onViewerDisposed(): void {\n this.dispose();\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\n\n/**\n * Configuration of {@link AxisViewTool}.\n */\nexport type AxisBoxConfig = {\n /**\n * Size in pixels of the axis tool.\n */\n size?: number;\n /**\n * Position, either absolute or relative.\n */\n position?: AbsolutePosition | RelativePosition;\n /**\n * How long the camera animation lasts when\n * clicking a face of the orientation box.\n */\n animationSpeed?: number;\n /**\n * Configuration for each of the faces of the orientation box.\n * Note that Reveal uses a right-handed Y up coordinate system,\n * which might differ from the original model space. To account\n * for this, you might want to reassign labels of the faces.\n */\n faces?: {\n xPositiveFace?: AxisBoxFaceConfig;\n xNegativeFace?: AxisBoxFaceConfig;\n yPositiveFace?: AxisBoxFaceConfig;\n yNegativeFace?: AxisBoxFaceConfig;\n zPositiveFace?: AxisBoxFaceConfig;\n zNegativeFace?: AxisBoxFaceConfig;\n };\n /**\n * Configuration of the compass \"base\" of the tool.\n */\n compass?: AxisBoxCompassConfig;\n};\n\n/**\n * Absolute position in pixels.\n */\nexport type AbsolutePosition = {\n xAbsolute: number;\n yAbsolute: number;\n};\n\n/**\n * Relative position from a corner of the viewer\n * and a given padding.\n */\nexport type RelativePosition = {\n corner: Corner;\n padding: THREE.Vector2;\n};\n\n/**\n * Configuration of each face of the orientation box.\n */\nexport type AxisBoxFaceConfig = {\n /**\n * Label of the respective face, e.g. 'X' or 'Right'.\n */\n label?: string;\n fontSize?: number;\n fontColor?: THREE.Color;\n outlineSize?: number;\n outlineColor?: THREE.Color;\n faceColor?: THREE.Color;\n};\n\n/**\n * Configuration of the compass.\n */\nexport type AxisBoxCompassConfig = {\n /**\n * Label of the orientation indicator. Defaults\n * to 'N' for north.\n */\n ringLabel?: string;\n /**\n * Offset in radians of the orientation indicator.\n */\n labelDelta?: number;\n fontSize?: number;\n fontColor?: THREE.Color;\n tickColor?: THREE.Color;\n};\n\n/**\n * A corner of the viewer.\n */\nexport enum Corner {\n TopRight,\n TopLeft,\n BottomLeft,\n BottomRight\n}\n\nexport const defaultAxisBoxCompassConfig: AxisBoxCompassConfig = {\n ringLabel: 'N',\n labelDelta: Math.PI,\n fontSize: undefined,\n fontColor: new THREE.Color(0xff0000),\n tickColor: new THREE.Color(0x949494)\n};\n\nexport const defaultFaceConfig: AxisBoxFaceConfig = {\n label: '',\n fontSize: undefined,\n fontColor: new THREE.Color(0x333333),\n outlineSize: undefined,\n outlineColor: new THREE.Color(0x333333),\n faceColor: new THREE.Color(0x949494)\n};\n\nexport const defaultAxisBoxConfig: Required<AxisBoxConfig> = {\n size: 128,\n position: {\n corner: Corner.BottomRight,\n padding: new THREE.Vector2()\n },\n animationSpeed: 200,\n faces: {\n xPositiveFace: {\n ...defaultFaceConfig,\n label: 'Right'\n },\n xNegativeFace: {\n ...defaultFaceConfig,\n label: 'Left'\n },\n yPositiveFace: {\n ...defaultFaceConfig,\n label: 'Up'\n },\n yNegativeFace: {\n ...defaultFaceConfig,\n label: 'Down'\n },\n zPositiveFace: {\n ...defaultFaceConfig,\n label: 'Front'\n },\n zNegativeFace: {\n ...defaultFaceConfig,\n label: 'Back'\n }\n },\n compass: defaultAxisBoxCompassConfig\n};\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport * as THREE from 'three';\nimport cloneDeep from 'lodash/cloneDeep';\nimport merge from 'lodash/merge';\nimport TWEEN from '@tweenjs/tween.js';\n\nimport { Cognite3DViewerToolBase } from '../Cognite3DViewerToolBase';\nimport {\n AxisBoxConfig,\n defaultAxisBoxConfig,\n AxisBoxFaceConfig,\n Corner,\n AbsolutePosition,\n RelativePosition\n} from './types';\nimport { RevealCameraControls } from '@reveal/camera-manager';\nimport { Cognite3DViewer } from '@reveal/core';\nimport { MetricsLogger } from '@reveal/metrics';\n\nexport class AxisViewTool extends Cognite3DViewerToolBase {\n private readonly _layoutConfig: Required<AxisBoxConfig>;\n\n private readonly _boxFaceGeometry: THREE.PlaneGeometry;\n\n private readonly _viewer: Cognite3DViewer;\n\n private readonly _axisGroup: THREE.Group;\n\n private readonly _interactiveObjects: THREE.Mesh[];\n private readonly _raycastCamera: THREE.OrthographicCamera;\n private readonly _raycaster: THREE.Raycaster;\n\n private readonly _screenPosition: THREE.Vector2;\n\n private readonly _disposeClickDiv: () => void;\n\n private _dynamicUpdatePosition = () => {};\n private readonly _updateClickDiv = () => {};\n\n constructor(viewer: Cognite3DViewer, config?: AxisBoxConfig) {\n super();\n\n this._screenPosition = new THREE.Vector2();\n this._boxFaceGeometry = new THREE.PlaneGeometry(0.85, 0.85, 1, 1);\n\n this._raycastCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);\n this._raycaster = new THREE.Raycaster();\n\n this._viewer = viewer;\n\n this._layoutConfig = merge(cloneDeep(defaultAxisBoxConfig), config);\n\n this._axisGroup = new THREE.Group();\n this._interactiveObjects = this.createAxisCross(this._axisGroup);\n\n [this._updateClickDiv, this._disposeClickDiv] = this.createClickDiv(viewer);\n this.addAxisBoxToViewer(this._axisGroup, this._layoutConfig.position!);\n\n MetricsLogger.trackCreateTool('AxisViewTool');\n }\n\n public dispose(): void {\n super.dispose();\n this._viewer.removeUiObject(this._axisGroup);\n this._disposeClickDiv();\n }\n\n private createClickDiv(viewer: Cognite3DViewer) {\n const canvasElement = viewer.domElement.querySelector('canvas');\n if (canvasElement === null) {\n throw new Error('Could not find canvas');\n }\n const divElement = document.createElement('div');\n divElement.style.position = 'absolute';\n divElement.style.height = `${this._layoutConfig.size}px`;\n divElement.style.width = `${this._layoutConfig.size}px`;\n divElement.style.zIndex = '1';\n\n let xMouse = 0;\n let yMouse = 0;\n\n divElement.addEventListener('mousedown', event => {\n const mouseDownEvent = new MouseEvent('mousedown', {\n clientX: event.clientX,\n clientY: event.clientY,\n button: event.button\n });\n xMouse = event.clientX;\n yMouse = event.clientY;\n viewer.renderer.domElement.dispatchEvent(mouseDownEvent);\n });\n\n divElement.addEventListener('mousemove', event => {\n const mouseMoveEvent = new MouseEvent('mousemove', {\n clientX: event.clientX,\n clientY: event.clientY,\n button: event.button\n });\n viewer.renderer.domElement.dispatchEvent(mouseMoveEvent);\n });\n\n divElement.addEventListener('contextmenu', event => event.preventDefault());\n\n divElement.addEventListener('mouseup', event => {\n const mouseUpEvent = new MouseEvent('mouseup', {\n clientX: event.clientX,\n clientY: event.clientY,\n button: event.button\n });\n\n const rect = viewer.domElement.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n if (Math.abs(xMouse - event.clientX) + Math.abs(yMouse - event.clientY) <= 10 && !this.handleClick(x, y, rect)) {\n viewer.renderer.domElement.dispatchEvent(mouseUpEvent);\n }\n });\n\n viewer.domElement.appendChild(divElement);\n\n return [\n () => {\n divElement.style.left = `${this._screenPosition.x}px`;\n divElement.style.bottom = `${this._screenPosition.y}px`;\n },\n () => {\n viewer.domElement.removeChild(divElement);\n }\n ];\n }\n\n private addAxisBoxToViewer(axisGroup: THREE.Group, position: AbsolutePosition | RelativePosition) {\n const size = this._layoutConfig.size;\n\n if (isAbsolute(position)) {\n this._screenPosition.x = position.xAbsolute;\n this._screenPosition.y = position.yAbsolute;\n } else {\n switch (position.corner) {\n case Corner.BottomRight:\n this._screenPosition.y = position.padding.y;\n\n this._dynamicUpdatePosition = () => {\n this._screenPosition.x = this._viewer.renderer.domElement.clientWidth - position.padding.x - size;\n };\n break;\n\n case Corner.TopRight:\n this._dynamicUpdatePosition = () => {\n this._screenPosition.x = this._viewer.renderer.domElement.clientWidth - position.padding.x - size;\n this._screenPosition.y = this._viewer.renderer.domElement.clientHeight - position.padding.y - size;\n };\n break;\n\n case Corner.TopLeft:\n this._screenPosition.x = position.padding.x;\n this._dynamicUpdatePosition = () => {\n this._screenPosition.y = this._viewer.renderer.domElement.clientHeight - position.padding.y - size;\n };\n break;\n\n case Corner.BottomLeft:\n this._screenPosition.x = position.padding.x;\n this._screenPosition.y = position.padding.y;\n break;\n default:\n throw new Error(`Unknown corner position for Axis Cross: Corner = ${position.corner}`);\n }\n this._dynamicUpdatePosition();\n }\n\n this._viewer.addUiObject(axisGroup, this._screenPosition, new THREE.Vector2(size, size));\n\n function isAbsolute(position: AbsolutePosition | RelativePosition): position is AbsolutePosition {\n return (\n (position as AbsolutePosition).xAbsolute !== undefined && (position as AbsolutePosition).yAbsolute !== undefined\n );\n }\n }\n\n private handleClick(xScreenPos: number, yScreenPos: number, boundingRect: DOMRect): boolean {\n const xNdc = (2 * (xScreenPos - this._screenPosition.x)) / this._layoutConfig.size - 1;\n const yNdc = (2 * (boundingRect.height - yScreenPos - this._screenPosition.y)) / this._layoutConfig.size - 1;\n this._raycaster.setFromCamera({ x: xNdc, y: yNdc }, this._raycastCamera);\n const rayOrigin = new THREE.Vector3(xNdc, yNdc, 1);\n const rayDirection = new THREE.Vector3(0, 0, -1).normalize();\n this._raycaster.set(rayOrigin, rayDirection);\n\n const intersects = this._raycaster.intersectObjects(this._interactiveObjects);\n\n if (!(intersects.length > 0)) return false;\n\n const targetPosition = intersects[0].object.position.clone().normalize();\n const targetUp = (intersects[0].object.userData.upVector as THREE.Vector3).clone();\n\n this.moveCameraTo(this._viewer.getCamera(), this._viewer.cameraControls, targetPosition, targetUp);\n\n return true;\n }\n\n private createAxisCross(axisGroup: THREE.Group) {\n const interactiveObjects = this.createBoxFaces();\n axisGroup.add(...interactiveObjects);\n\n const compass = this.createCompass();\n axisGroup.add(compass);\n\n this.setupTransformOnRender(axisGroup);\n\n return interactiveObjects;\n }\n\n private setupTransformOnRender(axisGroup: THREE.Group) {\n axisGroup.children[0].onBeforeRender = () => {\n this._dynamicUpdatePosition();\n axisGroup.quaternion.copy(this._viewer.getCamera().quaternion).invert();\n axisGroup.updateMatrixWorld();\n this._updateClickDiv();\n };\n }\n\n private createBoxFaces() {\n const facesConfig = this._layoutConfig.faces;\n\n const posXFace = this.createBoxFace(new THREE.Vector3(1, 0, 0), facesConfig.xPositiveFace!);\n const negXFace = this.createBoxFace(new THREE.Vector3(-1, 0, 0), facesConfig.xNegativeFace!);\n\n const posYFace = this.createBoxFace(\n new THREE.Vector3(0, 1, 0),\n facesConfig.yPositiveFace!,\n new THREE.Vector3(0, 0, -1)\n );\n const negYFace = this.createBoxFace(\n new THREE.Vector3(0, -1, 0),\n facesConfig.yNegativeFace!,\n new THREE.Vector3(0, 0, 1)\n );\n\n const posZFace = this.createBoxFace(new THREE.Vector3(0, 0, 1), facesConfig.zPositiveFace!);\n const negZFace = this.createBoxFace(new THREE.Vector3(0, 0, -1), facesConfig.zNegativeFace!);\n\n return [posXFace, negXFace, posYFace, negYFace, posZFace, negZFace];\n }\n\n private createCompass() {\n const compassPlaneGeometry = new THREE.PlaneGeometry(2.1, 2.1, 1, 1);\n const compass = new THREE.Mesh(\n compassPlaneGeometry,\n new THREE.MeshBasicMaterial({\n map: this.createCompassTexture(),\n side: THREE.DoubleSide,\n transparent: true\n })\n );\n\n const x = Math.sin(this._layoutConfig.compass.labelDelta!);\n const z = Math.cos(this._layoutConfig.compass.labelDelta!);\n\n compass.position.y = -0.5;\n compass.up.copy(new THREE.Vector3(x, 0, z));\n compass.lookAt(0, 0, 0);\n\n return compass;\n }\n\n private createCompassTexture() {\n const compassLayout = this._layoutConfig.compass;\n const textureSize = this._layoutConfig.size;\n\n const canvas = document.createElement('canvas');\n canvas.width = textureSize;\n canvas.height = textureSize;\n const context = canvas.getContext('2d')!;\n\n const halfSize = textureSize / 2;\n const radius = halfSize - halfSize / 4;\n\n const tickWidth = textureSize / 32;\n const tickSpace = textureSize / 8;\n\n context.strokeStyle = compassLayout.tickColor!.getStyle();\n context.lineWidth = textureSize / 16;\n context.setLineDash([tickWidth, tickSpace]);\n context.beginPath();\n context.arc(halfSize, halfSize, radius, 0, 2 * Math.PI);\n context.stroke();\n\n if (compassLayout.ringLabel && compassLayout.ringLabel.length > 0) {\n const fontSize = compassLayout.fontSize ?? textureSize / 5;\n context.font = `bold ${fontSize}px Arial`;\n context.textAlign = 'center';\n context.fillStyle = compassLayout.fontColor!.getStyle();\n context.fillText(compassLayout.ringLabel, halfSize, halfSize * (1 / 4) + fontSize / 3);\n }\n\n return new THREE.CanvasTexture(canvas);\n }\n\n private getFaceTexture(faceConfig: AxisBoxFaceConfig, size: number) {\n const textureSize = size / 2;\n\n const canvas = document.createElement('canvas');\n canvas.width = textureSize;\n canvas.height = textureSize;\n\n const context = canvas.getContext('2d')!;\n context.fillStyle = faceConfig.outlineColor!.getStyle();\n context.fillRect(0, 0, textureSize, textureSize);\n context.fillStyle = faceConfig.faceColor!.getStyle();\n\n const outlineSize = faceConfig.outlineSize ?? textureSize / 32;\n context.fillRect(outlineSize, outlineSize, textureSize - outlineSize * 2, textureSize - outlineSize * 2);\n context.fill();\n\n if (faceConfig.label !== '') {\n const fontSize = faceConfig.fontSize ?? textureSize / 3;\n context.font = `bold ${fontSize}px Arial`;\n context.textAlign = 'center';\n context.fillStyle = faceConfig.fontColor!.getStyle();\n context.fillText(faceConfig.label!, textureSize / 2, textureSize / 2 + fontSize / 3);\n }\n\n return new THREE.CanvasTexture(canvas);\n }\n\n private createBoxFace(position: THREE.Vector3, faceConfig: AxisBoxFaceConfig, upVector = new THREE.Vector3(0, 1, 0)) {\n const face = new THREE.Mesh(\n this._boxFaceGeometry,\n new THREE.MeshBasicMaterial({ map: this.getFaceTexture(faceConfig, this._layoutConfig.size) })\n );\n\n face.position.copy(position.multiplyScalar(0.5 * this._boxFaceGeometry.parameters.width));\n face.lookAt(position.multiplyScalar(2));\n\n face.userData.upVector = upVector;\n\n return face;\n }\n\n private moveCameraTo(\n camera: THREE.PerspectiveCamera,\n cameraControls: RevealCameraControls,\n targetAxis: THREE.Vector3,\n targetUpAxis: THREE.Vector3\n ) {\n const currentCameraPosition = camera.position.clone();\n const cameraTarget = cameraControls.getState().target;\n\n const targetRelativeStartPosition = currentCameraPosition.clone().sub(cameraTarget);\n const radius = targetRelativeStartPosition.length();\n\n const normalizedFrom = targetRelativeStartPosition.clone().normalize();\n\n const omega = Math.acos(normalizedFrom.dot(targetAxis));\n\n const from = { t: 0 };\n const to = { t: 1 };\n\n const animation = new TWEEN.Tween(from);\n\n const forward = targetAxis.clone();\n\n const fromRotation = camera.quaternion.clone();\n const toRotation = new THREE.Quaternion().setFromRotationMatrix(\n new THREE.Matrix4().makeBasis(targetUpAxis.clone().cross(forward), targetUpAxis, forward)\n );\n\n const epsilon = 1e-6;\n\n if (fromRotation.angleTo(toRotation) < epsilon) {\n return;\n }\n\n const tmpPosition = new THREE.Vector3();\n const tmpRotation = new THREE.Quaternion();\n let cachedCameraControlsEnabled: boolean;\n const tween = animation\n .to(to, this._layoutConfig.animationSpeed)\n .onUpdate(() => {\n tmpPosition\n .copy(normalizedFrom)\n .multiplyScalar(Math.sin((1 - from.t) * omega) / Math.sin(omega))\n .add(targetAxis.clone().multiplyScalar(Math.sin(from.t * omega) / Math.sin(omega)));\n\n tmpPosition.multiplyScalar(radius);\n tmpPosition.add(cameraTarget);\n\n tmpRotation.slerpQuaternions(fromRotation, toRotation, from.t);\n\n camera.position.copy(tmpPosition);\n camera.setRotationFromQuaternion(tmpRotation);\n })\n .start(TWEEN.now())\n .onStart(() => {\n cachedCameraControlsEnabled = cameraControls.enabled;\n cameraControls.enabled = false;\n })\n .onComplete(() => {\n cameraControls.setState(camera.position, cameraTarget);\n cameraControls.enabled = cachedCameraControlsEnabled;\n });\n tween.update(TWEEN.now());\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\n/**\n * Supported map Providers Bing, Here & Mapbox\n */\nexport enum MapProviders {\n BingMap = 'BingMap',\n HereMap = 'HereMap',\n MapboxMap = 'MapboxMap',\n OpenStreetMap = 'OpenStreetMap'\n}\n\n/**\n * Map data for Mapbox\n */\nexport enum MapboxMode {\n /**\n * Access the map data using a map style. For details see https://docs.mapbox.com/api/maps/styles/\n */\n Style = 100,\n /**\n * Access the map data using a map id or Tileset id. For details see https://docs.mapbox.com/help/glossary/tileset-id/\n */\n Map_Id = 101\n}\n\n/**\n * Mapbox Map Style, these are pre-defined styles using map/tileset id, created in Mapbox Studio style editor.\n * This is used when MapboxMode.Style is used for mode.\n */\nexport enum MapboxStyle {\n Streets = 'mapbox/streets-v10',\n Outdoor = 'mapbox/outdoors-v10',\n Light = 'mapbox/light-v9',\n Dark = 'mapbox/dark-v9',\n Satellite = 'mapbox/satellite-v9',\n Satellite_Streets = 'mapbox/satellite-streets-v10',\n Navigation_Day = 'mapbox/navigation-preview-day-v4',\n Navigation_Night = 'mapbox/navigation-preview-night-v4',\n Navigation_Guide_Day = 'mapbox/navigation-guidance-day-v4',\n Navigation_Guide_Night = 'mapbox/navigation-guidance-night-v4'\n}\n\n/**\n * A map/tileset ID is a unique identifier given to every tileset, used when MapboxMode.Map_Id is choosen for mode.\n */\nexport enum MapboxId {\n Streets = 'mapbox.mapbox-streets-v7',\n Satellite = 'mapbox.satellite',\n Terrain = 'mapbox.mapbox-terrain-v2',\n Traffic = 'mapbox.mapbox-traffic-v1',\n TerrainRGB = 'mapbox.terrain-rgb'\n}\n\n/**\n * Mapbox Map image tile format\n */\nexport enum MapboxImageFormat {\n PNG = 'png',\n PNG32 = 'png32',\n PNG64 = 'png64',\n PNG128 = 'png128',\n PNG256 = 'png256',\n JPG70 = 'jpg70',\n JPG80 = 'jpg80',\n JPG90 = 'jpg90',\n PNGRAW = 'pngraw'\n}\n\n/**\n * Bing Map View (aerial, road, bird's eye view of the map)\n */\nexport enum BingMapType {\n Aerial = 'a',\n Road = 'r',\n Aerial_Labels = 'h',\n Oblique = 'o',\n Oblique_Labels = 'b'\n}\n\n/**\n * Bing Map Tile Image formats\n */\nexport enum BingMapImageFormat {\n GIF = 'gif',\n JPEG = 'jpeg',\n PNG = 'png'\n}\n\n/**\n * Here Map types\n */\nexport enum HereMapType {\n Aerial = 'aerial',\n Base = 'base',\n Pano = 'pano',\n Traffic = 'traffic'\n}\n\n/**\n * Here Map View Scheme like day, night, satellite, terrain\n */\nexport enum HereMapScheme {\n Day = 'normal.day',\n Night = 'normal.night',\n Terrain = 'terrain.day',\n Satellite = 'satellite.day'\n}\n\n/**\n * Here Map Tiles Image Format\n */\nexport enum HereMapImageFormat {\n PNG = 'png',\n PNG8 = 'png8',\n JPG = 'jpg'\n}\n\nexport type BingMapConfig = {\n provider: MapProviders.BingMap;\n /**\n * Bing Map API Key\n */\n APIKey: string;\n /**\n * The type of the map used.\n */\n type?: BingMapType;\n};\n\nexport type HereMapConfig = {\n provider: MapProviders.HereMap;\n /**\n * Here map API Key\n */\n APIKey: string;\n /**\n * Service application code token.\n */\n appCode?: string;\n /**\n * The type of maps to be used.\n */\n style?: HereMapType;\n /**\n * Specifies the view scheme\n */\n scheme?: string;\n /**\n * Map image tile format\n */\n imageFormat?: HereMapImageFormat;\n /**\n Returned tile map image size.\n The following sizes are supported:\n - 256\n - 512\n - 128 (deprecated, although usage is still accepted)\n */\n size?: number;\n};\n\nexport type OpenStreetMapConfig = {\n provider: MapProviders.OpenStreetMap;\n};\n\nexport type MapboxConfig = {\n provider: MapProviders.MapboxMap;\n /**\n * Mapbox API Key\n */\n APIKey: string;\n /**\n * Map style or map ID if the mode is set to MAP_ID\n */\n id: string;\n /**\n Map tile access mode\n - MapboxMode.STYLE\n - MapboxMode.MAP_ID\n */\n mode?: MapboxMode;\n /**\n * Map image tile format\n */\n tileFormat?: MapboxImageFormat;\n /**\n * Flag to indicate if should use high resolution tiles\n */\n useHDPI?: boolean;\n};\n\n/**\n * Maps Configuration of {@link GeomapTool}.\n */\nexport type MapConfig = {\n /**\n * Latitude, Longitude position\n */\n latlong: LatLongPosition;\n} & (BingMapConfig | HereMapConfig | MapboxConfig | OpenStreetMapConfig);\n\n/**\n * Latitude, Longitude position.\n */\nexport type LatLongPosition = {\n latitude: number;\n longitude: number;\n};\n","/*!\n * Copyright 2021 Cognite AS\n */\n// To overcome \"implicitly has an 'any' type\" and \"unused variable reference\" error in the geo-three library\n// @ts-ignore\nimport * as GEOTHREE from 'geo-three';\nimport { Cognite3DViewer } from '@reveal/core';\nimport { LatLongPosition, MapConfig, MapProviders } from './MapConfig';\n\nexport class Geomap {\n private readonly _viewer: Cognite3DViewer;\n private readonly _map: GEOTHREE.MapView;\n private _intervalId: any = 0;\n private readonly _onCameraChange = this.handleCameraChange.bind(this);\n\n constructor(viewer: Cognite3DViewer, mapConfig: MapConfig) {\n this._viewer = viewer;\n const mapProvider = this.getMapProvider(mapConfig);\n this._map = new GEOTHREE.MapView(GEOTHREE.MapView.PLANAR, mapProvider, mapProvider);\n this._viewer.addObject3D(this._map);\n\n const coords = GEOTHREE.UnitsUtils.datumsToSpherical(mapConfig.latlong.latitude, mapConfig.latlong.longitude);\n const bound = this._viewer.models[0].getModelBoundingBox();\n this._map.position.set(-coords.x, bound.min.y, coords.y);\n this._map.updateMatrixWorld(true);\n this.requestRedraw(10000);\n this._viewer.on('cameraChange', this._onCameraChange);\n }\n\n private requestRedraw(timeOut: number) {\n if (this._intervalId == 0) {\n this._intervalId = setInterval(() => {\n this._viewer.requestRedraw();\n }, 100);\n\n setTimeout(() => {\n clearInterval(this._intervalId);\n this._intervalId = 0;\n }, timeOut);\n }\n }\n\n private getMapProvider(mapConfig: MapConfig) {\n let mapProvider: GEOTHREE.MapProvider;\n switch (mapConfig.provider) {\n case MapProviders.BingMap:\n mapProvider = new GEOTHREE.BingMapsProvider(mapConfig.APIKey, mapConfig.type);\n break;\n case MapProviders.HereMap:\n mapProvider = new GEOTHREE.HereMapsProvider(\n mapConfig.APIKey,\n mapConfig.appCode,\n mapConfig.style,\n mapConfig.scheme,\n mapConfig.imageFormat,\n mapConfig.size\n );\n break;\n case MapProviders.MapboxMap:\n mapProvider = new GEOTHREE.MapBoxProvider(mapConfig.APIKey, mapConfig.id, mapConfig.mode, mapConfig.tileFormat);\n break;\n case MapProviders.OpenStreetMap:\n mapProvider = new GEOTHREE.OpenStreetMapsProvider();\n break;\n\n default:\n throw new Error('Unsupported map provider');\n }\n\n return mapProvider;\n }\n\n public latLongToWorldCoordinates(latLong: LatLongPosition): { x: number; y: number } {\n return GEOTHREE.UnitsUtils.datumsToSpherical(latLong.latitude, latLong.longitude);\n }\n\n private handleCameraChange() {\n this.requestRedraw(1000);\n }\n\n public dispose(): void {\n this._viewer.removeObject3D(this._map);\n this._viewer.off('cameraChange', this._onCameraChange);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { Cognite3DViewerToolBase } from '../Cognite3DViewerToolBase';\nimport { LatLongPosition, MapConfig } from './MapConfig';\nimport { Geomap } from './Geomap';\n\nimport { Cognite3DViewer } from '@reveal/core';\nimport { MetricsLogger } from '@reveal/metrics';\n\n/**\n * The `GeomapTool` is a geolocation for the models and allow the user to place them on the maps.\n * @version New since 2.1.\n */\nexport class GeomapTool extends Cognite3DViewerToolBase {\n private readonly _viewer: Cognite3DViewer;\n private readonly _maps: Geomap;\n\n constructor(viewer: Cognite3DViewer, config: MapConfig) {\n super();\n\n this._viewer = viewer;\n this._maps = new Geomap(this._viewer, config);\n\n MetricsLogger.trackCreateTool('AxisViewTool');\n }\n\n /**\n * Converts Latitude & Longitude into Vector2 World coordinates on the Map\n * @param latLong Latitude & Longitude\n */\n public latLongToWorldCoordinates(latLong: LatLongPosition): { x: number; y: number } {\n return this._maps.latLongToWorldCoordinates(latLong);\n }\n\n public dispose(): void {\n super.dispose();\n this._maps.dispose();\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport { NodeCollectionBase, NodeAppearance } from '@reveal/core/src';\nimport { Cognite3DModel } from '@reveal/core';\nimport { MetricsLogger } from '@reveal/metrics';\n\n/**\n * Timeline Key Frames contains parameters to access Nodes, Styles for the Timeline\n */\nexport class Keyframe {\n private readonly _date: Date;\n private readonly _model: Cognite3DModel;\n private readonly _nodeCollectionAndAppearance: { nodes: NodeCollectionBase; nodeAppearance: NodeAppearance }[] = [];\n\n constructor(model: Cognite3DModel, date: Date) {\n this._model = model;\n this._date = date;\n }\n\n /**\n * Get date of the Keyframe\n * @returns date\n */\n public getKeyframeDate(): Date {\n return this._date;\n }\n\n /**\n * Assigns the styles for the node set for the model for this Keyframe\n */\n public activate(): void {\n this._nodeCollectionAndAppearance.forEach((node, _index) => {\n this._model.assignStyledNodeCollection(node.nodes, node.nodeAppearance);\n });\n }\n\n /**\n * Removes the style for the model\n */\n public deactivate(): void {\n this._nodeCollectionAndAppearance.forEach((node, _index) => {\n this._model.unassignStyledNodeCollection(node.nodes);\n });\n }\n\n /**\n * Add node & style to the collection\n * @param nodeCollection Node set to apply the Styles\n * @param nodeAppearance Style to assign to the node collection\n */\n public assignStyledNodeCollection(nodeCollection: NodeCollectionBase, nodeAppearance: NodeAppearance): void {\n MetricsLogger.trackCadModelStyled(nodeCollection.classToken, nodeAppearance);\n\n const index = this._nodeCollectionAndAppearance.findIndex(x => x.nodes === nodeCollection);\n if (index !== -1) {\n throw new Error(\n 'Node collection as already been assigned, use updateStyledNodeCollection() to update the appearance'\n );\n }\n\n this._nodeCollectionAndAppearance.push({ nodes: nodeCollection, nodeAppearance });\n }\n\n /**\n * Remove Node & Style for this keyframe's nodeCollection and nodeAppearance\n * @param nodeCollection Nodes to be unassign from node collection\n */\n public unassignStyledNodeCollection(nodeCollection: NodeCollectionBase): void {\n const index = this._nodeCollectionAndAppearance.findIndex(x => x.nodes === nodeCollection);\n if (index === -1) {\n throw new Error('Node collection has not been assigned to model');\n }\n this._nodeCollectionAndAppearance.splice(index, 1);\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\n\nimport TWEEN from '@tweenjs/tween.js';\n\nimport { Cognite3DModel } from '@reveal/core';\nimport { Cognite3DViewerToolBase } from '../Cognite3DViewerToolBase';\nimport { Keyframe } from './Keyframe';\nimport { TimelineDateUpdateDelegate } from './types';\nimport { EventTrigger, assertNever } from '@reveal/core/utilities';\n\n/**\n * Tool to applying styles to nodes based on date to play them over in Timeline\n */\nexport class TimelineTool extends Cognite3DViewerToolBase {\n private readonly _model: Cognite3DModel;\n private readonly _keyframes: Keyframe[];\n private _playback: TWEEN.Tween | undefined = undefined;\n private readonly _events = { dateChanged: new EventTrigger<TimelineDateUpdateDelegate>() };\n\n constructor(cadModel: Cognite3DModel) {\n super();\n\n this._model = cadModel;\n this._keyframes = new Array<Keyframe>();\n }\n\n /**\n * Subscribe to the Date changed event\n * @param event `dateChanged` event\n * @param listener Listen to Timeline date Update during Playback\n */\n public subscribe(event: 'dateChanged', listener: TimelineDateUpdateDelegate): void {\n switch (event) {\n case 'dateChanged':\n this._events.dateChanged.subscribe(listener);\n break;\n default:\n assertNever(event, `Unsupported event: '${event}'`);\n }\n }\n\n /**\n * Unsubscribe to the Date changed event\n * @param event `dateChanged` event\n * @param listener Remove Listen to Timeline date Update\n */\n public unsubscribe(event: 'dateChanged', listener: TimelineDateUpdateDelegate): void {\n switch (event) {\n case 'dateChanged':\n this._events.dateChanged.unsubscribe(listener);\n break;\n default:\n assertNever(event, `Unsupported event: '${event}'`);\n }\n }\n\n /**\n * Create Key frame for the Timeline\n * @param date - date value by Date.now() since January 1, 1970\n */\n public createKeyframe(date: Date): Keyframe {\n const keyframe = new Keyframe(this._model, date);\n this._keyframes.push(keyframe);\n this.sortKeyframesByDates();\n\n return keyframe;\n }\n\n /**\n * Returns the keyframe at the date given, or undefined if not found.\n * @param date\n * @returns\n */\n public getKeyframeByDate(date: Date): Keyframe | undefined {\n return this._keyframes.find(candidate => candidate.getKeyframeDate() === date);\n }\n\n /**\n * Removes the Keyframe from the timeline. Does nothing if the keyframe isn't part of the timeline.\n * @param keyframe - Keyframe to be removed from the timeline\n */\n public removeKeyframe(keyframe: Keyframe): void {\n const index = this._keyframes.findIndex(obj => obj === keyframe);\n\n if (index > -1) {\n this._keyframes.splice(index, 1);\n }\n }\n\n /**\n * Removes the Keyframe from the Timeline\n * @param date - Date of the Keyframe to be removed from the Timeline\n */\n public removeKeyframeByDate(date: Date): void {\n const index = this._keyframes.findIndex(obj => obj.getKeyframeDate() === date);\n\n if (index > -1) {\n this._keyframes.splice(index, 1);\n }\n }\n\n /**\n * Starts playback of Timeline\n * @param startDate - Keyframe date to start the Playback of Keyframes\n * @param endDate - Keyframe date to stop the Playback of Keyframes\n * @param totalDurationInMilliSeconds - Number of milliseconds for all Keyframe within startDate & endDate to be rendered\n */\n public play(startDate: Date, endDate: Date, totalDurationInMilliSeconds: number): void {\n this.stop();\n\n const playState = { dateInMs: startDate.getTime() };\n const to = { dateInMs: endDate.getTime() };\n const tween = new TWEEN.Tween(playState).to(to, totalDurationInMilliSeconds);\n let currentKeyframeIndex = -1;\n tween.onUpdate(() => {\n const date = new Date(playState.dateInMs);\n\n // Forward active keyframe to last keyframe that is before current date\n const prevIndex = currentKeyframeIndex;\n while (\n currentKeyframeIndex < this._keyframes.length - 1 &&\n this._keyframes[currentKeyframeIndex + 1].getKeyframeDate().getTime() <= date.getTime()\n ) {\n currentKeyframeIndex++;\n }\n\n if (currentKeyframeIndex !== prevIndex) {\n if (prevIndex !== -1) {\n this._keyframes[prevIndex].deactivate();\n }\n this._keyframes[currentKeyframeIndex].activate();\n }\n\n this._events.dateChanged.fire({\n date: date,\n activeKeyframe: this._keyframes[currentKeyframeIndex],\n startDate: startDate,\n endDate: endDate\n });\n });\n\n this._playback = tween;\n tween.start();\n }\n\n /**\n * Stops any ongoing playback\n */\n public stop(): void {\n if (this._playback !== undefined) {\n this._playback.stop();\n this._playback = undefined;\n }\n }\n\n /**\n * Pause any ongoing playback\n */\n public pause(): void {\n if (this._playback !== undefined && this._playback.isPlaying()) {\n this._playback.pause();\n }\n }\n\n /**\n * Resume any paused playback\n */\n public resume(): void {\n if (this._playback !== undefined && this._playback.isPaused()) {\n this._playback.resume();\n }\n }\n\n /**\n * Provides all Keyframes in the Timeline\n * @returns All Keyframes in Timeline\n */\n public getAllKeyframes(): Keyframe[] {\n return this._keyframes.slice();\n }\n\n public dispose(): void {\n super.dispose();\n this._events.dateChanged.unsubscribeAll();\n }\n\n /**\n * Sort the Timeline Keyframe by their Date\n */\n private sortKeyframesByDates() {\n if (this._keyframes.length > 1) {\n this._keyframes.sort((a: Keyframe, b: Keyframe) => {\n return a.getKeyframeDate().getTime() - b.getKeyframeDate().getTime();\n });\n }\n }\n}\n","/*!\n * Copyright 2021 Cognite AS\n */\nimport * as THREE from 'three';\n\nimport { Cognite3DViewer, Cognite3DModel } from '@reveal/core';\nimport { LevelOfDetail, SectorNode } from '@reveal/core/cad';\nimport { assertNever } from '@reveal/core/utilities';\n\nimport { Cognite3DViewerToolBase } from './Cognite3DViewerToolBase';\n\nexport type DebugLoadedSectorsToolOptions = {\n showSimpleSectors?: boolean;\n showDetailedSectors?: boolean;\n showDiscardedSectors?: boolean;\n colorBy?: 'depth' | 'lod' | 'loadedTimestamp' | 'random';\n leafsOnly?: boolean;\n sectorPathFilterRegex?: string;\n};\n\nexport class DebugLoadedSectorsTool extends Cognite3DViewerToolBase {\n private readonly _boundingBoxes = new THREE.Group();\n private readonly _viewer: Cognite3DViewer;\n private _options: Required<DebugLoadedSectorsToolOptions>;\n private _model?: Cognite3DModel;\n\n constructor(viewer: Cognite3DViewer, options: DebugLoadedSectorsToolOptions = {}) {\n super();\n this._viewer = viewer;\n this._viewer.addObject3D(this._boundingBoxes);\n this._options = {} as any; // Force - it's set in setOptions\n this.setOptions(options);\n }\n\n setOptions(options: DebugLoadedSectorsToolOptions): void {\n this._options = {\n showDetailedSectors: true,\n showDiscardedSectors: false,\n showSimpleSectors: true,\n colorBy: 'lod',\n leafsOnly: false,\n sectorPathFilterRegex: '.*',\n ...options\n };\n }\n\n dispose(): void {\n this._viewer.removeObject3D(this._boundingBoxes);\n }\n\n showSectorBoundingBoxes(model: Cognite3DModel): void {\n this._model = model;\n this.updateBoundingBoxes();\n }\n\n private updateBoundingBoxes() {\n this._boundingBoxes.clear();\n if (this._model === undefined) {\n return;\n }\n this._model.getModelTransformation(this._boundingBoxes.matrix);\n const shouldShowLod: boolean[] = [];\n shouldShowLod[LevelOfDetail.Discarded] = this._options.showDiscardedSectors;\n shouldShowLod[LevelOfDetail.Simple] = this._options.showSimpleSectors;\n shouldShowLod[LevelOfDetail.Detailed] = this._options.showDetailedSectors;\n\n const selectedSectorNodes: SectorNode[] = [];\n this._model.cadNode.traverse(node => {\n if (isSectorNode(node)) {\n const sectorNode = node as SectorNode;\n\n if (\n this.isSectorAcceptedByCurrentFilter(sectorNode) &&\n shouldShowLod[sectorNode.levelOfDetail] &&\n (!this._options.leafsOnly || isLeaf(sectorNode))\n ) {\n selectedSectorNodes.push(sectorNode);\n }\n }\n });\n\n selectedSectorNodes.forEach(sectorNode => {\n const bboxNode = this.createBboxNodeFor(sectorNode, selectedSectorNodes);\n this._boundingBoxes.add(bboxNode);\n });\n this._boundingBoxes.updateMatrixWorld(true);\n\n this._viewer.requestRedraw();\n }\n\n private isSectorAcceptedByCurrentFilter(node: SectorNode): boolean {\n const accepted = new RegExp(this._options.sectorPathFilterRegex).test(node.sectorPath);\n return accepted;\n }\n\n private createBboxNodeFor(node: SectorNode, allSelectedNodes: SectorNode[]) {\n const options = this._options;\n function determineColor() {\n switch (options.colorBy) {\n case 'depth': {\n const s = Math.min(1.0, node.depth / 8);\n return new THREE.Color(Colors.green).lerpHSL(Colors.red, s);\n }\n case 'lod': {\n switch (node.levelOfDetail) {\n case LevelOfDetail.Simple:\n return Colors.yellow;\n case LevelOfDetail.Detailed:\n return Colors.green;\n case LevelOfDetail.Discarded:\n return Colors.red;\n default:\n assertNever(node.levelOfDetail);\n }\n }\n case 'loadedTimestamp': {\n // Note! Horribly slow since we do this for every sector, but since this is a debug tool\n // we consider it OK\n const nodesByTimestamp = [...allSelectedNodes].sort((a, b) => a.updatedTimestamp - b.updatedTimestamp);\n const indexOfNode = nodesByTimestamp.findIndex(x => x === node);\n const s = (nodesByTimestamp.length - 1 - indexOfNode) / Math.max(nodesByTimestamp.length - 1, 1);\n return new THREE.Color(Colors.green).lerpHSL(Colors.red, s);\n }\n\n case 'random':\n return new THREE.Color().setHSL(Math.random(), 1.0, 0.5);\n\n default:\n assertNever(options.colorBy);\n }\n }\n const color = determineColor();\n return new THREE.Box3Helper(node.bounds, color);\n }\n}\n\nconst Colors = {\n green: new THREE.Color('#00ff00'),\n yellow: new THREE.Color('yellow'),\n red: new THREE.Color('red')\n};\n\nfunction isSectorNode(node: THREE.Object3D) {\n return node.name.match(/^Sector \\d+$/);\n}\n\nfunction isLeaf(node: SectorNode) {\n return !node.children.some(x => isSectorNode(x));\n}\n"],"sourceRoot":""}
|