@xtctwins/tctwins-core 1.0.35 → 1.0.36

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.
@@ -1404,7 +1404,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1404
1404
  \**********************/
1405
1405
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1406
1406
 
1407
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AlphaFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.AlphaFormat),\n/* harmony export */ AmbientLight: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.AmbientLight),\n/* harmony export */ AngleMeasurementsControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AngleMeasurementsControl),\n/* harmony export */ AngleMeasurementsMouseControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AngleMeasurementsMouseControl),\n/* harmony export */ AngleMeasurementsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AngleMeasurementsPlugin),\n/* harmony export */ AngleMeasurementsTouchControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AngleMeasurementsTouchControl),\n/* harmony export */ AnnotationsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AnnotationsPlugin),\n/* harmony export */ AxisGizmoPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AxisGizmoPlugin),\n/* harmony export */ BCFViewpointsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.BCFViewpointsPlugin),\n/* harmony export */ Bitmap: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Bitmap),\n/* harmony export */ ByteType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ByteType),\n/* harmony export */ CameraMemento: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CameraMemento),\n/* harmony export */ CameraPath: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CameraPath),\n/* harmony export */ CameraPathAnimation: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CameraPathAnimation),\n/* harmony export */ CityJSONLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.CityJSONLoaderPlugin),\n/* harmony export */ ClampToEdgeWrapping: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ClampToEdgeWrapping),\n/* harmony export */ Component: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Component),\n/* harmony export */ CompressedMediaType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CompressedMediaType),\n/* harmony export */ Configs: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Configs),\n/* harmony export */ ContextMenu: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.ContextMenu),\n/* harmony export */ CubicBezierCurve: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CubicBezierCurve),\n/* harmony export */ Curve: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Curve),\n/* harmony export */ DefaultLoadingManager: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.DefaultLoadingManager),\n/* harmony export */ DepthFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.DepthFormat),\n/* harmony export */ DepthStencilFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.DepthStencilFormat),\n/* harmony export */ DirLight: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.DirLight),\n/* harmony export */ DistanceMeasurementsControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.DistanceMeasurementsControl),\n/* harmony export */ DistanceMeasurementsMouseControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.DistanceMeasurementsMouseControl),\n/* harmony export */ DistanceMeasurementsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.DistanceMeasurementsPlugin),\n/* harmony export */ DistanceMeasurementsTouchControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.DistanceMeasurementsTouchControl),\n/* harmony export */ EdgeMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.EdgeMaterial),\n/* harmony export */ EmphasisMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.EmphasisMaterial),\n/* harmony export */ FaceAlignedSectionPlanesPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.FaceAlignedSectionPlanesPlugin),\n/* harmony export */ FastNavPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.FastNavPlugin),\n/* harmony export */ FloatType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.FloatType),\n/* harmony export */ Fresnel: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Fresnel),\n/* harmony export */ Frustum: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Frustum),\n/* harmony export */ FrustumPlane: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.FrustumPlane),\n/* harmony export */ GIFMediaType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.GIFMediaType),\n/* harmony export */ GLTFDefaultDataSource: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.GLTFDefaultDataSource),\n/* harmony export */ GLTFLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderPlugin),\n/* harmony export */ HalfFloatType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.HalfFloatType),\n/* harmony export */ ImagePlane: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ImagePlane),\n/* harmony export */ IntType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.IntType),\n/* harmony export */ JPEGMediaType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.JPEGMediaType),\n/* harmony export */ KTX2TextureTranscoder: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.KTX2TextureTranscoder),\n/* harmony export */ LASLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.LASLoaderPlugin),\n/* harmony export */ LambertMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LambertMaterial),\n/* harmony export */ LightMap: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LightMap),\n/* harmony export */ LineSet: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LineSet),\n/* harmony export */ LinearEncoding: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearEncoding),\n/* harmony export */ LinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearFilter),\n/* harmony export */ LinearMipMapLinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearMipMapLinearFilter),\n/* harmony export */ LinearMipMapNearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearMipMapNearestFilter),\n/* harmony export */ LinearMipmapLinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearMipmapLinearFilter),\n/* harmony export */ LinearMipmapNearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearMipmapNearestFilter),\n/* harmony export */ Loader: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Loader),\n/* harmony export */ LoadingManager: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LoadingManager),\n/* harmony export */ LocaleService: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LocaleService),\n/* harmony export */ LuminanceAlphaFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LuminanceAlphaFormat),\n/* harmony export */ LuminanceFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LuminanceFormat),\n/* harmony export */ Map: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Map),\n/* harmony export */ Marker: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Marker),\n/* harmony export */ MarqueePicker: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.MarqueePicker),\n/* harmony export */ MarqueePickerMouseControl: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.MarqueePickerMouseControl),\n/* harmony export */ Mesh: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Mesh),\n/* harmony export */ MetallicMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.MetallicMaterial),\n/* harmony export */ MirroredRepeatWrapping: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.MirroredRepeatWrapping),\n/* harmony export */ ModelMemento: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ModelMemento),\n/* harmony export */ NavCubePlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.NavCubePlugin),\n/* harmony export */ NearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestFilter),\n/* harmony export */ NearestMipMapLinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestMipMapLinearFilter),\n/* harmony export */ NearestMipMapNearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestMipMapNearestFilter),\n/* harmony export */ NearestMipmapLinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestMipmapLinearFilter),\n/* harmony export */ NearestMipmapNearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestMipmapNearestFilter),\n/* harmony export */ Node: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Node),\n/* harmony export */ OBJLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.OBJLoaderPlugin),\n/* harmony export */ ObjectsKdTree3: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.ObjectsKdTree3),\n/* harmony export */ ObjectsMemento: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ObjectsMemento),\n/* harmony export */ PNGMediaType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.PNGMediaType),\n/* harmony export */ Path: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Path),\n/* harmony export */ PerformanceModel: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.PerformanceModel),\n/* harmony export */ PhongMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.PhongMaterial),\n/* harmony export */ Plugin: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Plugin),\n/* harmony export */ PointLight: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.PointLight),\n/* harmony export */ PointerLens: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.PointerLens),\n/* harmony export */ QuadraticBezierCurve: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.QuadraticBezierCurve),\n/* harmony export */ Queue: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Queue),\n/* harmony export */ RGBAFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBAFormat),\n/* harmony export */ RGBAIntegerFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBAIntegerFormat),\n/* harmony export */ RGBA_ASTC_10x10_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_10x10_Format),\n/* harmony export */ RGBA_ASTC_10x5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_10x5_Format),\n/* harmony export */ RGBA_ASTC_10x6_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_10x6_Format),\n/* harmony export */ RGBA_ASTC_10x8_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_10x8_Format),\n/* harmony export */ RGBA_ASTC_12x10_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_12x10_Format),\n/* harmony export */ RGBA_ASTC_12x12_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_12x12_Format),\n/* harmony export */ RGBA_ASTC_4x4_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_4x4_Format),\n/* harmony export */ RGBA_ASTC_5x4_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_5x4_Format),\n/* harmony export */ RGBA_ASTC_5x5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_5x5_Format),\n/* harmony export */ RGBA_ASTC_6x5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_6x5_Format),\n/* harmony export */ RGBA_ASTC_6x6_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_6x6_Format),\n/* harmony export */ RGBA_ASTC_8x5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_8x5_Format),\n/* harmony export */ RGBA_ASTC_8x6_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_8x6_Format),\n/* harmony export */ RGBA_ASTC_8x8_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_8x8_Format),\n/* harmony export */ RGBA_BPTC_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_BPTC_Format),\n/* harmony export */ RGBA_ETC2_EAC_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ETC2_EAC_Format),\n/* harmony export */ RGBA_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_PVRTC_2BPPV1_Format),\n/* harmony export */ RGBA_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_PVRTC_4BPPV1_Format),\n/* harmony export */ RGBA_S3TC_DXT1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_S3TC_DXT1_Format),\n/* harmony export */ RGBA_S3TC_DXT3_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_S3TC_DXT3_Format),\n/* harmony export */ RGBA_S3TC_DXT5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_S3TC_DXT5_Format),\n/* harmony export */ RGBFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBFormat),\n/* harmony export */ RGB_ETC1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_ETC1_Format),\n/* harmony export */ RGB_ETC2_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_ETC2_Format),\n/* harmony export */ RGB_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_PVRTC_2BPPV1_Format),\n/* harmony export */ RGB_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_PVRTC_4BPPV1_Format),\n/* harmony export */ RGB_S3TC_DXT1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_S3TC_DXT1_Format),\n/* harmony export */ RGFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGFormat),\n/* harmony export */ RGIntegerFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGIntegerFormat),\n/* harmony export */ ReadableGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ReadableGeometry),\n/* harmony export */ RedFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RedFormat),\n/* harmony export */ RedIntegerFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RedIntegerFormat),\n/* harmony export */ ReflectionMap: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ReflectionMap),\n/* harmony export */ RepeatWrapping: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RepeatWrapping),\n/* harmony export */ STLDefaultDataSource: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.STLDefaultDataSource),\n/* harmony export */ STLLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.STLLoaderPlugin),\n/* harmony export */ SceneModel: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SceneModel),\n/* harmony export */ SceneModelMesh: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SceneModelMesh),\n/* harmony export */ SceneModelTransform: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SceneModelTransform),\n/* harmony export */ SectionBox: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SectionBox),\n/* harmony export */ SectionPlane: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SectionPlane),\n/* harmony export */ SectionPlanesPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.SectionPlanesPlugin),\n/* harmony export */ ShortType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ShortType),\n/* harmony export */ Skybox: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Skybox),\n/* harmony export */ SkyboxesPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.SkyboxesPlugin),\n/* harmony export */ SpecularMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SpecularMaterial),\n/* harmony export */ SplineCurve: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SplineCurve),\n/* harmony export */ SpriteMarker: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SpriteMarker),\n/* harmony export */ StoreyViewsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.StoreyViewsPlugin),\n/* harmony export */ Texture: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Texture),\n/* harmony export */ TextureTranscoder: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.TextureTranscoder),\n/* harmony export */ TreeViewPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.TreeViewPlugin),\n/* harmony export */ UnsignedByteType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedByteType),\n/* harmony export */ UnsignedInt248Type: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedInt248Type),\n/* harmony export */ UnsignedIntType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedIntType),\n/* harmony export */ UnsignedShort4444Type: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedShort4444Type),\n/* harmony export */ UnsignedShort5551Type: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedShort5551Type),\n/* harmony export */ UnsignedShortType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedShortType),\n/* harmony export */ VBOGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.VBOGeometry),\n/* harmony export */ ViewCullPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.ViewCullPlugin),\n/* harmony export */ Viewer: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Viewer),\n/* harmony export */ WebIFCLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.WebIFCLoaderPlugin),\n/* harmony export */ WorkerPool: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.WorkerPool),\n/* harmony export */ XML3DLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.XML3DLoaderPlugin),\n/* harmony export */ XTCDefaultDataSource: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.XTCDefaultDataSource),\n/* harmony export */ XTCLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.XTCLoaderPlugin),\n/* harmony export */ buildBoxGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildBoxGeometry),\n/* harmony export */ buildBoxLinesGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildBoxLinesGeometry),\n/* harmony export */ buildCylinderGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildCylinderGeometry),\n/* harmony export */ buildGridGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildGridGeometry),\n/* harmony export */ buildPlaneGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildPlaneGeometry),\n/* harmony export */ buildSphereGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildSphereGeometry),\n/* harmony export */ buildTorusGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry),\n/* harmony export */ buildVectorTextGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildVectorTextGeometry),\n/* harmony export */ createRTCViewMat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.createRTCViewMat),\n/* harmony export */ frustumIntersectsAABB3: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.frustumIntersectsAABB3),\n/* harmony export */ getKTX2TextureTranscoder: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.getKTX2TextureTranscoder),\n/* harmony export */ getPlaneRTCPos: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.getPlaneRTCPos),\n/* harmony export */ load3DSGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.load3DSGeometry),\n/* harmony export */ loadOBJGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.loadOBJGeometry),\n/* harmony export */ math: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.math),\n/* harmony export */ rtcToWorldPos: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.rtcToWorldPos),\n/* harmony export */ sRGBEncoding: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.sRGBEncoding),\n/* harmony export */ setFrustum: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.setFrustum),\n/* harmony export */ stats: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.stats),\n/* harmony export */ utils: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.utils),\n/* harmony export */ worldToRTCPos: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.worldToRTCPos),\n/* harmony export */ worldToRTCPositions: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.worldToRTCPositions)\n/* harmony export */ });\n/* harmony import */ var _extras_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./extras/index.js */ \"./src/extras/index.js\");\n/* harmony import */ var _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./plugins/index.js */ \"./src/plugins/index.js\");\n/* harmony import */ var _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./viewer/index.js */ \"./src/viewer/index.js\");\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/index.js?");
1407
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AlphaFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.AlphaFormat),\n/* harmony export */ AmbientLight: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.AmbientLight),\n/* harmony export */ AngleMeasurementsControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AngleMeasurementsControl),\n/* harmony export */ AngleMeasurementsMouseControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AngleMeasurementsMouseControl),\n/* harmony export */ AngleMeasurementsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AngleMeasurementsPlugin),\n/* harmony export */ AngleMeasurementsTouchControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AngleMeasurementsTouchControl),\n/* harmony export */ AnnotationsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AnnotationsPlugin),\n/* harmony export */ AxisGizmoPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.AxisGizmoPlugin),\n/* harmony export */ BCFViewpointsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.BCFViewpointsPlugin),\n/* harmony export */ Bitmap: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Bitmap),\n/* harmony export */ ByteType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ByteType),\n/* harmony export */ CameraMemento: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CameraMemento),\n/* harmony export */ CameraPath: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CameraPath),\n/* harmony export */ CameraPathAnimation: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CameraPathAnimation),\n/* harmony export */ Canvas: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Canvas),\n/* harmony export */ CityJSONLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.CityJSONLoaderPlugin),\n/* harmony export */ ClampToEdgeWrapping: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ClampToEdgeWrapping),\n/* harmony export */ Component: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Component),\n/* harmony export */ CompressedMediaType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CompressedMediaType),\n/* harmony export */ Configs: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Configs),\n/* harmony export */ ContextMenu: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.ContextMenu),\n/* harmony export */ CubicBezierCurve: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.CubicBezierCurve),\n/* harmony export */ Curve: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Curve),\n/* harmony export */ DefaultLoadingManager: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.DefaultLoadingManager),\n/* harmony export */ DepthFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.DepthFormat),\n/* harmony export */ DepthStencilFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.DepthStencilFormat),\n/* harmony export */ DirLight: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.DirLight),\n/* harmony export */ DistanceMeasurementsControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.DistanceMeasurementsControl),\n/* harmony export */ DistanceMeasurementsMouseControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.DistanceMeasurementsMouseControl),\n/* harmony export */ DistanceMeasurementsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.DistanceMeasurementsPlugin),\n/* harmony export */ DistanceMeasurementsTouchControl: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.DistanceMeasurementsTouchControl),\n/* harmony export */ EdgeMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.EdgeMaterial),\n/* harmony export */ EmphasisMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.EmphasisMaterial),\n/* harmony export */ FaceAlignedSectionPlanesPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.FaceAlignedSectionPlanesPlugin),\n/* harmony export */ FastNavPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.FastNavPlugin),\n/* harmony export */ FloatType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.FloatType),\n/* harmony export */ Fresnel: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Fresnel),\n/* harmony export */ Frustum: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Frustum),\n/* harmony export */ FrustumPlane: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.FrustumPlane),\n/* harmony export */ GIFMediaType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.GIFMediaType),\n/* harmony export */ GLTFDefaultDataSource: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.GLTFDefaultDataSource),\n/* harmony export */ GLTFLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderPlugin),\n/* harmony export */ HalfFloatType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.HalfFloatType),\n/* harmony export */ ImagePlane: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ImagePlane),\n/* harmony export */ IntType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.IntType),\n/* harmony export */ JPEGMediaType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.JPEGMediaType),\n/* harmony export */ KTX2TextureTranscoder: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.KTX2TextureTranscoder),\n/* harmony export */ LASLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.LASLoaderPlugin),\n/* harmony export */ LambertMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LambertMaterial),\n/* harmony export */ LightMap: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LightMap),\n/* harmony export */ LineSet: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LineSet),\n/* harmony export */ LinearEncoding: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearEncoding),\n/* harmony export */ LinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearFilter),\n/* harmony export */ LinearMipMapLinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearMipMapLinearFilter),\n/* harmony export */ LinearMipMapNearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearMipMapNearestFilter),\n/* harmony export */ LinearMipmapLinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearMipmapLinearFilter),\n/* harmony export */ LinearMipmapNearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LinearMipmapNearestFilter),\n/* harmony export */ Loader: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Loader),\n/* harmony export */ LoadingManager: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LoadingManager),\n/* harmony export */ LocaleService: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LocaleService),\n/* harmony export */ LuminanceAlphaFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LuminanceAlphaFormat),\n/* harmony export */ LuminanceFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.LuminanceFormat),\n/* harmony export */ Map: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Map),\n/* harmony export */ Marker: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Marker),\n/* harmony export */ MarqueePicker: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.MarqueePicker),\n/* harmony export */ MarqueePickerMouseControl: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.MarqueePickerMouseControl),\n/* harmony export */ Mesh: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Mesh),\n/* harmony export */ MetallicMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.MetallicMaterial),\n/* harmony export */ MirroredRepeatWrapping: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.MirroredRepeatWrapping),\n/* harmony export */ ModelMemento: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ModelMemento),\n/* harmony export */ NavCubePlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.NavCubePlugin),\n/* harmony export */ NearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestFilter),\n/* harmony export */ NearestMipMapLinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestMipMapLinearFilter),\n/* harmony export */ NearestMipMapNearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestMipMapNearestFilter),\n/* harmony export */ NearestMipmapLinearFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestMipmapLinearFilter),\n/* harmony export */ NearestMipmapNearestFilter: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.NearestMipmapNearestFilter),\n/* harmony export */ Node: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Node),\n/* harmony export */ OBJLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.OBJLoaderPlugin),\n/* harmony export */ ObjectsKdTree3: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.ObjectsKdTree3),\n/* harmony export */ ObjectsMemento: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ObjectsMemento),\n/* harmony export */ PNGMediaType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.PNGMediaType),\n/* harmony export */ Path: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Path),\n/* harmony export */ PerformanceModel: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.PerformanceModel),\n/* harmony export */ PhongMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.PhongMaterial),\n/* harmony export */ Plugin: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Plugin),\n/* harmony export */ PointLight: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.PointLight),\n/* harmony export */ PointerLens: () => (/* reexport safe */ _extras_index_js__WEBPACK_IMPORTED_MODULE_0__.PointerLens),\n/* harmony export */ QuadraticBezierCurve: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.QuadraticBezierCurve),\n/* harmony export */ Queue: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Queue),\n/* harmony export */ RGBAFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBAFormat),\n/* harmony export */ RGBAIntegerFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBAIntegerFormat),\n/* harmony export */ RGBA_ASTC_10x10_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_10x10_Format),\n/* harmony export */ RGBA_ASTC_10x5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_10x5_Format),\n/* harmony export */ RGBA_ASTC_10x6_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_10x6_Format),\n/* harmony export */ RGBA_ASTC_10x8_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_10x8_Format),\n/* harmony export */ RGBA_ASTC_12x10_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_12x10_Format),\n/* harmony export */ RGBA_ASTC_12x12_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_12x12_Format),\n/* harmony export */ RGBA_ASTC_4x4_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_4x4_Format),\n/* harmony export */ RGBA_ASTC_5x4_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_5x4_Format),\n/* harmony export */ RGBA_ASTC_5x5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_5x5_Format),\n/* harmony export */ RGBA_ASTC_6x5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_6x5_Format),\n/* harmony export */ RGBA_ASTC_6x6_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_6x6_Format),\n/* harmony export */ RGBA_ASTC_8x5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_8x5_Format),\n/* harmony export */ RGBA_ASTC_8x6_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_8x6_Format),\n/* harmony export */ RGBA_ASTC_8x8_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ASTC_8x8_Format),\n/* harmony export */ RGBA_BPTC_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_BPTC_Format),\n/* harmony export */ RGBA_ETC2_EAC_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_ETC2_EAC_Format),\n/* harmony export */ RGBA_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_PVRTC_2BPPV1_Format),\n/* harmony export */ RGBA_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_PVRTC_4BPPV1_Format),\n/* harmony export */ RGBA_S3TC_DXT1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_S3TC_DXT1_Format),\n/* harmony export */ RGBA_S3TC_DXT3_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_S3TC_DXT3_Format),\n/* harmony export */ RGBA_S3TC_DXT5_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBA_S3TC_DXT5_Format),\n/* harmony export */ RGBFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGBFormat),\n/* harmony export */ RGB_ETC1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_ETC1_Format),\n/* harmony export */ RGB_ETC2_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_ETC2_Format),\n/* harmony export */ RGB_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_PVRTC_2BPPV1_Format),\n/* harmony export */ RGB_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_PVRTC_4BPPV1_Format),\n/* harmony export */ RGB_S3TC_DXT1_Format: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGB_S3TC_DXT1_Format),\n/* harmony export */ RGFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGFormat),\n/* harmony export */ RGIntegerFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RGIntegerFormat),\n/* harmony export */ ReadableGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ReadableGeometry),\n/* harmony export */ RedFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RedFormat),\n/* harmony export */ RedIntegerFormat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RedIntegerFormat),\n/* harmony export */ ReflectionMap: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ReflectionMap),\n/* harmony export */ Renderer: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Renderer),\n/* harmony export */ RepeatWrapping: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.RepeatWrapping),\n/* harmony export */ STLDefaultDataSource: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.STLDefaultDataSource),\n/* harmony export */ STLLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.STLLoaderPlugin),\n/* harmony export */ Scene: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Scene),\n/* harmony export */ SceneModel: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SceneModel),\n/* harmony export */ SceneModelMesh: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SceneModelMesh),\n/* harmony export */ SceneModelTransform: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SceneModelTransform),\n/* harmony export */ SectionBox: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SectionBox),\n/* harmony export */ SectionPlane: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SectionPlane),\n/* harmony export */ SectionPlanesPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.SectionPlanesPlugin),\n/* harmony export */ ShortType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.ShortType),\n/* harmony export */ Skybox: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Skybox),\n/* harmony export */ SkyboxesPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.SkyboxesPlugin),\n/* harmony export */ SpecularMaterial: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SpecularMaterial),\n/* harmony export */ SplineCurve: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SplineCurve),\n/* harmony export */ SpriteMarker: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.SpriteMarker),\n/* harmony export */ StoreyViewsPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.StoreyViewsPlugin),\n/* harmony export */ Texture: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Texture),\n/* harmony export */ TextureTranscoder: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.TextureTranscoder),\n/* harmony export */ TreeViewPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.TreeViewPlugin),\n/* harmony export */ UnsignedByteType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedByteType),\n/* harmony export */ UnsignedInt248Type: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedInt248Type),\n/* harmony export */ UnsignedIntType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedIntType),\n/* harmony export */ UnsignedShort4444Type: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedShort4444Type),\n/* harmony export */ UnsignedShort5551Type: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedShort5551Type),\n/* harmony export */ UnsignedShortType: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.UnsignedShortType),\n/* harmony export */ VBOGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.VBOGeometry),\n/* harmony export */ ViewCullPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.ViewCullPlugin),\n/* harmony export */ Viewer: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.Viewer),\n/* harmony export */ WebIFCLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.WebIFCLoaderPlugin),\n/* harmony export */ WorkerPool: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.WorkerPool),\n/* harmony export */ XML3DLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.XML3DLoaderPlugin),\n/* harmony export */ XTCDefaultDataSource: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.XTCDefaultDataSource),\n/* harmony export */ XTCLoaderPlugin: () => (/* reexport safe */ _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__.XTCLoaderPlugin),\n/* harmony export */ buildBoxGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildBoxGeometry),\n/* harmony export */ buildBoxLinesGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildBoxLinesGeometry),\n/* harmony export */ buildCylinderGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildCylinderGeometry),\n/* harmony export */ buildGridGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildGridGeometry),\n/* harmony export */ buildPlaneGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildPlaneGeometry),\n/* harmony export */ buildSphereGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildSphereGeometry),\n/* harmony export */ buildTorusGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry),\n/* harmony export */ buildVectorTextGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.buildVectorTextGeometry),\n/* harmony export */ createRTCViewMat: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.createRTCViewMat),\n/* harmony export */ frustumIntersectsAABB3: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.frustumIntersectsAABB3),\n/* harmony export */ getKTX2TextureTranscoder: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.getKTX2TextureTranscoder),\n/* harmony export */ getPlaneRTCPos: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.getPlaneRTCPos),\n/* harmony export */ load3DSGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.load3DSGeometry),\n/* harmony export */ loadOBJGeometry: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.loadOBJGeometry),\n/* harmony export */ math: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.math),\n/* harmony export */ rtcToWorldPos: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.rtcToWorldPos),\n/* harmony export */ sRGBEncoding: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.sRGBEncoding),\n/* harmony export */ setFrustum: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.setFrustum),\n/* harmony export */ stats: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.stats),\n/* harmony export */ utils: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.utils),\n/* harmony export */ worldToRTCPos: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.worldToRTCPos),\n/* harmony export */ worldToRTCPositions: () => (/* reexport safe */ _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__.worldToRTCPositions)\n/* harmony export */ });\n/* harmony import */ var _extras_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./extras/index.js */ \"./src/extras/index.js\");\n/* harmony import */ var _plugins_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./plugins/index.js */ \"./src/plugins/index.js\");\n/* harmony import */ var _viewer_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./viewer/index.js */ \"./src/viewer/index.js\");\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/index.js?");
1408
1408
 
1409
1409
  /***/ }),
1410
1410
 
@@ -1644,7 +1644,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1644
1644
  \**************************************************************************************/
1645
1645
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1646
1646
 
1647
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ FaceAlignedSectionPlanesPlugin: () => (/* binding */ FaceAlignedSectionPlanesPlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_sectionPlane_SectionPlane_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/sectionPlane/SectionPlane.js */ \"./src/viewer/scene/sectionPlane/SectionPlane.js\");\n/* harmony import */ var _FaceAlignedSectionPlanesControl_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./FaceAlignedSectionPlanesControl.js */ \"./src/plugins/FaceAlignedSectionPlanesPlugin/FaceAlignedSectionPlanesControl.js\");\n/* harmony import */ var _Overview_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Overview.js */ \"./src/plugins/FaceAlignedSectionPlanesPlugin/Overview.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst tempAABB = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.AABB3();\r\nconst tempVec3 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n/**\r\n * FaceAlignedSectionPlanesPlugin is a {@link Viewer} plugin that creates and edits face-aligned {@link SectionPlane}s.\r\n *\r\n * [<img src=\"https://xeokit.github.io/xeokit-sdk/assets/images/FaceAlignedSectionPlanesPlugin.gif\">](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_FaceAlignedSectionPlanesPlugin)\r\n *\r\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_FaceAlignedSectionPlanesPlugin)]\r\n *\r\n * ## Overview\r\n *\r\n * * Use the FaceAlignedSectionPlanesPlugin to\r\n * create and edit {@link SectionPlane}s to slice portions off your models and reveal internal structures.\r\n *\r\n * * As shown in the screen capture above, FaceAlignedSectionPlanesPlugin shows an overview of all your SectionPlanes (on the right, in\r\n * this example).\r\n * * Click a plane in the overview to activate a 3D control with which you can interactively\r\n * reposition its SectionPlane in the main canvas.\r\n * * Configure the plugin with an HTML element that the user can click-and-drag on to reposition the SectionPlane for which the control is active.\r\n * * Use {@link BCFViewpointsPlugin} to save and load SectionPlanes in BCF viewpoints.\r\n *\r\n * ## Usage\r\n *\r\n * In the example below, we'll use a {@link GLTFLoaderPlugin} to load a model, and a FaceAlignedSectionPlanesPlugin\r\n * to slice it open with two {@link SectionPlane}s. We'll show the overview in the bottom right of the Viewer\r\n * canvas. Finally, we'll programmatically activate the 3D editing control, so that we can use it to interactively\r\n * reposition our second SectionPlane.\r\n *\r\n * ````JavaScript\r\n * import {Viewer, GLTFLoaderPlugin, FaceAlignedSectionPlanesPlugin} from \"xeokit-sdk.es.js\";\r\n *\r\n * // Create a Viewer and arrange its Camera\r\n *\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\"\r\n * });\r\n *\r\n * viewer.camera.eye = [-5.02, 2.22, 15.09];\r\n * viewer.camera.look = [4.97, 2.79, 9.89];\r\n * viewer.camera.up = [-0.05, 0.99, 0.02];\r\n *\r\n * // Add a GLTFLoaderPlugin\r\n *\r\n * const gltfLoader = new GLTFLoaderPlugin(viewer);\r\n *\r\n * // Add a FaceAlignedSectionPlanesPlugin, with overview visible\r\n *\r\n * const faceAlignedSectionPlanes = new FaceAlignedSectionPlanesPlugin(viewer, {\r\n * overviewCanvasID: \"myOverviewCanvas\",\r\n * overviewVisible: true,\r\n * controlElementId: \"myControlElement\", // ID of element to capture drag events that move the SectionPlane\r\n * dragSensitivity: 1 // Sensitivity factor that governs the rate at which dragging moves the SectionPlane\r\n * });\r\n *\r\n * // Load a model\r\n *\r\n * const model = gltfLoader.load({\r\n * id: \"myModel\",\r\n * src: \"./models/gltf/schependomlaan/scene.glb\"\r\n * });\r\n *\r\n * // Create a couple of section planes\r\n * // These will be shown in the overview\r\n *\r\n * faceAlignedSectionPlanes.createSectionPlane({\r\n * id: \"mySectionPlane\",\r\n * pos: [1.04, 1.95, 9.74],\r\n * dir: [1.0, 0.0, 0.0]\r\n * });\r\n *\r\n * faceAlignedSectionPlanes.createSectionPlane({\r\n * id: \"mySectionPlane2\",\r\n * pos: [2.30, 4.46, 14.93],\r\n * dir: [0.0, -0.09, -0.79]\r\n * });\r\n *\r\n * // Show the FaceAlignedSectionPlanesPlugin's 3D editing gizmo,\r\n * // to interactively reposition one of our SectionPlanes\r\n *\r\n * faceAlignedSectionPlanes.showControl(\"mySectionPlane2\");\r\n *\r\n * const mySectionPlane2 = faceAlignedSectionPlanes.sectionPlanes[\"mySectionPlane2\"];\r\n *\r\n * // Programmatically reposition one of our SectionPlanes\r\n * // This also updates its position as shown in the overview gizmo\r\n *\r\n * mySectionPlane2.pos = [11.0, 6.0, -12];\r\n * mySectionPlane2.dir = [0.4, 0.0, 0.5];\r\n * ````\r\n */\r\nclass FaceAlignedSectionPlanesPlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_1__.Plugin {\r\n\r\n /**\r\n * @constructor\r\n * @param {Viewer} viewer The Viewer.\r\n * @param {Object} cfg Plugin configuration.\r\n * @param {String} [cfg.id=\"SectionPlanes\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\r\n * @param {String} [cfg.overviewCanvasId] ID of a canvas element to display the overview.\r\n * @param {String} [cfg.overviewVisible=true] Initial visibility of the overview canvas.\r\n * @param {String} cfg.controlElementId ID of an HTML element that catches drag events to move the active SectionPlane.\r\n * @param {Number} [cfg.dragSensitivity=1] Sensitivity factor that governs the rate at which dragging on the control element moves SectionPlane.\r\n */\r\n constructor(viewer, cfg = {}) {\r\n\r\n super(\"FaceAlignedSectionPlanesPlugin\", viewer);\r\n\r\n this._freeControls = [];\r\n this._sectionPlanes = viewer.scene.sectionPlanes;\r\n this._controls = {};\r\n this._shownControlId = null;\r\n this._dragSensitivity = cfg.dragSensitivity || 1;\r\n\r\n if (cfg.overviewCanvasId !== null && cfg.overviewCanvasId !== undefined) {\r\n\r\n const overviewCanvas = document.getElementById(cfg.overviewCanvasId);\r\n\r\n if (!overviewCanvas) {\r\n this.warn(\"Can't find overview canvas: '\" + cfg.overviewCanvasId + \"' - will create plugin without overview\");\r\n\r\n } else {\r\n\r\n this._overview = new _Overview_js__WEBPACK_IMPORTED_MODULE_4__.Overview(this, {\r\n overviewCanvas: overviewCanvas,\r\n visible: cfg.overviewVisible,\r\n\r\n onHoverEnterPlane: ((id) => {\r\n this._overview.setPlaneHighlighted(id, true);\r\n }),\r\n\r\n onHoverLeavePlane: ((id) => {\r\n this._overview.setPlaneHighlighted(id, false);\r\n }),\r\n\r\n onClickedPlane: ((id) => {\r\n if (this.getShownControl() === id) {\r\n this.hideControl();\r\n return;\r\n }\r\n this.showControl(id);\r\n const sectionPlane = this.sectionPlanes[id];\r\n const sectionPlanePos = sectionPlane.pos;\r\n tempAABB.set(this.viewer.scene.aabb);\r\n _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(tempAABB, tempVec3);\r\n tempAABB[0] += sectionPlanePos[0] - tempVec3[0];\r\n tempAABB[1] += sectionPlanePos[1] - tempVec3[1];\r\n tempAABB[2] += sectionPlanePos[2] - tempVec3[2];\r\n tempAABB[3] += sectionPlanePos[0] - tempVec3[0];\r\n tempAABB[4] += sectionPlanePos[1] - tempVec3[1];\r\n tempAABB[5] += sectionPlanePos[2] - tempVec3[2];\r\n this.viewer.cameraFlight.flyTo({\r\n aabb: tempAABB,\r\n fitFOV: 65\r\n });\r\n }),\r\n\r\n onClickedNothing: (() => {\r\n this.hideControl();\r\n })\r\n });\r\n }\r\n }\r\n\r\n if (cfg.controlElementId === null || cfg.controlElementId === undefined) {\r\n this.error(\"Parameter expected: controlElementId\");\r\n } else {\r\n this._controlElement = document.getElementById(cfg.controlElementId);\r\n if (!this._controlElement) {\r\n this.warn(\"Can't find control element: '\" + cfg.controlElementId + \"' - will create plugin without control element\");\r\n\r\n }\r\n }\r\n\r\n this._onSceneSectionPlaneCreated = viewer.scene.on(\"sectionPlaneCreated\", (sectionPlane) => {\r\n\r\n // SectionPlane created, either via FaceAlignedSectionPlanesPlugin#createSectionPlane(), or by directly\r\n // instantiating a SectionPlane independently of FaceAlignedSectionPlanesPlugin, which can be done\r\n // by BCFViewpointsPlugin#loadViewpoint().\r\n\r\n this._sectionPlaneCreated(sectionPlane);\r\n });\r\n }\r\n\r\n /**\r\n * Sets the factor that governs how fast a SectionPlane moves as we drag on the control element.\r\n *\r\n * @param {Number} dragSensitivity The dragging sensitivity factor.\r\n */\r\n setDragSensitivity(dragSensitivity) {\r\n this._dragSensitivity = dragSensitivity || 1;\r\n }\r\n\r\n /**\r\n * Gets the factor that governs how fast a SectionPlane moves as we drag on the control element.\r\n *\r\n * @return {Number} The dragging sensitivity factor.\r\n */\r\n getDragSensitivity() {\r\n return this._dragSensitivity;\r\n }\r\n\r\n /**\r\n * Sets if the overview canvas is visible.\r\n *\r\n * @param {Boolean} visible Whether or not the overview canvas is visible.\r\n */\r\n setOverviewVisible(visible) {\r\n if (this._overview) {\r\n this._overview.setVisible(visible);\r\n }\r\n }\r\n\r\n /**\r\n * Gets if the overview canvas is visible.\r\n *\r\n * @return {Boolean} True when the overview canvas is visible.\r\n */\r\n getOverviewVisible() {\r\n if (this._overview) {\r\n return this._overview.getVisible();\r\n }\r\n }\r\n\r\n /**\r\n * Returns a map of the {@link SectionPlane}s created by this FaceAlignedSectionPlanesPlugin.\r\n *\r\n * @returns {{String:SectionPlane}} A map containing the {@link SectionPlane}s, each mapped to its {@link SectionPlane#id}.\r\n */\r\n get sectionPlanes() {\r\n return this._sectionPlanes;\r\n }\r\n\r\n /**\r\n * Creates a {@link SectionPlane}.\r\n *\r\n * The {@link SectionPlane} will be registered by {@link SectionPlane#id} in {@link FaceAlignedSectionPlanesPlugin#sectionPlanes}.\r\n *\r\n * @param {Object} params {@link SectionPlane} configuration.\r\n * @param {String} [params.id] Unique ID to assign to the {@link SectionPlane}. Must be unique among all components in the {@link Viewer}'s {@link Scene}. Auto-generated when omitted.\r\n * @param {Number[]} [params.pos=[0,0,0]] World-space position of the {@link SectionPlane}.\r\n * @param {Number[]} [params.dir=[0,0,-1]] World-space vector indicating the orientation of the {@link SectionPlane}.\r\n * @param {Boolean} [params.active=true] Whether the {@link SectionPlane} is initially active. Only clips while this is true.\r\n * @returns {SectionPlane} The new {@link SectionPlane}.\r\n */\r\n createSectionPlane(params = {}) {\r\n\r\n if (params.id !== undefined && params.id !== null && this.viewer.scene.components[params.id]) {\r\n this.error(\"Viewer component with this ID already exists: \" + params.id);\r\n delete params.id;\r\n }\r\n\r\n // Note that SectionPlane constructor fires \"sectionPlaneCreated\" on the Scene,\r\n // which FaceAlignedSectionPlanesPlugin handles and calls #_sectionPlaneCreated to create gizmo and add to overview canvas.\r\n\r\n const sectionPlane = new _viewer_scene_sectionPlane_SectionPlane_js__WEBPACK_IMPORTED_MODULE_2__.SectionPlane(this.viewer.scene, {\r\n id: params.id,\r\n pos: params.pos,\r\n dir: params.dir,\r\n active: true || 0\r\n });\r\n return sectionPlane;\r\n }\r\n\r\n _sectionPlaneCreated(sectionPlane) {\r\n const control = (this._freeControls.length > 0) ? this._freeControls.pop() : new _FaceAlignedSectionPlanesControl_js__WEBPACK_IMPORTED_MODULE_3__.FaceAlignedSectionPlanesControl(this);\r\n control._setSectionPlane(sectionPlane);\r\n control.setVisible(false);\r\n this._controls[sectionPlane.id] = control;\r\n if (this._overview) {\r\n this._overview.addSectionPlane(sectionPlane);\r\n }\r\n sectionPlane.once(\"destroyed\", () => {\r\n this._sectionPlaneDestroyed(sectionPlane);\r\n });\r\n }\r\n\r\n /**\r\n * Inverts the direction of {@link SectionPlane#dir} on every existing SectionPlane.\r\n *\r\n * Inverts all SectionPlanes, including those that were not created with FaceAlignedSectionPlanesPlugin.\r\n */\r\n flipSectionPlanes() {\r\n const sectionPlanes = this.viewer.scene.sectionPlanes;\r\n for (let id in sectionPlanes) {\r\n const sectionPlane = sectionPlanes[id];\r\n sectionPlane.flipDir();\r\n }\r\n }\r\n\r\n /**\r\n * Shows the 3D editing gizmo for a {@link SectionPlane}.\r\n *\r\n * @param {String} id ID of the {@link SectionPlane}.\r\n */\r\n showControl(id) {\r\n const control = this._controls[id];\r\n if (!control) {\r\n this.error(\"Control not found: \" + id);\r\n return;\r\n }\r\n this.hideControl();\r\n control.setVisible(true);\r\n if (this._overview) {\r\n this._overview.setPlaneSelected(id, true);\r\n }\r\n this._shownControlId = id;\r\n }\r\n\r\n /**\r\n * Gets the ID of the {@link SectionPlane} that the 3D editing gizmo is shown for.\r\n *\r\n * Returns ````null```` when the editing gizmo is not shown.\r\n *\r\n * @returns {String} ID of the the {@link SectionPlane} that the 3D editing gizmo is shown for, if shown, else ````null````.\r\n */\r\n getShownControl() {\r\n return this._shownControlId;\r\n }\r\n\r\n /**\r\n * Hides the 3D {@link SectionPlane} editing gizmo if shown.\r\n */\r\n hideControl() {\r\n for (let id in this._controls) {\r\n if (this._controls.hasOwnProperty(id)) {\r\n this._controls[id].setVisible(false);\r\n if (this._overview) {\r\n this._overview.setPlaneSelected(id, false);\r\n }\r\n }\r\n }\r\n this._shownControlId = null;\r\n }\r\n\r\n /**\r\n * Destroys a {@link SectionPlane} created by this FaceAlignedSectionPlanesPlugin.\r\n *\r\n * @param {String} id ID of the {@link SectionPlane}.\r\n */\r\n destroySectionPlane(id) {\r\n let sectionPlane = this.viewer.scene.sectionPlanes[id];\r\n if (!sectionPlane) {\r\n this.error(\"SectionPlane not found: \" + id);\r\n return;\r\n }\r\n this._sectionPlaneDestroyed(sectionPlane);\r\n sectionPlane.destroy();\r\n\r\n if (id === this._shownControlId) {\r\n this._shownControlId = null;\r\n }\r\n }\r\n\r\n _sectionPlaneDestroyed(sectionPlane) {\r\n if (this._overview) {\r\n this._overview.removeSectionPlane(sectionPlane);\r\n }\r\n const control = this._controls[sectionPlane.id];\r\n if (!control) {\r\n return;\r\n }\r\n control.setVisible(false);\r\n control._setSectionPlane(null);\r\n delete this._controls[sectionPlane.id];\r\n this._freeControls.push(control);\r\n }\r\n\r\n /**\r\n * Destroys all {@link SectionPlane}s created by this FaceAlignedSectionPlanesPlugin.\r\n */\r\n clear() {\r\n const ids = Object.keys(this._sectionPlanes);\r\n for (let i = 0, len = ids.length; i < len; i++) {\r\n this.destroySectionPlane(ids[i]);\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n send(name, value) {\r\n switch (name) {\r\n\r\n case \"snapshotStarting\": // Viewer#getSnapshot() about to take snapshot - hide controls\r\n for (let id in this._controls) {\r\n if (this._controls.hasOwnProperty(id)) {\r\n this._controls[id].setCulled(true);\r\n }\r\n }\r\n break;\r\n\r\n case \"snapshotFinished\": // Viewer#getSnapshot() finished taking snapshot - show controls again\r\n for (let id in this._controls) {\r\n if (this._controls.hasOwnProperty(id)) {\r\n this._controls[id].setCulled(false);\r\n }\r\n }\r\n break;\r\n\r\n case \"clearSectionPlanes\":\r\n this.clear();\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Destroys this FaceAlignedSectionPlanesPlugin.\r\n *\r\n * Also destroys each {@link SectionPlane} created by this FaceAlignedSectionPlanesPlugin.\r\n *\r\n * Does not destroy the canvas the FaceAlignedSectionPlanesPlugin was configured with.\r\n */\r\n destroy() {\r\n this.clear();\r\n if (this._overview) {\r\n this._overview.destroy();\r\n }\r\n this._destroyFreeControls();\r\n super.destroy();\r\n }\r\n\r\n _destroyFreeControls() {\r\n let control = this._freeControls.pop();\r\n while (control) {\r\n control._destroy();\r\n control = this._freeControls.pop();\r\n }\r\n this.viewer.scene.off(this._onSceneSectionPlaneCreated);\r\n }\r\n}\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/FaceAlignedSectionPlanesPlugin/FaceAlignedSectionPlanesPlugin.js?");
1647
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ FaceAlignedSectionPlanesPlugin: () => (/* binding */ FaceAlignedSectionPlanesPlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_sectionPlane_SectionPlane_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/sectionPlane/SectionPlane.js */ \"./src/viewer/scene/sectionPlane/SectionPlane.js\");\n/* harmony import */ var _FaceAlignedSectionPlanesControl_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./FaceAlignedSectionPlanesControl.js */ \"./src/plugins/FaceAlignedSectionPlanesPlugin/FaceAlignedSectionPlanesControl.js\");\n/* harmony import */ var _Overview_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Overview.js */ \"./src/plugins/FaceAlignedSectionPlanesPlugin/Overview.js\");\n\n\n\n\n\n\nconst tempAABB = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.AABB3();\nconst tempVec3 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\n/**\n * FaceAlignedSectionPlanesPlugin is a {@link Viewer} plugin that creates and edits face-aligned {@link SectionPlane}s.\n *\n * [<img src=\"https://xeokit.github.io/xeokit-sdk/assets/images/FaceAlignedSectionPlanesPlugin.gif\">](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_FaceAlignedSectionPlanesPlugin)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_FaceAlignedSectionPlanesPlugin)]\n *\n * ## Overview\n *\n * * Use the FaceAlignedSectionPlanesPlugin to\n * create and edit {@link SectionPlane}s to slice portions off your models and reveal internal structures.\n *\n * * As shown in the screen capture above, FaceAlignedSectionPlanesPlugin shows an overview of all your SectionPlanes (on the right, in\n * this example).\n * * Click a plane in the overview to activate a 3D control with which you can interactively\n * reposition its SectionPlane in the main canvas.\n * * Configure the plugin with an HTML element that the user can click-and-drag on to reposition the SectionPlane for which the control is active.\n * * Use {@link BCFViewpointsPlugin} to save and load SectionPlanes in BCF viewpoints.\n *\n * ## Usage\n *\n * In the example below, we'll use a {@link GLTFLoaderPlugin} to load a model, and a FaceAlignedSectionPlanesPlugin\n * to slice it open with two {@link SectionPlane}s. We'll show the overview in the bottom right of the Viewer\n * canvas. Finally, we'll programmatically activate the 3D editing control, so that we can use it to interactively\n * reposition our second SectionPlane.\n *\n * ````JavaScript\n * import {Viewer, GLTFLoaderPlugin, FaceAlignedSectionPlanesPlugin} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer and arrange its Camera\n *\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [-5.02, 2.22, 15.09];\n * viewer.camera.look = [4.97, 2.79, 9.89];\n * viewer.camera.up = [-0.05, 0.99, 0.02];\n *\n * // Add a GLTFLoaderPlugin\n *\n * const gltfLoader = new GLTFLoaderPlugin(viewer);\n *\n * // Add a FaceAlignedSectionPlanesPlugin, with overview visible\n *\n * const faceAlignedSectionPlanes = new FaceAlignedSectionPlanesPlugin(viewer, {\n * overviewCanvasID: \"myOverviewCanvas\",\n * overviewVisible: true,\n * controlElementId: \"myControlElement\", // ID of element to capture drag events that move the SectionPlane\n * dragSensitivity: 1 // Sensitivity factor that governs the rate at which dragging moves the SectionPlane\n * });\n *\n * // Load a model\n *\n * const model = gltfLoader.load({\n * id: \"myModel\",\n * src: \"./models/gltf/schependomlaan/scene.glb\"\n * });\n *\n * // Create a couple of section planes\n * // These will be shown in the overview\n *\n * faceAlignedSectionPlanes.createSectionPlane({\n * id: \"mySectionPlane\",\n * pos: [1.04, 1.95, 9.74],\n * dir: [1.0, 0.0, 0.0]\n * });\n *\n * faceAlignedSectionPlanes.createSectionPlane({\n * id: \"mySectionPlane2\",\n * pos: [2.30, 4.46, 14.93],\n * dir: [0.0, -0.09, -0.79]\n * });\n *\n * // Show the FaceAlignedSectionPlanesPlugin's 3D editing gizmo,\n * // to interactively reposition one of our SectionPlanes\n *\n * faceAlignedSectionPlanes.showControl(\"mySectionPlane2\");\n *\n * const mySectionPlane2 = faceAlignedSectionPlanes.sectionPlanes[\"mySectionPlane2\"];\n *\n * // Programmatically reposition one of our SectionPlanes\n * // This also updates its position as shown in the overview gizmo\n *\n * mySectionPlane2.pos = [11.0, 6.0, -12];\n * mySectionPlane2.dir = [0.4, 0.0, 0.5];\n * ````\n */\nclass FaceAlignedSectionPlanesPlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_1__.Plugin {\n\n /**\n * @constructor\n * @param {Viewer} viewer The Viewer.\n * @param {Object} cfg Plugin configuration.\n * @param {String} [cfg.id=\"SectionPlanes\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n * @param {String} [cfg.overviewCanvasId] ID of a canvas element to display the overview.\n * @param {String} [cfg.overviewVisible=true] Initial visibility of the overview canvas.\n * @param {String} cfg.controlElementId ID of an HTML element that catches drag events to move the active SectionPlane.\n * @param {Number} [cfg.dragSensitivity=1] Sensitivity factor that governs the rate at which dragging on the control element moves SectionPlane.\n */\n constructor(viewer, cfg = {}) {\n\n super(\"FaceAlignedSectionPlanesPlugin\", viewer);\n\n this._freeControls = [];\n this._sectionPlanes = viewer.scene.sectionPlanes;\n this._controls = {};\n this._shownControlId = null;\n this._dragSensitivity = cfg.dragSensitivity || 1;\n\n if (cfg.overviewCanvasId !== null && cfg.overviewCanvasId !== undefined) {\n\n const overviewCanvas = document.getElementById(cfg.overviewCanvasId);\n\n if (!overviewCanvas) {\n this.warn(\"Can't find overview canvas: '\" + cfg.overviewCanvasId + \"' - will create plugin without overview\");\n\n } else {\n\n this._overview = new _Overview_js__WEBPACK_IMPORTED_MODULE_4__.Overview(this, {\n overviewCanvas: overviewCanvas,\n visible: cfg.overviewVisible,\n\n onHoverEnterPlane: ((id) => {\n this._overview.setPlaneHighlighted(id, true);\n }),\n\n onHoverLeavePlane: ((id) => {\n this._overview.setPlaneHighlighted(id, false);\n }),\n\n onClickedPlane: ((id) => {\n if (this.getShownControl() === id) {\n this.hideControl();\n return;\n }\n this.showControl(id);\n const sectionPlane = this.sectionPlanes[id];\n const sectionPlanePos = sectionPlane.pos;\n tempAABB.set(this.viewer.scene.aabb);\n _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(tempAABB, tempVec3);\n tempAABB[0] += sectionPlanePos[0] - tempVec3[0];\n tempAABB[1] += sectionPlanePos[1] - tempVec3[1];\n tempAABB[2] += sectionPlanePos[2] - tempVec3[2];\n tempAABB[3] += sectionPlanePos[0] - tempVec3[0];\n tempAABB[4] += sectionPlanePos[1] - tempVec3[1];\n tempAABB[5] += sectionPlanePos[2] - tempVec3[2];\n this.viewer.cameraFlight.flyTo({\n aabb: tempAABB,\n fitFOV: 65\n });\n }),\n\n onClickedNothing: (() => {\n this.hideControl();\n })\n });\n }\n }\n\n if (cfg.controlElementId === null || cfg.controlElementId === undefined) {\n this.error(\"Parameter expected: controlElementId\");\n } else {\n this._controlElement = document.getElementById(cfg.controlElementId);\n if (!this._controlElement) {\n this.warn(\"Can't find control element: '\" + cfg.controlElementId + \"' - will create plugin without control element\");\n\n }\n }\n\n this._onSceneSectionPlaneCreated = viewer.scene.on(\"sectionPlaneCreated\", (sectionPlane) => {\n\n // SectionPlane created, either via FaceAlignedSectionPlanesPlugin#createSectionPlane(), or by directly\n // instantiating a SectionPlane independently of FaceAlignedSectionPlanesPlugin, which can be done\n // by BCFViewpointsPlugin#loadViewpoint().\n\n this._sectionPlaneCreated(sectionPlane);\n });\n }\n\n /**\n * Sets the factor that governs how fast a SectionPlane moves as we drag on the control element.\n *\n * @param {Number} dragSensitivity The dragging sensitivity factor.\n */\n setDragSensitivity(dragSensitivity) {\n this._dragSensitivity = dragSensitivity || 1;\n }\n\n /**\n * Gets the factor that governs how fast a SectionPlane moves as we drag on the control element.\n *\n * @return {Number} The dragging sensitivity factor.\n */\n getDragSensitivity() {\n return this._dragSensitivity;\n }\n\n /**\n * Sets if the overview canvas is visible.\n *\n * @param {Boolean} visible Whether or not the overview canvas is visible.\n */\n setOverviewVisible(visible) {\n if (this._overview) {\n this._overview.setVisible(visible);\n }\n }\n\n /**\n * Gets if the overview canvas is visible.\n *\n * @return {Boolean} True when the overview canvas is visible.\n */\n getOverviewVisible() {\n if (this._overview) {\n return this._overview.getVisible();\n }\n }\n\n /**\n * Returns a map of the {@link SectionPlane}s created by this FaceAlignedSectionPlanesPlugin.\n *\n * @returns {{String:SectionPlane}} A map containing the {@link SectionPlane}s, each mapped to its {@link SectionPlane#id}.\n */\n get sectionPlanes() {\n return this._sectionPlanes;\n }\n\n /**\n * Creates a {@link SectionPlane}.\n *\n * The {@link SectionPlane} will be registered by {@link SectionPlane#id} in {@link FaceAlignedSectionPlanesPlugin#sectionPlanes}.\n *\n * @param {Object} params {@link SectionPlane} configuration.\n * @param {String} [params.id] Unique ID to assign to the {@link SectionPlane}. Must be unique among all components in the {@link Viewer}'s {@link Scene}. Auto-generated when omitted.\n * @param {Number[]} [params.pos=[0,0,0]] World-space position of the {@link SectionPlane}.\n * @param {Number[]} [params.dir=[0,0,-1]] World-space vector indicating the orientation of the {@link SectionPlane}.\n * @param {Boolean} [params.active=true] Whether the {@link SectionPlane} is initially active. Only clips while this is true.\n * @returns {SectionPlane} The new {@link SectionPlane}.\n */\n createSectionPlane(params = {}) {\n\n if (params.id !== undefined && params.id !== null && this.viewer.scene.components[params.id]) {\n this.error(\"Viewer component with this ID already exists: \" + params.id);\n delete params.id;\n }\n\n // Note that SectionPlane constructor fires \"sectionPlaneCreated\" on the Scene,\n // which FaceAlignedSectionPlanesPlugin handles and calls #_sectionPlaneCreated to create gizmo and add to overview canvas.\n\n const sectionPlane = new _viewer_scene_sectionPlane_SectionPlane_js__WEBPACK_IMPORTED_MODULE_2__.SectionPlane(this.viewer.scene, {\n id: params.id,\n pos: params.pos,\n dir: params.dir,\n active: true || 0\n });\n return sectionPlane;\n }\n\n _sectionPlaneCreated(sectionPlane) {\n const control = (this._freeControls.length > 0) ? this._freeControls.pop() : new _FaceAlignedSectionPlanesControl_js__WEBPACK_IMPORTED_MODULE_3__.FaceAlignedSectionPlanesControl(this);\n control._setSectionPlane(sectionPlane);\n control.setVisible(false);\n this._controls[sectionPlane.id] = control;\n if (this._overview) {\n this._overview.addSectionPlane(sectionPlane);\n }\n sectionPlane.once(\"destroyed\", () => {\n this._sectionPlaneDestroyed(sectionPlane);\n });\n }\n\n /**\n * Inverts the direction of {@link SectionPlane#dir} on every existing SectionPlane.\n *\n * Inverts all SectionPlanes, including those that were not created with FaceAlignedSectionPlanesPlugin.\n */\n flipSectionPlanes() {\n const sectionPlanes = this.viewer.scene.sectionPlanes;\n for (let id in sectionPlanes) {\n const sectionPlane = sectionPlanes[id];\n sectionPlane.flipDir();\n }\n }\n\n /**\n * Shows the 3D editing gizmo for a {@link SectionPlane}.\n *\n * @param {String} id ID of the {@link SectionPlane}.\n */\n showControl(id) {\n const control = this._controls[id];\n if (!control) {\n this.error(\"Control not found: \" + id);\n return;\n }\n this.hideControl();\n control.setVisible(true);\n if (this._overview) {\n this._overview.setPlaneSelected(id, true);\n }\n this._shownControlId = id;\n }\n\n /**\n * Gets the ID of the {@link SectionPlane} that the 3D editing gizmo is shown for.\n *\n * Returns ````null```` when the editing gizmo is not shown.\n *\n * @returns {String} ID of the the {@link SectionPlane} that the 3D editing gizmo is shown for, if shown, else ````null````.\n */\n getShownControl() {\n return this._shownControlId;\n }\n\n /**\n * Hides the 3D {@link SectionPlane} editing gizmo if shown.\n */\n hideControl() {\n for (let id in this._controls) {\n if (this._controls.hasOwnProperty(id)) {\n this._controls[id].setVisible(false);\n if (this._overview) {\n this._overview.setPlaneSelected(id, false);\n }\n }\n }\n this._shownControlId = null;\n }\n\n /**\n * Destroys a {@link SectionPlane} created by this FaceAlignedSectionPlanesPlugin.\n *\n * @param {String} id ID of the {@link SectionPlane}.\n */\n destroySectionPlane(id) {\n let sectionPlane = this.viewer.scene.sectionPlanes[id];\n if (!sectionPlane) {\n this.error(\"SectionPlane not found: \" + id);\n return;\n }\n this._sectionPlaneDestroyed(sectionPlane);\n sectionPlane.destroy();\n\n if (id === this._shownControlId) {\n this._shownControlId = null;\n }\n }\n\n _sectionPlaneDestroyed(sectionPlane) {\n if (this._overview) {\n this._overview.removeSectionPlane(sectionPlane);\n }\n const control = this._controls[sectionPlane.id];\n if (!control) {\n return;\n }\n control.setVisible(false);\n control._setSectionPlane(null);\n delete this._controls[sectionPlane.id];\n this._freeControls.push(control);\n }\n\n /**\n * Destroys all {@link SectionPlane}s created by this FaceAlignedSectionPlanesPlugin.\n */\n clear() {\n const ids = Object.keys(this._sectionPlanes);\n for (let i = 0, len = ids.length; i < len; i++) {\n this.destroySectionPlane(ids[i]);\n }\n }\n\n /**\n * @private\n */\n send(name, value) {\n switch (name) {\n\n case \"snapshotStarting\": // Viewer#getSnapshot() about to take snapshot - hide controls\n for (let id in this._controls) {\n if (this._controls.hasOwnProperty(id)) {\n this._controls[id].setCulled(true);\n }\n }\n break;\n\n case \"snapshotFinished\": // Viewer#getSnapshot() finished taking snapshot - show controls again\n for (let id in this._controls) {\n if (this._controls.hasOwnProperty(id)) {\n this._controls[id].setCulled(false);\n }\n }\n break;\n\n case \"clearSectionPlanes\":\n this.clear();\n break;\n }\n }\n\n /**\n * Destroys this FaceAlignedSectionPlanesPlugin.\n *\n * Also destroys each {@link SectionPlane} created by this FaceAlignedSectionPlanesPlugin.\n *\n * Does not destroy the canvas the FaceAlignedSectionPlanesPlugin was configured with.\n */\n destroy() {\n this.clear();\n if (this._overview) {\n this._overview.destroy();\n }\n this._destroyFreeControls();\n super.destroy();\n }\n\n _destroyFreeControls() {\n let control = this._freeControls.pop();\n while (control) {\n control._destroy();\n control = this._freeControls.pop();\n }\n this.viewer.scene.off(this._onSceneSectionPlaneCreated);\n }\n}\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/FaceAlignedSectionPlanesPlugin/FaceAlignedSectionPlanesPlugin.js?");
1648
1648
 
1649
1649
  /***/ }),
1650
1650
 
@@ -1794,7 +1794,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1794
1794
  \****************************************************/
1795
1795
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1796
1796
 
1797
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ NavCubePlugin: () => (/* binding */ NavCubePlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_scene_Scene_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/scene/Scene.js */ \"./src/viewer/scene/scene/Scene.js\");\n/* harmony import */ var _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./../../viewer/scene/lights/DirLight.js */ \"./src/viewer/scene/lights/DirLight.js\");\n/* harmony import */ var _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./../../viewer/scene/mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../viewer/scene/geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../viewer/scene/materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _viewer_scene_materials_Texture_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../viewer/scene/materials/Texture.js */ \"./src/viewer/scene/materials/Texture.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildCylinderGeometry.js */ \"./src/viewer/scene/geometry/builders/buildCylinderGeometry.js\");\n/* harmony import */ var _CubeTextureCanvas_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./CubeTextureCanvas.js */ \"./src/plugins/NavCubePlugin/CubeTextureCanvas.js\");\n/* harmony import */ var _viewer_scene_constants_constants_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../viewer/scene/constants/constants.js */ \"./src/viewer/scene/constants/constants.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst tempVec3a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\nconst tempVec3b = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\nconst tempMat4a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\r\n\r\n/**\r\n * {@link Viewer} plugin that lets us look at the entire {@link Scene} from along a chosen axis or diagonal.\r\n *\r\n * [<img src=\"https://user-images.githubusercontent.com/83100/55674490-c93c2e00-58b5-11e9-8a28-eb08876947c0.gif\">](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_NavCubePlugin)\r\n *\r\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_NavCubePlugin)]\r\n *\r\n * ## Overview\r\n *\r\n * * Rotating the NavCube causes the Viewer's {@link Camera} to orbit its current\r\n * point-of-interest. Conversely, orbiting the Camera causes the NavCube to rotate accordingly.\r\n * * The faces of the NavCube are aligned with the Viewer's {@link Scene}'s World-space coordinate axis. Clicking on a face moves\r\n * the Camera to look at the entire Scene along the corresponding axis. Clicking on an edge or a corner looks at\r\n * the entire Scene along a diagonal.\r\n * * The NavCube can be configured to either jump or fly the Camera to each new position. We can configure how tightly the\r\n * NavCube fits the Scene to view, and when flying, we can configure how fast it flies. We can also configure whether the\r\n * NavCube fits all objects to view, or just the currently visible objects. See below for a usage example.\r\n * * Clicking the NavCube also sets {@link CameraControl#pivotPos} to the center of the fitted objects.\r\n *\r\n * ## Usage\r\n *\r\n * In the example below, we'll create a Viewer and add a NavCubePlugin, which will create a NavCube gizmo in the canvas\r\n * with the given ID. Then we'll use the {@link XTCLoaderPlugin} to load a model into the Viewer's Scene. We can then\r\n * use the NavCube to look at the model along each axis or diagonal.\r\n *\r\n * ````JavaScript\r\n * import {Viewer, XTCLoaderPlugin, NavCubePlugin} from \"xeokit-sdk.es.js\";\r\n *\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\"\r\n * });\r\n *\r\n * viewer.camera.eye = [-3.93, 2.85, 27.01];\r\n * viewer.camera.look = [4.40, 3.72, 8.89];\r\n * viewer.camera.up = [-0.01, 0.99, 0.03];\r\n *\r\n * const navCube = new NavCubePlugin(viewer, {\r\n *\r\n * canvasID: \"myNavCubeCanvas\",\r\n *\r\n * visible: true, // Initially visible (default)\r\n *\r\n * cameraFly: true, // Fly camera to each selected axis/diagonal\r\n * cameraFitFOV: 45, // How much field-of-view the scene takes once camera has fitted it to view\r\n * cameraFlyDuration: 0.5,// How long (in seconds) camera takes to fly to each new axis/diagonal\r\n *\r\n * fitVisible: false, // Fit whole scene, including invisible objects (default)\r\n *\r\n * synchProjection: false // Keep NavCube in perspective projection, even when camera switches to ortho (default)\r\n * });\r\n *\r\n * const xtcLoader = new XTCLoaderPlugin(viewer);\r\n *\r\n * const model = xtcLoader.load({\r\n * id: \"myModel\",\r\n * src: \"./models/xtc/Duplex.ifc.xtc\",\r\n * edges: true\r\n * });\r\n * ````\r\n */\r\nclass NavCubePlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__.Plugin {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Viewer} viewer The {@link Viewer}.\r\n\t * @param {Object} cfg NavCubePlugin configuration.\r\n\t * @param {String} [cfg.id=\"NavCube\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\r\n\t * @param {String} [cfg.canvasId] ID of an existing HTML canvas to display the NavCube - either this or canvasElement is mandatory. When both values are given, the element reference is always preferred to the ID.\r\n\t * @param {HTMLCanvasElement} [cfg.canvasElement] Reference of an existing HTML canvas to display the NavCube - either this or canvasId is mandatory. When both values are given, the element reference is always preferred to the ID.\r\n\t * @param {div} [cfg.viewerElement] Reference of an existing div to contain the canvas\r\n\t * @param {Boolean} [cfg.visible=true] Initial visibility.\r\n\t * @param {Boolean} [cfg.shadowVisible=true] Whether the shadow of the cube is visible.\r\n\t * @param {String} [cfg.cameraFly=true] Whether the {@link Camera} flies or jumps to each selected axis or diagonal.\r\n\t * @param {String} [cfg.cameraFitFOV=45] How much of the field-of-view, in degrees, that the 3D scene should fill the {@link Canvas} when the {@link Camera} moves to an axis or diagonal.\r\n\t * @param {String} [cfg.cameraFlyDuration=0.5] When flying the {@link Camera} to each new axis or diagonal, how long, in seconds, that the Camera takes to get there.\r\n\t * @param {String} [cfg.color=\"lightgrey\"] Custom uniform color for the faces of the NavCube.\r\n\t * @param {String} [cfg.frontColor=\"#55FF55\"] Custom color for the front face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.backColor=\"#55FF55\"] Custom color for the back face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.leftColor=\"#FF5555\"] Custom color for the left face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.rightColor=\"#FF5555\"] Custom color for the right face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.topColor=\"#5555FF\"] Custom color for the top face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.bottomColor=\"#5555FF\"] Custom color for the bottom face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.hoverColor=\"rgba(0,0,0,0.4)\"] Custom color for highlighting regions on the NavCube as we hover the pointer over them.\r\n\t * @param {String} [cfg.textColor=\"black\"] Custom text color for labels of the NavCube.\r\n\t * @param {Boolean} [cfg.fitVisible=false] Sets whether the axis, corner and edge-aligned views will fit the\r\n\t * view to the entire {@link Scene} or just to visible object-{@link Entity}s. Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.\r\n\t * @param {Boolean} [cfg.synchProjection=false] Sets whether the NavCube switches between perspective and orthographic projections in synchrony with the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.\r\n\t * @param {Boolean} [cfg.isProjectNorth] sets whether the NavCube switches between true north and project north - using the project north offset angle.\r\n\t * @param {number} [cfg.projectNorthOffsetAngle] sets the NavCube project north offset angle - when the {@link isProjectNorth} is true.\r\n\t */\r\n\tconstructor(viewer, cfg = {}) {\r\n\t\tsuper(\"NavCube\", viewer, cfg);\r\n\r\n\t\tviewer.navCube = this;\r\n\r\n\t\tvar visible = true;\r\n\r\n\t\ttry {\r\n\t\t\tthis._navCubeScene = new _viewer_scene_scene_Scene_js__WEBPACK_IMPORTED_MODULE_2__.Scene(viewer, {\r\n\t\t\t\tcanvasId: cfg.canvasId,\r\n\t\t\t\tcanvasElement: cfg.canvasElement,\r\n\t\t\t\ttransparent: true,\r\n\t\t\t\tspinnerElementId: \"navcube_spinner\"\r\n\t\t\t});\r\n\r\n\t\t\tthis._navCubeCanvas = this._navCubeScene.canvas.canvas;\r\n\r\n\t\t\tthis._navCubeScene.input.keyboardEnabled = false; // Don't want keyboard input in the NavCube\r\n\t\t} catch (error) {\r\n\t\t\tthis.error(error);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst navCubeScene = this._navCubeScene;\r\n\r\n\t\tnavCubeScene.clearLights();\r\n\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_3__.DirLight(navCubeScene, { dir: [0.4, -0.4, 0.8], color: [0.8, 1.0, 1.0], intensity: 1.0, space: \"view\" });\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_3__.DirLight(navCubeScene, { dir: [-0.8, -0.3, -0.4], color: [0.8, 0.8, 0.8], intensity: 1.0, space: \"view\" });\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_3__.DirLight(navCubeScene, { dir: [0.8, -0.6, -0.8], color: [1.0, 1.0, 1.0], intensity: 1.0, space: \"view\" });\r\n\r\n\t\tthis._navCubeCamera = navCubeScene.camera;\r\n\t\tthis._navCubeCamera.ortho.scale = 7.0;\r\n\t\tthis._navCubeCamera.ortho.near = 0.1;\r\n\t\tthis._navCubeCamera.ortho.far = 2000;\r\n\r\n\t\tnavCubeScene.edgeMaterial.edgeColor = [0.2, 0.2, 0.2];\r\n\t\tnavCubeScene.edgeMaterial.edgeAlpha = 0.6;\r\n\r\n\t\tthis._zUp = Boolean(viewer.camera.zUp);\r\n\r\n\t\tvar self = this;\r\n\r\n\t\tthis.setIsProjectNorth(cfg.isProjectNorth);\r\n\t\tthis.setProjectNorthOffsetAngle(cfg.projectNorthOffsetAngle);\r\n\r\n\t\tconst rotateTrueNorth = (this.rotateTrueNorth = (function () {\r\n\t\t\tconst trueNorthMatrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\r\n\t\t\treturn function (dir, vec, dest) {\r\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.identityMat4(trueNorthMatrix);\r\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.rotationMat4v(dir * self._projectNorthOffsetAngle * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.DEGTORAD, [0, 1, 0], trueNorthMatrix);\r\n\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec3(trueNorthMatrix, vec, dest);\r\n\t\t\t};\r\n\t\t})());\r\n\r\n\t\tthis._synchCamera = (function () {\r\n\t\t\tvar matrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.rotationMat4c(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.DEGTORAD, 1, 0, 0);\r\n\t\t\tvar eyeLookVec = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\t\t\tvar eyeLookVecCube = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\t\t\tvar upCube = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\t\t\treturn function () {\r\n\t\t\t\tvar eye = viewer.camera.eye;\r\n\t\t\t\tvar look = viewer.camera.look;\r\n\t\t\t\tvar up = viewer.camera.up;\r\n\t\t\t\teyeLookVec = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulVec3Scalar(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.subVec3(eye, look, eyeLookVec)), 5);\r\n\r\n\t\t\t\tif (self._isProjectNorth && self._projectNorthOffsetAngle) {\r\n\t\t\t\t\teyeLookVec = rotateTrueNorth(-1, eyeLookVec, tempVec3a);\r\n\t\t\t\t\tup = rotateTrueNorth(-1, up, tempVec3b);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (self._zUp) {\r\n\t\t\t\t\t// +Z up\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec3(matrix, eyeLookVec, eyeLookVecCube);\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec3(matrix, up, upCube);\r\n\t\t\t\t\tself._navCubeCamera.look = [0, 0, 0];\r\n\t\t\t\t\tself._navCubeCamera.eye = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec3(matrix, eyeLookVec, eyeLookVecCube);\r\n\t\t\t\t\tself._navCubeCamera.up = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformPoint3(matrix, up, upCube);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// +Y up\r\n\t\t\t\t\tself._navCubeCamera.look = [0, 0, 0];\r\n\t\t\t\t\tself._navCubeCamera.eye = eyeLookVec;\r\n\t\t\t\t\tself._navCubeCamera.up = up;\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t})();\r\n\r\n\t\tthis._cubeTextureCanvas = new _CubeTextureCanvas_js__WEBPACK_IMPORTED_MODULE_9__.CubeTextureCanvas(viewer, navCubeScene, cfg);\r\n\r\n\t\tthis._cubeSampler = new _viewer_scene_materials_Texture_js__WEBPACK_IMPORTED_MODULE_7__.Texture(navCubeScene, {\r\n\t\t\timage: this._cubeTextureCanvas.getImage(),\r\n\t\t\tflipY: true,\r\n\t\t\twrapS: _viewer_scene_constants_constants_js__WEBPACK_IMPORTED_MODULE_10__.ClampToEdgeWrapping,\r\n\t\t\twrapT: _viewer_scene_constants_constants_js__WEBPACK_IMPORTED_MODULE_10__.ClampToEdgeWrapping\r\n\t\t});\r\n\r\n\t\tthis._cubeMesh = new _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_4__.Mesh(navCubeScene, {\r\n\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_5__.ReadableGeometry(navCubeScene, {\r\n\t\t\t\tprimitive: \"triangles\",\r\n\t\t\t\tnormals: [\r\n\t\t\t\t\t0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,\r\n\t\t\t\t\t-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1,\r\n\t\t\t\t\t0, 0, -1\r\n\t\t\t\t],\r\n\t\t\t\tpositions: [\r\n\t\t\t\t\t1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1,\r\n\t\t\t\t\t-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1,\r\n\t\t\t\t\t-1, -1, -1, -1, 1, -1, 1, 1, -1\r\n\t\t\t\t],\r\n\t\t\t\tuv: [\r\n\t\t\t\t\t0.5, 0.6666, 0.25, 0.6666, 0.25, 0.3333, 0.5, 0.3333, 0.5, 0.6666, 0.5, 0.3333, 0.75, 0.3333, 0.75, 0.6666,\r\n\t\t\t\t\t0.5, 0.6666, 0.5, 1, 0.25, 1, 0.25, 0.6666, 0.25, 0.6666, 0.0, 0.6666, 0.0, 0.3333, 0.25, 0.3333, 0.25, 0,\r\n\t\t\t\t\t0.5, 0, 0.5, 0.3333, 0.25, 0.3333, 0.75, 0.3333, 1.0, 0.3333, 1.0, 0.6666, 0.75, 0.6666\r\n\t\t\t\t],\r\n\t\t\t\tindices: [\r\n\t\t\t\t\t0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20,\r\n\t\t\t\t\t21, 22, 20, 22, 23\r\n\t\t\t\t]\r\n\t\t\t}),\r\n\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_6__.PhongMaterial(navCubeScene, {\r\n\t\t\t\tdiffuse: [0.4, 0.4, 0.4],\r\n\t\t\t\tspecular: [0.4, 0.4, 0.4],\r\n\t\t\t\temissive: [0.6, 0.6, 0.6],\r\n\t\t\t\tdiffuseMap: this._cubeSampler,\r\n\t\t\t\temissiveMap: this._cubeSampler\r\n\t\t\t}),\r\n\t\t\tvisible: !!visible,\r\n\t\t\tedges: true\r\n\t\t});\r\n\r\n\t\tthis._shadow =\r\n\t\t\tcfg.shadowVisible === false\r\n\t\t\t\t? null\r\n\t\t\t\t: new _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_4__.Mesh(navCubeScene, {\r\n\t\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_5__.ReadableGeometry(\r\n\t\t\t\t\t\t\tnavCubeScene,\r\n\t\t\t\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_8__.buildCylinderGeometry)({\r\n\t\t\t\t\t\t\t\tcenter: [0, 0, 0],\r\n\t\t\t\t\t\t\t\tradiusTop: 0.001,\r\n\t\t\t\t\t\t\t\tradiusBottom: 1.4,\r\n\t\t\t\t\t\t\t\theight: 0.01,\r\n\t\t\t\t\t\t\t\tradialSegments: 20,\r\n\t\t\t\t\t\t\t\theightSegments: 1,\r\n\t\t\t\t\t\t\t\topenEnded: true\r\n\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_6__.PhongMaterial(navCubeScene, {\r\n\t\t\t\t\t\t\tdiffuse: [0.0, 0.0, 0.0],\r\n\t\t\t\t\t\t\tspecular: [0, 0, 0],\r\n\t\t\t\t\t\t\temissive: [0.0, 0.0, 0.0],\r\n\t\t\t\t\t\t\talpha: 0.5\r\n\t\t\t\t\t\t}),\r\n\t\t\t\t\t\tposition: [0, -1.5, 0],\r\n\t\t\t\t\t\tvisible: !!visible,\r\n\t\t\t\t\t\tpickable: false,\r\n\t\t\t\t\t\tbackfaces: false\r\n\t\t\t\t });\r\n\r\n\t\tthis._onCameraMatrix = viewer.camera.on(\"matrix\", this._synchCamera);\r\n\t\tthis._onCameraWorldAxis = viewer.camera.on(\"worldAxis\", () => {\r\n\t\t\tif (viewer.camera.zUp) {\r\n\t\t\t\tthis._zUp = true;\r\n\t\t\t\tthis._cubeTextureCanvas.setZUp();\r\n\t\t\t\tthis._repaint();\r\n\t\t\t\tthis._synchCamera();\r\n\t\t\t} else if (viewer.camera.yUp) {\r\n\t\t\t\tthis._zUp = false;\r\n\t\t\t\tthis._cubeTextureCanvas.setYUp();\r\n\t\t\t\tthis._repaint();\r\n\t\t\t\tthis._synchCamera();\r\n\t\t\t}\r\n\t\t});\r\n\t\tthis._onCameraFOV = viewer.camera.perspective.on(\"fov\", (fov) => {\r\n\t\t\tif (this._synchProjection) {\r\n\t\t\t\tthis._navCubeCamera.perspective.fov = fov;\r\n\t\t\t}\r\n\t\t});\r\n\t\tthis._onCameraProjection = viewer.camera.on(\"projection\", (projection) => {\r\n\t\t\tif (this._synchProjection) {\r\n\t\t\t\tthis._navCubeCamera.projection =\r\n\t\t\t\t\tprojection === \"ortho\" || projection === \"perspective\" ? projection : \"perspective\";\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tvar lastAreaId = -1;\r\n\r\n\t\tfunction actionMove(posX, posY) {\r\n\t\t\tvar yawInc = (posX - lastX) * -sensitivity;\r\n\t\t\tvar pitchInc = (posY - lastY) * -sensitivity;\r\n\t\t\tyaw -= yawInc;\r\n\t\t\tpitch -= pitchInc;\r\n\t\t\tif (minPitch !== undefined && pitch < minPitch) {\r\n\t\t\t\tpitch = minPitch;\r\n\t\t\t}\r\n\t\t\tif (maxPitch !== undefined && pitch > maxPitch) {\r\n\t\t\t\tpitch = maxPitch;\r\n\t\t\t}\r\n\t\t\tviewer.camera.orbitYaw(yawInc);\r\n\t\t\tviewer.camera.orbitPitch(-pitchInc);\r\n\t\t\tlastX = posX;\r\n\t\t\tlastY = posY;\r\n\t\t}\r\n\r\n\t\tfunction getCoordsWithinElement(event) {\r\n\t\t\tvar coords = [0, 0];\r\n\t\t\tif (!event) {\r\n\t\t\t\tevent = window.event;\r\n\t\t\t\tcoords[0] = event.x;\r\n\t\t\t\tcoords[1] = event.y;\r\n\t\t\t} else {\r\n\t\t\t\tvar element = event.target;\r\n\t\t\t\tvar totalOffsetLeft = 0;\r\n\t\t\t\tvar totalOffsetTop = 0;\r\n\t\t\t\twhile (element.offsetParent) {\r\n\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\r\n\t\t\t\t\ttotalOffsetTop += element.offsetTop;\r\n\t\t\t\t\telement = element.offsetParent;\r\n\t\t\t\t}\r\n\t\t\t\tcoords[0] = event.pageX - totalOffsetLeft;\r\n\t\t\t\tcoords[1] = event.pageY - totalOffsetTop;\r\n\t\t\t}\r\n\t\t\treturn coords;\r\n\t\t}\r\n\r\n\t\t{\r\n\t\t\tvar downX = null;\r\n\t\t\tvar downY = null;\r\n\t\t\tvar down = false;\r\n\t\t\tvar over = false;\r\n\r\n\t\t\tvar yaw = 0;\r\n\t\t\tvar pitch = 0;\r\n\t\t\tvar minPitch = null;\r\n\t\t\tvar maxPitch = null;\r\n\t\t\tvar sensitivity = 0.5;\r\n\r\n\t\t\tvar lastX;\r\n\t\t\tvar lastY;\r\n\r\n\t\t\tself._navCubeCanvas.addEventListener(\r\n\t\t\t\t\"mouseenter\",\r\n\t\t\t\t(self._onMouseEnter = function (e) {\r\n\t\t\t\t\tover = true;\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tself._navCubeCanvas.addEventListener(\r\n\t\t\t\t\"mouseleave\",\r\n\t\t\t\t(self._onMouseLeave = function (e) {\r\n\t\t\t\t\tover = false;\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tself._navCubeCanvas.addEventListener(\r\n\t\t\t\t\"mousedown\",\r\n\t\t\t\t(self._onMouseDown = function (e) {\r\n\t\t\t\t\tif (e.which !== 1) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdownX = e.x;\r\n\t\t\t\t\tdownY = e.y;\r\n\t\t\t\t\tlastX = e.clientX;\r\n\t\t\t\t\tlastY = e.clientY;\r\n\t\t\t\t\tvar canvasPos = getCoordsWithinElement(e);\r\n\t\t\t\t\tvar hit = navCubeScene.pick({\r\n\t\t\t\t\t\tcanvasPos: canvasPos\r\n\t\t\t\t\t});\r\n\t\t\t\t\tif (hit) {\r\n\t\t\t\t\t\tdown = true;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdown = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tdocument.addEventListener(\r\n\t\t\t\t\"mouseup\",\r\n\t\t\t\t(self._onMouseUp = function (e) {\r\n\t\t\t\t\tif (e.which !== 1) {\r\n\t\t\t\t\t\t// Left button\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdown = false;\r\n\t\t\t\t\tif (downX === null) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvar canvasPos = getCoordsWithinElement(e);\r\n\t\t\t\t\tvar hit = navCubeScene.pick({\r\n\t\t\t\t\t\tcanvasPos: canvasPos,\r\n\t\t\t\t\t\tpickSurface: true\r\n\t\t\t\t\t});\r\n\t\t\t\t\tif (hit) {\r\n\t\t\t\t\t\tif (hit.uv) {\r\n\t\t\t\t\t\t\tvar areaId = self._cubeTextureCanvas.getArea(hit.uv);\r\n\t\t\t\t\t\t\tif (areaId >= 0) {\r\n\t\t\t\t\t\t\t\tdocument.body.style.cursor = \"pointer\";\r\n\t\t\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tif (areaId >= 0) {\r\n\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(areaId, true);\r\n\t\t\t\t\t\t\t\t\tlastAreaId = areaId;\r\n\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\tif (e.x < downX - 3 || e.x > downX + 3 || e.y < downY - 3 || e.y > downY + 3) {\r\n\t\t\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tvar dir = self._cubeTextureCanvas.getAreaDir(areaId);\r\n\t\t\t\t\t\t\t\t\tif (dir) {\r\n\t\t\t\t\t\t\t\t\t\tvar up = self._cubeTextureCanvas.getAreaUp(areaId);\r\n\t\t\t\t\t\t\t\t\t\tif (self._isProjectNorth && self._projectNorthOffsetAngle) {\r\n\t\t\t\t\t\t\t\t\t\t\tdir = rotateTrueNorth(+1, dir, tempVec3a);\r\n\t\t\t\t\t\t\t\t\t\t\tup = rotateTrueNorth(+1, up, tempVec3b);\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\tflyTo(dir, up, function () {\r\n\t\t\t\t\t\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\t\tdocument.body.style.cursor = \"pointer\";\r\n\t\t\t\t\t\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\t\tif (areaId >= 0) {\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(areaId, false);\r\n\t\t\t\t\t\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tdocument.addEventListener(\r\n\t\t\t\t\"mousemove\",\r\n\t\t\t\t(self._onMouseMove = function (e) {\r\n\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (e.buttons === 1 && !down) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (down) {\r\n\t\t\t\t\t\tvar posX = e.clientX;\r\n\t\t\t\t\t\tvar posY = e.clientY;\r\n\t\t\t\t\t\tdocument.body.style.cursor = \"move\";\r\n\t\t\t\t\t\tactionMove(posX, posY);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (!over) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvar canvasPos = getCoordsWithinElement(e);\r\n\t\t\t\t\tvar hit = navCubeScene.pick({\r\n\t\t\t\t\t\tcanvasPos: canvasPos,\r\n\t\t\t\t\t\tpickSurface: true\r\n\t\t\t\t\t});\r\n\t\t\t\t\tif (hit) {\r\n\t\t\t\t\t\tif (hit.uv) {\r\n\t\t\t\t\t\t\tdocument.body.style.cursor = \"pointer\";\r\n\t\t\t\t\t\t\tvar areaId = self._cubeTextureCanvas.getArea(hit.uv);\r\n\t\t\t\t\t\t\tif (areaId === lastAreaId) {\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (areaId >= 0) {\r\n\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(areaId, true);\r\n\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\tlastAreaId = areaId;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.body.style.cursor = \"default\";\r\n\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tvar flyTo = (this.flyTo = (function () {\r\n\t\t\t\tvar center = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\t\t\t\treturn function (dir, up, ok) {\r\n\t\t\t\t\tvar aabb = self._fitVisible ? viewer.scene.getAABB(viewer.scene.visibleObjectIds) : viewer.scene.aabb;\r\n\t\t\t\t\tvar diag = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.getAABB3Diag(aabb);\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.getAABB3Center(aabb, center);\r\n\t\t\t\t\tvar dist = Math.abs(diag / Math.tan(self._cameraFitFOV * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.DEGTORAD));\r\n\t\t\t\t\tviewer.cameraControl.pivotPos = center;\r\n\t\t\t\t\tif (self._cameraFly) {\r\n\t\t\t\t\t\tviewer.cameraFlight.flyTo(\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\tlook: center,\r\n\t\t\t\t\t\t\t\teye: [center[0] - dist * dir[0], center[1] - dist * dir[1], center[2] - dist * dir[2]],\r\n\t\t\t\t\t\t\t\tup: up || [0, 1, 0],\r\n\t\t\t\t\t\t\t\torthoScale: diag * 1.1,\r\n\t\t\t\t\t\t\t\tfitFOV: self._cameraFitFOV,\r\n\t\t\t\t\t\t\t\tduration: self._cameraFlyDuration\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tok\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tviewer.cameraFlight.jumpTo(\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\tlook: center,\r\n\t\t\t\t\t\t\t\teye: [center[0] - dist * dir[0], center[1] - dist * dir[1], center[2] - dist * dir[2]],\r\n\t\t\t\t\t\t\t\tup: up || [0, 1, 0],\r\n\t\t\t\t\t\t\t\torthoScale: diag * 1.1,\r\n\t\t\t\t\t\t\t\tfitFOV: self._cameraFitFOV\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tok\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t};\r\n\t\t\t})());\r\n\t\t}\r\n\r\n\t\tthis._onUpdated = viewer.localeService.on(\"updated\", () => {\r\n\t\t\tthis._cubeTextureCanvas.clear();\r\n\t\t\tthis._repaint();\r\n\t\t});\r\n\r\n\t\tthis.setVisible(cfg.visible);\r\n\t\tthis.setCameraFitFOV(cfg.cameraFitFOV);\r\n\t\tthis.setCameraFly(cfg.cameraFly);\r\n\t\tthis.setCameraFlyDuration(cfg.cameraFlyDuration);\r\n\t\tthis.setFitVisible(cfg.fitVisible);\r\n\t\tthis.setSynchProjection(cfg.synchProjection);\r\n\t}\r\n\r\n\tflyByClick(areaId) {\r\n\t\tif (areaId >= 0) {\r\n\t\t\tthis._cubeTextureCanvas.setAreaHighlighted(areaId, true);\r\n\t\t\tthis._repaint();\r\n\t\t\tvar dir = this._cubeTextureCanvas.getAreaDir(areaId);\r\n\t\t\tif (dir) {\r\n\t\t\t\tvar up = this._cubeTextureCanvas.getAreaUp(areaId);\r\n\t\t\t\tif (this._isProjectNorth && this._projectNorthOffsetAngle) {\r\n\t\t\t\t\tdir = this.rotateTrueNorth(+1, dir, tempVec3a);\r\n\t\t\t\t\tup = this.rotateTrueNorth(+1, up, tempVec3b);\r\n\t\t\t\t}\r\n\t\t\t\tthis.flyTo(dir, up, function () {\r\n\t\t\t\t\tdocument.body.style.cursor = \"pointer\";\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tget navCubeScene() {\r\n\t\treturn this._navCubeScene;\r\n\t}\r\n\r\n\tsend(name, value) {\r\n\t\tswitch (name) {\r\n\t\t\tcase \"language\":\r\n\t\t\t\tthis._cubeTextureCanvas.clear();\r\n\t\t\t\tthis._repaint(); // CubeTextureCanvas gets language from Viewer\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\t_repaint() {\r\n\t\tconst image = this._cubeTextureCanvas.getImage();\r\n\t\tthis._cubeMesh.material.diffuseMap.image = image;\r\n\t\tthis._cubeMesh.material.emissiveMap.image = image;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if the NavCube is visible.\r\n\t *\r\n\t * @param {Boolean} visible Whether or not the NavCube is visible.\r\n\t */\r\n\tsetVisible(visible = true) {\r\n\t\tif (!this._navCubeCanvas) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._cubeMesh.visible = visible;\r\n\t\tif (this._shadow) {\r\n\t\t\tthis._shadow.visible = visible;\r\n\t\t}\r\n\t\tthis._navCubeCanvas.style.visibility = visible ? \"visible\" : \"hidden\";\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if the NavCube is visible.\r\n\t *\r\n\t * @return {Boolean} True when the NavCube is visible.\r\n\t */\r\n\tgetVisible() {\r\n\t\tif (!this._navCubeCanvas) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn this._cubeMesh.visible;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the axis, corner and edge-aligned views will fit the\r\n\t * view to the entire {@link Scene} or just to visible object-{@link Entity}s.\r\n\t *\r\n\t * Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.\r\n\t *\r\n\t * @param {Boolean} fitVisible Set ````true```` to fit only visible object-Entitys.\r\n\t */\r\n\tsetFitVisible(fitVisible = false) {\r\n\t\tthis._fitVisible = fitVisible;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the axis, corner and edge-aligned views will fit the\r\n\t * view to the entire {@link Scene} or just to visible object-{@link Entity}s.\r\n\t *\r\n\t * Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.\r\n\t *\r\n\t * @return {Boolean} True when fitting only visible object-Entitys.\r\n\t */\r\n\tgetFitVisible() {\r\n\t\treturn this._fitVisible;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the {@link Camera} flies or jumps to each selected axis or diagonal.\r\n\t *\r\n\t * Default is ````true````, to fly.\r\n\t *\r\n\t * @param {Boolean} cameraFly Set ````true```` to fly, else ````false```` to jump.\r\n\t */\r\n\tsetCameraFly(cameraFly = true) {\r\n\t\tthis._cameraFly = cameraFly;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the {@link Camera} flies or jumps to each selected axis or diagonal.\r\n\t *\r\n\t * Default is ````true````, to fly.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` to fly, else ````false```` to jump.\r\n\t */\r\n\tgetCameraFly() {\r\n\t\treturn this._cameraFly;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets how much of the field-of-view, in degrees, that the {@link Scene} should\r\n\t * fill the canvas when flying or jumping the {@link Camera} to each selected axis or diagonal.\r\n\t *\r\n\t * Default value is ````45````.\r\n\t *\r\n\t * @param {Number} cameraFitFOV New FOV value.\r\n\t */\r\n\tsetCameraFitFOV(cameraFitFOV = 45) {\r\n\t\tthis._cameraFitFOV = cameraFitFOV;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets how much of the field-of-view, in degrees, that the {@link Scene} should\r\n\t * fill the canvas when flying or jumping the {@link Camera} to each selected axis or diagonal.\r\n\t *\r\n\t * Default value is ````45````.\r\n\t *\r\n\t * @returns {Number} Current FOV value.\r\n\t */\r\n\tgetCameraFitFOV() {\r\n\t\treturn this._cameraFitFOV;\r\n\t}\r\n\r\n\t/**\r\n\t * When flying the {@link Camera} to each new axis or diagonal, sets how long, in seconds, that the Camera takes to get there.\r\n\t *\r\n\t * Default is ````0.5````.\r\n\t *\r\n\t * @param {Boolean} cameraFlyDuration Camera flight duration in seconds.\r\n\t */\r\n\tsetCameraFlyDuration(cameraFlyDuration = 0.5) {\r\n\t\tthis._cameraFlyDuration = cameraFlyDuration;\r\n\t}\r\n\r\n\t/**\r\n\t * When flying the {@link Camera} to each new axis or diagonal, gets how long, in seconds, that the Camera takes to get there.\r\n\t *\r\n\t * Default is ````0.5````.\r\n\t *\r\n\t * @returns {Boolean} Camera flight duration in seconds.\r\n\t */\r\n\tgetCameraFlyDuration() {\r\n\t\treturn this._cameraFlyDuration;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the NavCube switches between perspective and orthographic projections in synchrony with\r\n\t * the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.\r\n\t *\r\n\t * @param {Boolean} synchProjection Set ````true```` to keep NavCube projection synchronized with {@link Camera#projection}.\r\n\t */\r\n\tsetSynchProjection(synchProjection = false) {\r\n\t\tthis._synchProjection = synchProjection;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the NavCube switches between perspective and orthographic projections in synchrony with\r\n\t * the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.\r\n\t *\r\n\t * @return {Boolean} True when NavCube projection is synchronized with {@link Camera#projection}.\r\n\t */\r\n\tgetSynchProjection() {\r\n\t\treturn this._synchProjection;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the NavCube switches between project north and true north\r\n\t *\r\n\t * @param {Boolean} isProjectNorth Set ````true```` to use project north offset\r\n\t */\r\n\tsetIsProjectNorth(isProjectNorth = false) {\r\n\t\tthis._isProjectNorth = isProjectNorth;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the NavCube switches between project north and true north\r\n\t *\r\n\t * @return {Boolean} isProjectNorth when ````true```` - use project north offset\r\n\t */\r\n\tgetIsProjectNorth() {\r\n\t\treturn this._isProjectNorth;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the NavCube project north offset angle (used when {@link isProjectNorth} is ````true````\r\n\t *\r\n\t * @param {number} projectNorthOffsetAngle Set the vector offset for project north\r\n\t */\r\n\tsetProjectNorthOffsetAngle(projectNorthOffsetAngle) {\r\n\t\tthis._projectNorthOffsetAngle = projectNorthOffsetAngle;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the offset angle between project north and true north\r\n\t *\r\n\t * @return {number} projectNorthOffsetAngle\r\n\t */\r\n\tgetProjectNorthOffsetAngle() {\r\n\t\treturn this._projectNorthOffsetAngle;\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys this NavCubePlugin.\r\n\t *\r\n\t * Does not destroy the canvas the NavCubePlugin was configured with.\r\n\t */\r\n\tdestroy() {\r\n\t\tif (this._navCubeCanvas) {\r\n\t\t\tthis.viewer.localeService.off(this._onUpdated);\r\n\t\t\tthis.viewer.camera.off(this._onCameraMatrix);\r\n\t\t\tthis.viewer.camera.off(this._onCameraWorldAxis);\r\n\t\t\tthis.viewer.camera.perspective.off(this._onCameraFOV);\r\n\t\t\tthis.viewer.camera.off(this._onCameraProjection);\r\n\r\n\t\t\tthis._navCubeCanvas.removeEventListener(\"mouseenter\", this._onMouseEnter);\r\n\t\t\tthis._navCubeCanvas.removeEventListener(\"mouseleave\", this._onMouseLeave);\r\n\t\t\tthis._navCubeCanvas.removeEventListener(\"mousedown\", this._onMouseDown);\r\n\r\n\t\t\tdocument.removeEventListener(\"mousemove\", this._onMouseMove);\r\n\t\t\tdocument.removeEventListener(\"mouseup\", this._onMouseUp);\r\n\r\n\t\t\tthis._navCubeCanvas = null;\r\n\t\t\tthis._cubeTextureCanvas.destroy();\r\n\t\t\tthis._cubeTextureCanvas = null;\r\n\r\n\t\t\tthis._onMouseEnter = null;\r\n\t\t\tthis._onMouseLeave = null;\r\n\t\t\tthis._onMouseDown = null;\r\n\t\t\tthis._onMouseMove = null;\r\n\t\t\tthis._onMouseUp = null;\r\n\t\t}\r\n\r\n\t\tthis._navCubeScene.destroy();\r\n\t\tthis._navCubeScene = null;\r\n\t\tthis._cubeMesh = null;\r\n\t\tthis._shadow = null;\r\n\r\n\t\tsuper.destroy();\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/NavCubePlugin/NavCubePlugin.js?");
1797
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ NavCubePlugin: () => (/* binding */ NavCubePlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_scene_Scene_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/scene/Scene.js */ \"./src/viewer/scene/scene/Scene.js\");\n/* harmony import */ var _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./../../viewer/scene/lights/DirLight.js */ \"./src/viewer/scene/lights/DirLight.js\");\n/* harmony import */ var _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./../../viewer/scene/mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../viewer/scene/geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../viewer/scene/materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _viewer_scene_materials_Texture_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../viewer/scene/materials/Texture.js */ \"./src/viewer/scene/materials/Texture.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildCylinderGeometry.js */ \"./src/viewer/scene/geometry/builders/buildCylinderGeometry.js\");\n/* harmony import */ var _CubeTextureCanvas_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./CubeTextureCanvas.js */ \"./src/plugins/NavCubePlugin/CubeTextureCanvas.js\");\n/* harmony import */ var _viewer_scene_constants_constants_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../viewer/scene/constants/constants.js */ \"./src/viewer/scene/constants/constants.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst tempVec3a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\nconst tempVec3b = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\nconst tempMat4a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\r\n\r\n/**\r\n * {@link Viewer} plugin that lets us look at the entire {@link Scene} from along a chosen axis or diagonal.\r\n *\r\n * [<img src=\"https://user-images.githubusercontent.com/83100/55674490-c93c2e00-58b5-11e9-8a28-eb08876947c0.gif\">](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_NavCubePlugin)\r\n *\r\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_NavCubePlugin)]\r\n *\r\n * ## Overview\r\n *\r\n * * Rotating the NavCube causes the Viewer's {@link Camera} to orbit its current\r\n * point-of-interest. Conversely, orbiting the Camera causes the NavCube to rotate accordingly.\r\n * * The faces of the NavCube are aligned with the Viewer's {@link Scene}'s World-space coordinate axis. Clicking on a face moves\r\n * the Camera to look at the entire Scene along the corresponding axis. Clicking on an edge or a corner looks at\r\n * the entire Scene along a diagonal.\r\n * * The NavCube can be configured to either jump or fly the Camera to each new position. We can configure how tightly the\r\n * NavCube fits the Scene to view, and when flying, we can configure how fast it flies. We can also configure whether the\r\n * NavCube fits all objects to view, or just the currently visible objects. See below for a usage example.\r\n * * Clicking the NavCube also sets {@link CameraControl#pivotPos} to the center of the fitted objects.\r\n *\r\n * ## Usage\r\n *\r\n * In the example below, we'll create a Viewer and add a NavCubePlugin, which will create a NavCube gizmo in the canvas\r\n * with the given ID. Then we'll use the {@link XTCLoaderPlugin} to load a model into the Viewer's Scene. We can then\r\n * use the NavCube to look at the model along each axis or diagonal.\r\n *\r\n * ````JavaScript\r\n * import {Viewer, XTCLoaderPlugin, NavCubePlugin} from \"xeokit-sdk.es.js\";\r\n *\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\"\r\n * });\r\n *\r\n * viewer.camera.eye = [-3.93, 2.85, 27.01];\r\n * viewer.camera.look = [4.40, 3.72, 8.89];\r\n * viewer.camera.up = [-0.01, 0.99, 0.03];\r\n *\r\n * const navCube = new NavCubePlugin(viewer, {\r\n *\r\n * canvasID: \"myNavCubeCanvas\",\r\n *\r\n * visible: true, // Initially visible (default)\r\n *\r\n * cameraFly: true, // Fly camera to each selected axis/diagonal\r\n * cameraFitFOV: 45, // How much field-of-view the scene takes once camera has fitted it to view\r\n * cameraFlyDuration: 0.5,// How long (in seconds) camera takes to fly to each new axis/diagonal\r\n *\r\n * fitVisible: false, // Fit whole scene, including invisible objects (default)\r\n *\r\n * synchProjection: false // Keep NavCube in perspective projection, even when camera switches to ortho (default)\r\n * });\r\n *\r\n * const xtcLoader = new XTCLoaderPlugin(viewer);\r\n *\r\n * const model = xtcLoader.load({\r\n * id: \"myModel\",\r\n * src: \"./models/xtc/Duplex.ifc.xtc\",\r\n * edges: true\r\n * });\r\n * ````\r\n */\r\nclass NavCubePlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__.Plugin {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Viewer} viewer The {@link Viewer}.\r\n\t * @param {Object} cfg NavCubePlugin configuration.\r\n\t * @param {String} [cfg.id=\"NavCube\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\r\n\t * @param {String} [cfg.canvasId] ID of an existing HTML canvas to display the NavCube - either this or canvasElement is mandatory. When both values are given, the element reference is always preferred to the ID.\r\n\t * @param {HTMLCanvasElement} [cfg.canvasElement] Reference of an existing HTML canvas to display the NavCube - either this or canvasId is mandatory. When both values are given, the element reference is always preferred to the ID.\r\n\t * @param {div} [cfg.viewerElement] Reference of an existing div to contain the canvas\r\n\t * @param {Boolean} [cfg.visible=true] Initial visibility.\r\n\t * @param {Boolean} [cfg.shadowVisible=true] Whether the shadow of the cube is visible.\r\n\t * @param {String} [cfg.cameraFly=true] Whether the {@link Camera} flies or jumps to each selected axis or diagonal.\r\n\t * @param {String} [cfg.cameraFitFOV=45] How much of the field-of-view, in degrees, that the 3D scene should fill the {@link Canvas} when the {@link Camera} moves to an axis or diagonal.\r\n\t * @param {String} [cfg.cameraFlyDuration=0.5] When flying the {@link Camera} to each new axis or diagonal, how long, in seconds, that the Camera takes to get there.\r\n\t * @param {String} [cfg.color=\"lightgrey\"] Custom uniform color for the faces of the NavCube.\r\n\t * @param {String} [cfg.frontColor=\"#55FF55\"] Custom color for the front face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.backColor=\"#55FF55\"] Custom color for the back face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.leftColor=\"#FF5555\"] Custom color for the left face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.rightColor=\"#FF5555\"] Custom color for the right face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.topColor=\"#5555FF\"] Custom color for the top face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.bottomColor=\"#5555FF\"] Custom color for the bottom face of the NavCube. Overrides ````color````.\r\n\t * @param {String} [cfg.hoverColor=\"rgba(0,0,0,0.4)\"] Custom color for highlighting regions on the NavCube as we hover the pointer over them.\r\n\t * @param {String} [cfg.textColor=\"black\"] Custom text color for labels of the NavCube.\r\n\t * @param {Boolean} [cfg.fitVisible=false] Sets whether the axis, corner and edge-aligned views will fit the\r\n\t * view to the entire {@link Scene} or just to visible object-{@link Entity}s. Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.\r\n\t * @param {Boolean} [cfg.synchProjection=false] Sets whether the NavCube switches between perspective and orthographic projections in synchrony with the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.\r\n\t * @param {Boolean} [cfg.isProjectNorth] sets whether the NavCube switches between true north and project north - using the project north offset angle.\r\n\t * @param {number} [cfg.projectNorthOffsetAngle] sets the NavCube project north offset angle - when the {@link isProjectNorth} is true.\r\n\t */\r\n\tconstructor(viewer, cfg = {}) {\r\n\t\tsuper(\"NavCube\", viewer, cfg);\r\n\r\n\t\tviewer.navCube = this;\r\n\r\n\t\tvar visible = true;\r\n\r\n\t\ttry {\r\n\t\t\tthis._navCubeScene = new _viewer_scene_scene_Scene_js__WEBPACK_IMPORTED_MODULE_2__.Scene(viewer, {\r\n\t\t\t\tcanvasId: cfg.canvasId,\r\n\t\t\t\tcanvasElement: cfg.canvasElement,\r\n\t\t\t\ttransparent: true,\r\n\t\t\t\tspinnerElementId: \"navcube_spinner\"\r\n\t\t\t});\r\n\r\n\t\t\tthis._navCubeCanvas = this._navCubeScene.canvas.canvas;\r\n\r\n\t\t\tthis._navCubeScene.input.keyboardEnabled = false; // Don't want keyboard input in the NavCube\r\n\t\t} catch (error) {\r\n\t\t\tthis.error(error);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst navCubeScene = this._navCubeScene;\r\n\r\n\t\tnavCubeScene.clearLights();\r\n\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_3__.DirLight(navCubeScene, { dir: [0.4, -0.4, 0.8], color: [0.8, 1.0, 1.0], intensity: 1.0, space: \"view\" });\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_3__.DirLight(navCubeScene, { dir: [-0.8, -0.3, -0.4], color: [0.8, 0.8, 0.8], intensity: 1.0, space: \"view\" });\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_3__.DirLight(navCubeScene, { dir: [0.8, -0.6, -0.8], color: [1.0, 1.0, 1.0], intensity: 1.0, space: \"view\" });\r\n\r\n\t\tthis._navCubeCamera = navCubeScene.camera;\r\n\t\tthis._navCubeCamera.ortho.scale = 7.0;\r\n\t\tthis._navCubeCamera.ortho.near = 0.1;\r\n\t\tthis._navCubeCamera.ortho.far = 2000;\r\n\r\n\t\tnavCubeScene.edgeMaterial.edgeColor = [0.2, 0.2, 0.2];\r\n\t\tnavCubeScene.edgeMaterial.edgeAlpha = 0.6;\r\n\r\n\t\tthis._zUp = Boolean(viewer.camera.zUp);\r\n\r\n\t\tvar self = this;\r\n\r\n\t\tthis.setIsProjectNorth(cfg.isProjectNorth);\r\n\t\tthis.setProjectNorthOffsetAngle(cfg.projectNorthOffsetAngle);\r\n\r\n\t\tconst rotateTrueNorth = (this.rotateTrueNorth = (function () {\r\n\t\t\tconst trueNorthMatrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\r\n\t\t\treturn function (dir, vec, dest) {\r\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.identityMat4(trueNorthMatrix);\r\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.rotationMat4v(dir * self._projectNorthOffsetAngle * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.DEGTORAD, [0, 1, 0], trueNorthMatrix);\r\n\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec3(trueNorthMatrix, vec, dest);\r\n\t\t\t};\r\n\t\t})());\r\n\r\n\t\tthis._synchCamera = (function () {\r\n\t\t\tvar matrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.rotationMat4c(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.DEGTORAD, 1, 0, 0);\r\n\t\t\tvar eyeLookVec = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\t\t\tvar eyeLookVecCube = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\t\t\tvar upCube = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\t\t\treturn function () {\r\n\t\t\t\tvar eye = viewer.camera.eye;\r\n\t\t\t\tvar look = viewer.camera.look;\r\n\t\t\t\tvar up = viewer.camera.up;\r\n\t\t\t\teyeLookVec = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulVec3Scalar(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.subVec3(eye, look, eyeLookVec)), 5);\r\n\r\n\t\t\t\tif (self._isProjectNorth && self._projectNorthOffsetAngle) {\r\n\t\t\t\t\teyeLookVec = rotateTrueNorth(-1, eyeLookVec, tempVec3a);\r\n\t\t\t\t\tup = rotateTrueNorth(-1, up, tempVec3b);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (self._zUp) {\r\n\t\t\t\t\t// +Z up\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec3(matrix, eyeLookVec, eyeLookVecCube);\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec3(matrix, up, upCube);\r\n\t\t\t\t\tself._navCubeCamera.look = [0, 0, 0];\r\n\t\t\t\t\tself._navCubeCamera.eye = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec3(matrix, eyeLookVec, eyeLookVecCube);\r\n\t\t\t\t\tself._navCubeCamera.up = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformPoint3(matrix, up, upCube);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// +Y up\r\n\t\t\t\t\tself._navCubeCamera.look = [0, 0, 0];\r\n\t\t\t\t\tself._navCubeCamera.eye = eyeLookVec;\r\n\t\t\t\t\tself._navCubeCamera.up = up;\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t})();\r\n\r\n\t\tthis._cubeTextureCanvas = new _CubeTextureCanvas_js__WEBPACK_IMPORTED_MODULE_9__.CubeTextureCanvas(viewer, navCubeScene, cfg);\r\n\r\n\t\tthis._cubeSampler = new _viewer_scene_materials_Texture_js__WEBPACK_IMPORTED_MODULE_7__.Texture(navCubeScene, {\r\n\t\t\timage: this._cubeTextureCanvas.getImage(),\r\n\t\t\tflipY: true,\r\n\t\t\twrapS: _viewer_scene_constants_constants_js__WEBPACK_IMPORTED_MODULE_10__.ClampToEdgeWrapping,\r\n\t\t\twrapT: _viewer_scene_constants_constants_js__WEBPACK_IMPORTED_MODULE_10__.ClampToEdgeWrapping\r\n\t\t});\r\n\r\n\t\tthis._cubeMesh = new _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_4__.Mesh(navCubeScene, {\r\n\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_5__.ReadableGeometry(navCubeScene, {\r\n\t\t\t\tprimitive: \"triangles\",\r\n\t\t\t\tnormals: [\r\n\t\t\t\t\t0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,\r\n\t\t\t\t\t-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1,\r\n\t\t\t\t\t0, 0, -1\r\n\t\t\t\t],\r\n\t\t\t\tpositions: [\r\n\t\t\t\t\t1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1,\r\n\t\t\t\t\t-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1,\r\n\t\t\t\t\t-1, -1, -1, -1, 1, -1, 1, 1, -1\r\n\t\t\t\t],\r\n\t\t\t\tuv: [\r\n\t\t\t\t\t0.5, 0.6666, 0.25, 0.6666, 0.25, 0.3333, 0.5, 0.3333, 0.5, 0.6666, 0.5, 0.3333, 0.75, 0.3333, 0.75, 0.6666,\r\n\t\t\t\t\t0.5, 0.6666, 0.5, 1, 0.25, 1, 0.25, 0.6666, 0.25, 0.6666, 0.0, 0.6666, 0.0, 0.3333, 0.25, 0.3333, 0.25, 0,\r\n\t\t\t\t\t0.5, 0, 0.5, 0.3333, 0.25, 0.3333, 0.75, 0.3333, 1.0, 0.3333, 1.0, 0.6666, 0.75, 0.6666\r\n\t\t\t\t],\r\n\t\t\t\tindices: [\r\n\t\t\t\t\t0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20,\r\n\t\t\t\t\t21, 22, 20, 22, 23\r\n\t\t\t\t]\r\n\t\t\t}),\r\n\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_6__.PhongMaterial(navCubeScene, {\r\n\t\t\t\tdiffuse: [0.4, 0.4, 0.4],\r\n\t\t\t\tspecular: [0.4, 0.4, 0.4],\r\n\t\t\t\temissive: [0.6, 0.6, 0.6],\r\n\t\t\t\tdiffuseMap: this._cubeSampler,\r\n\t\t\t\temissiveMap: this._cubeSampler\r\n\t\t\t}),\r\n\t\t\tvisible: !!visible,\r\n\t\t\tedges: true\r\n\t\t});\r\n\r\n\t\tthis._shadow =\r\n\t\t\tcfg.shadowVisible === false\r\n\t\t\t\t? null\r\n\t\t\t\t: new _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_4__.Mesh(navCubeScene, {\r\n\t\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_5__.ReadableGeometry(\r\n\t\t\t\t\t\t\tnavCubeScene,\r\n\t\t\t\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_8__.buildCylinderGeometry)({\r\n\t\t\t\t\t\t\t\tcenter: [0, 0, 0],\r\n\t\t\t\t\t\t\t\tradiusTop: 0.001,\r\n\t\t\t\t\t\t\t\tradiusBottom: 1.4,\r\n\t\t\t\t\t\t\t\theight: 0.01,\r\n\t\t\t\t\t\t\t\tradialSegments: 20,\r\n\t\t\t\t\t\t\t\theightSegments: 1,\r\n\t\t\t\t\t\t\t\topenEnded: true\r\n\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_6__.PhongMaterial(navCubeScene, {\r\n\t\t\t\t\t\t\tdiffuse: [0.0, 0.0, 0.0],\r\n\t\t\t\t\t\t\tspecular: [0, 0, 0],\r\n\t\t\t\t\t\t\temissive: [0.0, 0.0, 0.0],\r\n\t\t\t\t\t\t\talpha: 0.5\r\n\t\t\t\t\t\t}),\r\n\t\t\t\t\t\tposition: [0, -1.5, 0],\r\n\t\t\t\t\t\tvisible: !!visible,\r\n\t\t\t\t\t\tpickable: false,\r\n\t\t\t\t\t\tbackfaces: false\r\n\t\t\t\t });\r\n\r\n\t\tthis._onCameraMatrix = viewer.camera.on(\"matrix\", this._synchCamera);\r\n\t\tthis._onCameraWorldAxis = viewer.camera.on(\"worldAxis\", () => {\r\n\t\t\tif (viewer.camera.zUp) {\r\n\t\t\t\tthis._zUp = true;\r\n\t\t\t\tthis._cubeTextureCanvas.setZUp();\r\n\t\t\t\tthis._repaint();\r\n\t\t\t\tthis._synchCamera();\r\n\t\t\t} else if (viewer.camera.yUp) {\r\n\t\t\t\tthis._zUp = false;\r\n\t\t\t\tthis._cubeTextureCanvas.setYUp();\r\n\t\t\t\tthis._repaint();\r\n\t\t\t\tthis._synchCamera();\r\n\t\t\t}\r\n\t\t});\r\n\t\tthis._onCameraFOV = viewer.camera.perspective.on(\"fov\", (fov) => {\r\n\t\t\tif (this._synchProjection) {\r\n\t\t\t\tthis._navCubeCamera.perspective.fov = fov;\r\n\t\t\t}\r\n\t\t});\r\n\t\tthis._onCameraProjection = viewer.camera.on(\"projection\", (projection) => {\r\n\t\t\tif (this._synchProjection) {\r\n\t\t\t\tthis._navCubeCamera.projection =\r\n\t\t\t\t\tprojection === \"ortho\" || projection === \"perspective\" ? projection : \"perspective\";\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tvar lastAreaId = -1;\r\n\r\n\t\tfunction actionMove(posX, posY) {\r\n\t\t\tvar yawInc = (posX - lastX) * -sensitivity;\r\n\t\t\tvar pitchInc = (posY - lastY) * -sensitivity;\r\n\t\t\tyaw -= yawInc;\r\n\t\t\tpitch -= pitchInc;\r\n\t\t\tif (minPitch !== undefined && pitch < minPitch) {\r\n\t\t\t\tpitch = minPitch;\r\n\t\t\t}\r\n\t\t\tif (maxPitch !== undefined && pitch > maxPitch) {\r\n\t\t\t\tpitch = maxPitch;\r\n\t\t\t}\r\n\t\t\tviewer.camera.orbitYaw(yawInc);\r\n\t\t\tviewer.camera.orbitPitch(-pitchInc);\r\n\t\t\tlastX = posX;\r\n\t\t\tlastY = posY;\r\n\t\t}\r\n\r\n\t\tfunction getCoordsWithinElement(event) {\r\n\t\t\tvar coords = [0, 0];\r\n\t\t\tif (!event) {\r\n\t\t\t\tevent = window.event;\r\n\t\t\t\tcoords[0] = event.x;\r\n\t\t\t\tcoords[1] = event.y;\r\n\t\t\t} else {\r\n\t\t\t\tvar element = event.target;\r\n\t\t\t\tvar totalOffsetLeft = 0;\r\n\t\t\t\tvar totalOffsetTop = 0;\r\n\t\t\t\twhile (element.offsetParent) {\r\n\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\r\n\t\t\t\t\ttotalOffsetTop += element.offsetTop;\r\n\t\t\t\t\telement = element.offsetParent;\r\n\t\t\t\t}\r\n\t\t\t\tcoords[0] = event.pageX - totalOffsetLeft;\r\n\t\t\t\tcoords[1] = event.pageY - totalOffsetTop;\r\n\t\t\t}\r\n\t\t\treturn coords;\r\n\t\t}\r\n\r\n\t\t{\r\n\t\t\tvar downX = null;\r\n\t\t\tvar downY = null;\r\n\t\t\tvar down = false;\r\n\t\t\tvar over = false;\r\n\r\n\t\t\tvar yaw = 0;\r\n\t\t\tvar pitch = 0;\r\n\t\t\tvar minPitch = null;\r\n\t\t\tvar maxPitch = null;\r\n\t\t\tvar sensitivity = 0.5;\r\n\r\n\t\t\tvar lastX;\r\n\t\t\tvar lastY;\r\n\r\n\t\t\tself._navCubeCanvas.addEventListener(\r\n\t\t\t\t\"mouseenter\",\r\n\t\t\t\t(self._onMouseEnter = function (e) {\r\n\t\t\t\t\tover = true;\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tself._navCubeCanvas.addEventListener(\r\n\t\t\t\t\"mouseleave\",\r\n\t\t\t\t(self._onMouseLeave = function (e) {\r\n\t\t\t\t\tover = false;\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tself._navCubeCanvas.addEventListener(\r\n\t\t\t\t\"mousedown\",\r\n\t\t\t\t(self._onMouseDown = function (e) {\r\n\t\t\t\t\tif (e.which !== 1) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdownX = e.x;\r\n\t\t\t\t\tdownY = e.y;\r\n\t\t\t\t\tlastX = e.clientX;\r\n\t\t\t\t\tlastY = e.clientY;\r\n\t\t\t\t\tvar canvasPos = getCoordsWithinElement(e);\r\n\t\t\t\t\tvar hit = navCubeScene.pick({\r\n\t\t\t\t\t\tcanvasPos: canvasPos\r\n\t\t\t\t\t});\r\n\t\t\t\t\tif (hit) {\r\n\t\t\t\t\t\tdown = true;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdown = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tdocument.addEventListener(\r\n\t\t\t\t\"mouseup\",\r\n\t\t\t\t(self._onMouseUp = function (e) {\r\n\t\t\t\t\tif (e.which !== 1) {\r\n\t\t\t\t\t\t// Left button\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdown = false;\r\n\t\t\t\t\tif (downX === null) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvar canvasPos = getCoordsWithinElement(e);\r\n\t\t\t\t\tvar hit = navCubeScene.pick({\r\n\t\t\t\t\t\tcanvasPos: canvasPos,\r\n\t\t\t\t\t\tpickSurface: true\r\n\t\t\t\t\t});\r\n\t\t\t\t\tif (hit) {\r\n\t\t\t\t\t\tif (hit.uv) {\r\n\t\t\t\t\t\t\tvar areaId = self._cubeTextureCanvas.getArea(hit.uv);\r\n\t\t\t\t\t\t\tif (areaId >= 0) {\r\n\t\t\t\t\t\t\t\tdocument.body.style.cursor = \"pointer\";\r\n\t\t\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tif (areaId >= 0) {\r\n\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(areaId, true);\r\n\t\t\t\t\t\t\t\t\tlastAreaId = areaId;\r\n\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\tif (e.x < downX - 3 || e.x > downX + 3 || e.y < downY - 3 || e.y > downY + 3) {\r\n\t\t\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tvar dir = self._cubeTextureCanvas.getAreaDir(areaId);\r\n\t\t\t\t\t\t\t\t\tif (dir) {\r\n\t\t\t\t\t\t\t\t\t\tvar up = self._cubeTextureCanvas.getAreaUp(areaId);\r\n\t\t\t\t\t\t\t\t\t\tif (self._isProjectNorth && self._projectNorthOffsetAngle) {\r\n\t\t\t\t\t\t\t\t\t\t\tdir = rotateTrueNorth(+1, dir, tempVec3a);\r\n\t\t\t\t\t\t\t\t\t\t\tup = rotateTrueNorth(+1, up, tempVec3b);\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\tflyTo(dir, up, function () {\r\n\t\t\t\t\t\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\t\tdocument.body.style.cursor = \"pointer\";\r\n\t\t\t\t\t\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\t\tif (areaId >= 0) {\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(areaId, false);\r\n\t\t\t\t\t\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tdocument.addEventListener(\r\n\t\t\t\t\"mousemove\",\r\n\t\t\t\t(self._onMouseMove = function (e) {\r\n\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (e.buttons === 1 && !down) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (down) {\r\n\t\t\t\t\t\tvar posX = e.clientX;\r\n\t\t\t\t\t\tvar posY = e.clientY;\r\n\t\t\t\t\t\tdocument.body.style.cursor = \"move\";\r\n\t\t\t\t\t\tactionMove(posX, posY);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (!over) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvar canvasPos = getCoordsWithinElement(e);\r\n\t\t\t\t\tvar hit = navCubeScene.pick({\r\n\t\t\t\t\t\tcanvasPos: canvasPos,\r\n\t\t\t\t\t\tpickSurface: true\r\n\t\t\t\t\t});\r\n\t\t\t\t\tif (hit) {\r\n\t\t\t\t\t\tif (hit.uv) {\r\n\t\t\t\t\t\t\tdocument.body.style.cursor = \"pointer\";\r\n\t\t\t\t\t\t\tvar areaId = self._cubeTextureCanvas.getArea(hit.uv);\r\n\t\t\t\t\t\t\tif (areaId === lastAreaId) {\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (areaId >= 0) {\r\n\t\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(areaId, true);\r\n\t\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\t\tlastAreaId = areaId;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.body.style.cursor = \"default\";\r\n\t\t\t\t\t\tif (lastAreaId >= 0) {\r\n\t\t\t\t\t\t\tself._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\r\n\t\t\t\t\t\t\tself._repaint();\r\n\t\t\t\t\t\t\tlastAreaId = -1;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tvar flyTo = (this.flyTo = (function () {\r\n\t\t\t\tvar center = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\t\t\t\treturn function (dir, up, ok) {\r\n\t\t\t\t\tvar aabb = self._fitVisible ? viewer.scene.getAABB(viewer.scene.visibleObjectIds) : viewer.scene.aabb;\r\n\t\t\t\t\tvar diag = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.getAABB3Diag(aabb);\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.getAABB3Center(aabb, center);\r\n\t\t\t\t\tvar dist = Math.abs(diag / Math.tan(self._cameraFitFOV * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.DEGTORAD));\r\n\t\t\t\t\tviewer.cameraControl.pivotPos = center;\r\n\t\t\t\t\tif (self._cameraFly) {\r\n\t\t\t\t\t\tviewer.cameraFlight.flyTo(\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\tlook: center,\r\n\t\t\t\t\t\t\t\teye: [center[0] - dist * dir[0], center[1] - dist * dir[1], center[2] - dist * dir[2]],\r\n\t\t\t\t\t\t\t\tup: up || [0, 1, 0],\r\n\t\t\t\t\t\t\t\torthoScale: diag * 1.1,\r\n\t\t\t\t\t\t\t\tfitFOV: self._cameraFitFOV,\r\n\t\t\t\t\t\t\t\tduration: self._cameraFlyDuration\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tok\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tviewer.cameraFlight.jumpTo(\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\tlook: center,\r\n\t\t\t\t\t\t\t\teye: [center[0] - dist * dir[0], center[1] - dist * dir[1], center[2] - dist * dir[2]],\r\n\t\t\t\t\t\t\t\tup: up || [0, 1, 0],\r\n\t\t\t\t\t\t\t\torthoScale: diag * 1.1,\r\n\t\t\t\t\t\t\t\tfitFOV: self._cameraFitFOV\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tok\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t};\r\n\t\t\t})());\r\n\t\t}\r\n\r\n\t\tthis._onUpdated = viewer.localeService.on(\"updated\", () => {\r\n\t\t\tthis._cubeTextureCanvas.clear();\r\n\t\t\tthis._repaint();\r\n\t\t});\r\n\r\n\t\tthis.setVisible(cfg.visible);\r\n\t\tthis.setCameraFitFOV(cfg.cameraFitFOV);\r\n\t\tthis.setCameraFly(cfg.cameraFly);\r\n\t\tthis.setCameraFlyDuration(cfg.cameraFlyDuration);\r\n\t\tthis.setFitVisible(cfg.fitVisible);\r\n\t\tthis.setSynchProjection(cfg.synchProjection);\r\n\t}\r\n\r\n\tflyByClick(areaId) {\r\n\t\tif (areaId >= 0) {\r\n\t\t\tthis._cubeTextureCanvas.setAreaHighlighted(areaId, true);\r\n\t\t\tthis._repaint();\r\n\t\t\tvar dir = this._cubeTextureCanvas.getAreaDir(areaId);\r\n\t\t\tif (dir) {\r\n\t\t\t\tvar up = this._cubeTextureCanvas.getAreaUp(areaId);\r\n\t\t\t\tif (this._isProjectNorth && this._projectNorthOffsetAngle) {\r\n\t\t\t\t\tdir = this.rotateTrueNorth(+1, dir, tempVec3a);\r\n\t\t\t\t\tup = this.rotateTrueNorth(+1, up, tempVec3b);\r\n\t\t\t\t}\r\n\t\t\t\tthis.flyTo(dir, up, function () {\r\n\t\t\t\t\tdocument.body.style.cursor = \"pointer\";\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tjumpByClick(areaId) {\r\n\t\tthis.setCameraFly(false);\r\n\t\tthis.flyByClick(areaId);\r\n\t\tthis.setCameraFly(true);\r\n\t}\r\n\r\n\tget navCubeScene() {\r\n\t\treturn this._navCubeScene;\r\n\t}\r\n\r\n\tsend(name, value) {\r\n\t\tswitch (name) {\r\n\t\t\tcase \"language\":\r\n\t\t\t\tthis._cubeTextureCanvas.clear();\r\n\t\t\t\tthis._repaint(); // CubeTextureCanvas gets language from Viewer\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\t_repaint() {\r\n\t\tconst image = this._cubeTextureCanvas.getImage();\r\n\t\tthis._cubeMesh.material.diffuseMap.image = image;\r\n\t\tthis._cubeMesh.material.emissiveMap.image = image;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if the NavCube is visible.\r\n\t *\r\n\t * @param {Boolean} visible Whether or not the NavCube is visible.\r\n\t */\r\n\tsetVisible(visible = true) {\r\n\t\tif (!this._navCubeCanvas) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._cubeMesh.visible = visible;\r\n\t\tif (this._shadow) {\r\n\t\t\tthis._shadow.visible = visible;\r\n\t\t}\r\n\t\tthis._navCubeCanvas.style.visibility = visible ? \"visible\" : \"hidden\";\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if the NavCube is visible.\r\n\t *\r\n\t * @return {Boolean} True when the NavCube is visible.\r\n\t */\r\n\tgetVisible() {\r\n\t\tif (!this._navCubeCanvas) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn this._cubeMesh.visible;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the axis, corner and edge-aligned views will fit the\r\n\t * view to the entire {@link Scene} or just to visible object-{@link Entity}s.\r\n\t *\r\n\t * Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.\r\n\t *\r\n\t * @param {Boolean} fitVisible Set ````true```` to fit only visible object-Entitys.\r\n\t */\r\n\tsetFitVisible(fitVisible = false) {\r\n\t\tthis._fitVisible = fitVisible;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the axis, corner and edge-aligned views will fit the\r\n\t * view to the entire {@link Scene} or just to visible object-{@link Entity}s.\r\n\t *\r\n\t * Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.\r\n\t *\r\n\t * @return {Boolean} True when fitting only visible object-Entitys.\r\n\t */\r\n\tgetFitVisible() {\r\n\t\treturn this._fitVisible;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the {@link Camera} flies or jumps to each selected axis or diagonal.\r\n\t *\r\n\t * Default is ````true````, to fly.\r\n\t *\r\n\t * @param {Boolean} cameraFly Set ````true```` to fly, else ````false```` to jump.\r\n\t */\r\n\tsetCameraFly(cameraFly = true) {\r\n\t\tthis._cameraFly = cameraFly;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the {@link Camera} flies or jumps to each selected axis or diagonal.\r\n\t *\r\n\t * Default is ````true````, to fly.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` to fly, else ````false```` to jump.\r\n\t */\r\n\tgetCameraFly() {\r\n\t\treturn this._cameraFly;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets how much of the field-of-view, in degrees, that the {@link Scene} should\r\n\t * fill the canvas when flying or jumping the {@link Camera} to each selected axis or diagonal.\r\n\t *\r\n\t * Default value is ````45````.\r\n\t *\r\n\t * @param {Number} cameraFitFOV New FOV value.\r\n\t */\r\n\tsetCameraFitFOV(cameraFitFOV = 45) {\r\n\t\tthis._cameraFitFOV = cameraFitFOV;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets how much of the field-of-view, in degrees, that the {@link Scene} should\r\n\t * fill the canvas when flying or jumping the {@link Camera} to each selected axis or diagonal.\r\n\t *\r\n\t * Default value is ````45````.\r\n\t *\r\n\t * @returns {Number} Current FOV value.\r\n\t */\r\n\tgetCameraFitFOV() {\r\n\t\treturn this._cameraFitFOV;\r\n\t}\r\n\r\n\t/**\r\n\t * When flying the {@link Camera} to each new axis or diagonal, sets how long, in seconds, that the Camera takes to get there.\r\n\t *\r\n\t * Default is ````0.5````.\r\n\t *\r\n\t * @param {Boolean} cameraFlyDuration Camera flight duration in seconds.\r\n\t */\r\n\tsetCameraFlyDuration(cameraFlyDuration = 0.5) {\r\n\t\tthis._cameraFlyDuration = cameraFlyDuration;\r\n\t}\r\n\r\n\t/**\r\n\t * When flying the {@link Camera} to each new axis or diagonal, gets how long, in seconds, that the Camera takes to get there.\r\n\t *\r\n\t * Default is ````0.5````.\r\n\t *\r\n\t * @returns {Boolean} Camera flight duration in seconds.\r\n\t */\r\n\tgetCameraFlyDuration() {\r\n\t\treturn this._cameraFlyDuration;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the NavCube switches between perspective and orthographic projections in synchrony with\r\n\t * the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.\r\n\t *\r\n\t * @param {Boolean} synchProjection Set ````true```` to keep NavCube projection synchronized with {@link Camera#projection}.\r\n\t */\r\n\tsetSynchProjection(synchProjection = false) {\r\n\t\tthis._synchProjection = synchProjection;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the NavCube switches between perspective and orthographic projections in synchrony with\r\n\t * the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.\r\n\t *\r\n\t * @return {Boolean} True when NavCube projection is synchronized with {@link Camera#projection}.\r\n\t */\r\n\tgetSynchProjection() {\r\n\t\treturn this._synchProjection;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the NavCube switches between project north and true north\r\n\t *\r\n\t * @param {Boolean} isProjectNorth Set ````true```` to use project north offset\r\n\t */\r\n\tsetIsProjectNorth(isProjectNorth = false) {\r\n\t\tthis._isProjectNorth = isProjectNorth;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the NavCube switches between project north and true north\r\n\t *\r\n\t * @return {Boolean} isProjectNorth when ````true```` - use project north offset\r\n\t */\r\n\tgetIsProjectNorth() {\r\n\t\treturn this._isProjectNorth;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the NavCube project north offset angle (used when {@link isProjectNorth} is ````true````\r\n\t *\r\n\t * @param {number} projectNorthOffsetAngle Set the vector offset for project north\r\n\t */\r\n\tsetProjectNorthOffsetAngle(projectNorthOffsetAngle) {\r\n\t\tthis._projectNorthOffsetAngle = projectNorthOffsetAngle;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the offset angle between project north and true north\r\n\t *\r\n\t * @return {number} projectNorthOffsetAngle\r\n\t */\r\n\tgetProjectNorthOffsetAngle() {\r\n\t\treturn this._projectNorthOffsetAngle;\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys this NavCubePlugin.\r\n\t *\r\n\t * Does not destroy the canvas the NavCubePlugin was configured with.\r\n\t */\r\n\tdestroy() {\r\n\t\tif (this._navCubeCanvas) {\r\n\t\t\tthis.viewer.localeService.off(this._onUpdated);\r\n\t\t\tthis.viewer.camera.off(this._onCameraMatrix);\r\n\t\t\tthis.viewer.camera.off(this._onCameraWorldAxis);\r\n\t\t\tthis.viewer.camera.perspective.off(this._onCameraFOV);\r\n\t\t\tthis.viewer.camera.off(this._onCameraProjection);\r\n\r\n\t\t\tthis._navCubeCanvas.removeEventListener(\"mouseenter\", this._onMouseEnter);\r\n\t\t\tthis._navCubeCanvas.removeEventListener(\"mouseleave\", this._onMouseLeave);\r\n\t\t\tthis._navCubeCanvas.removeEventListener(\"mousedown\", this._onMouseDown);\r\n\r\n\t\t\tdocument.removeEventListener(\"mousemove\", this._onMouseMove);\r\n\t\t\tdocument.removeEventListener(\"mouseup\", this._onMouseUp);\r\n\r\n\t\t\tthis._navCubeCanvas = null;\r\n\t\t\tthis._cubeTextureCanvas.destroy();\r\n\t\t\tthis._cubeTextureCanvas = null;\r\n\r\n\t\t\tthis._onMouseEnter = null;\r\n\t\t\tthis._onMouseLeave = null;\r\n\t\t\tthis._onMouseDown = null;\r\n\t\t\tthis._onMouseMove = null;\r\n\t\t\tthis._onMouseUp = null;\r\n\t\t}\r\n\r\n\t\tthis._navCubeScene.destroy();\r\n\t\tthis._navCubeScene = null;\r\n\t\tthis._cubeMesh = null;\r\n\t\tthis._shadow = null;\r\n\r\n\t\tsuper.destroy();\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/NavCubePlugin/NavCubePlugin.js?");
1798
1798
 
1799
1799
  /***/ }),
1800
1800
 
@@ -1824,7 +1824,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1824
1824
  \************************************************************/
1825
1825
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1826
1826
 
1827
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ OBJSceneGraphLoader: () => (/* binding */ OBJSceneGraphLoader)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _viewer_scene_materials_Texture_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../viewer/scene/materials/Texture.js */ \"./src/viewer/scene/materials/Texture.js\");\n/* harmony import */ var _viewer_scene_core_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../viewer/scene/core.js */ \"./src/viewer/scene/core.js\");\n/* harmony import */ var _viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../viewer/scene/math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst tempVec3a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_6__.math.vec3();\r\n\r\n/**\r\n * @private\r\n */\r\nclass OBJSceneGraphLoader {\r\n\r\n /**\r\n * Loads OBJ and MTL from file(s) into a {@link Node}.\r\n *\r\n * @static\r\n * @param {Node} modelNode Node to load into.\r\n * @param {String} src Path to OBJ file.\r\n * @param {Object} params Loading options.\r\n */\r\n load(modelNode, src, params = {}) {\r\n\r\n var spinner = modelNode.scene.canvas.spinner;\r\n spinner.processes++;\r\n\r\n loadOBJ(modelNode, src, function (state) {\r\n loadMTLs(modelNode, state, function () {\r\n\r\n createMeshes(modelNode, state);\r\n\r\n spinner.processes--;\r\n\r\n _viewer_scene_core_js__WEBPACK_IMPORTED_MODULE_4__.core.scheduleTask(function () {\r\n modelNode.fire(\"loaded\", true, false);\r\n });\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Parses OBJ and MTL text strings into a {@link Node}.\r\n *\r\n * @static\r\n * @param {Node} modelNode Node to load into.\r\n * @param {String} objText OBJ text string.\r\n * @param {String} [mtlText] MTL text string.\r\n * @param {String} [basePath] Base path for external resources.\r\n */\r\n parse(modelNode, objText, mtlText, basePath) {\r\n if (!objText) {\r\n this.warn(\"load() param expected: objText\");\r\n return;\r\n }\r\n var state = parseOBJ(modelNode, objText, null);\r\n if (mtlText) {\r\n parseMTL(modelNode, mtlText, basePath);\r\n }\r\n createMeshes(modelNode, state);\r\n modelNode.src = null;\r\n modelNode.fire(\"loaded\", true, false);\r\n }\r\n}\r\n\r\n//--------------------------------------------------------------------------------------------\r\n// Loads OBJ\r\n//\r\n// Parses OBJ into an intermediate state object. The object will contain geometry data\r\n// and material IDs from which meshes can be created later. The object will also\r\n// contain a list of filenames of the MTL files referenced by the OBJ, is any.\r\n//\r\n// Originally based on the THREE.js OBJ and MTL loaders:\r\n//\r\n// https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/OBJLoader.js\r\n// https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/MTLLoader.js\r\n//--------------------------------------------------------------------------------------------\r\n\r\nvar loadOBJ = function (modelNode, url, ok) {\r\n loadFile(url, function (text) {\r\n var state = parseOBJ(modelNode, text, url);\r\n ok(state);\r\n },\r\n function (error) {\r\n modelNode.error(error);\r\n });\r\n};\r\n\r\nvar parseOBJ = (function () {\r\n\r\n const regexp = {\r\n // v float float float\r\n vertex_pattern: /^v\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)/,\r\n // vn float float float\r\n normal_pattern: /^vn\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)/,\r\n // vt float float\r\n uv_pattern: /^vt\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)/,\r\n // f vertex vertex vertex\r\n face_vertex: /^f\\s+(-?\\d+)\\s+(-?\\d+)\\s+(-?\\d+)(?:\\s+(-?\\d+))?/,\r\n // f vertex/uv vertex/uv vertex/uv\r\n face_vertex_uv: /^f\\s+(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)(?:\\s+(-?\\d+)\\/(-?\\d+))?/,\r\n // f vertex/uv/normal vertex/uv/normal vertex/uv/normal\r\n face_vertex_uv_normal: /^f\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+)(?:\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))?/,\r\n // f vertex//normal vertex//normal vertex//normal\r\n face_vertex_normal: /^f\\s+(-?\\d+)\\/\\/(-?\\d+)\\s+(-?\\d+)\\/\\/(-?\\d+)\\s+(-?\\d+)\\/\\/(-?\\d+)(?:\\s+(-?\\d+)\\/\\/(-?\\d+))?/,\r\n // o object_name | g group_name\r\n object_pattern: /^[og]\\s*(.+)?/,\r\n // s boolean\r\n smoothing_pattern: /^s\\s+(\\d+|on|off)/,\r\n // mtllib file_reference\r\n material_library_pattern: /^mtllib /,\r\n // usemtl material_name\r\n material_use_pattern: /^usemtl /\r\n };\r\n\r\n return function (modelNode, text, url) {\r\n\r\n url = url || \"\";\r\n\r\n var state = {\r\n src: url,\r\n basePath: getBasePath(url),\r\n objects: [],\r\n object: {},\r\n positions: [],\r\n normals: [],\r\n uv: [],\r\n materialLibraries: {}\r\n };\r\n\r\n startObject(state, \"\", false);\r\n\r\n // Parts of this parser logic are derived from the THREE.js OBJ loader:\r\n // https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/OBJLoader.js\r\n\r\n if (text.indexOf('\\r\\n') !== -1) {\r\n // This is faster than String.split with regex that splits on both\r\n text = text.replace('\\r\\n', '\\n');\r\n }\r\n\r\n var lines = text.split('\\n');\r\n var line = '', lineFirstChar = '', lineSecondChar = '';\r\n var lineLength = 0;\r\n var result = [];\r\n\r\n // Faster to just trim left side of the line. Use if available.\r\n var trimLeft = (typeof ''.trimLeft === 'function');\r\n\r\n for (var i = 0, l = lines.length; i < l; i++) {\r\n\r\n line = lines[i];\r\n\r\n line = trimLeft ? line.trimLeft() : line.trim();\r\n\r\n lineLength = line.length;\r\n\r\n if (lineLength === 0) {\r\n continue;\r\n }\r\n\r\n lineFirstChar = line.charAt(0);\r\n\r\n if (lineFirstChar === '#') {\r\n continue;\r\n }\r\n\r\n if (lineFirstChar === 'v') {\r\n\r\n lineSecondChar = line.charAt(1);\r\n\r\n if (lineSecondChar === ' ' && (result = regexp.vertex_pattern.exec(line)) !== null) {\r\n\r\n // 0 1 2 3\r\n // ['v 1.0 2.0 3.0', '1.0', '2.0', '3.0']\r\n\r\n state.positions.push(\r\n parseFloat(result[1]),\r\n parseFloat(result[2]),\r\n parseFloat(result[3])\r\n );\r\n\r\n } else if (lineSecondChar === 'n' && (result = regexp.normal_pattern.exec(line)) !== null) {\r\n\r\n // 0 1 2 3\r\n // ['vn 1.0 2.0 3.0', '1.0', '2.0', '3.0']\r\n\r\n state.normals.push(\r\n parseFloat(result[1]),\r\n parseFloat(result[2]),\r\n parseFloat(result[3])\r\n );\r\n\r\n } else if (lineSecondChar === 't' && (result = regexp.uv_pattern.exec(line)) !== null) {\r\n\r\n // 0 1 2\r\n // ['vt 0.1 0.2', '0.1', '0.2']\r\n\r\n state.uv.push(\r\n parseFloat(result[1]),\r\n parseFloat(result[2])\r\n );\r\n\r\n } else {\r\n\r\n modelNode.error('Unexpected vertex/normal/uv line: \\'' + line + '\\'');\r\n return;\r\n }\r\n\r\n } else if (lineFirstChar === 'f') {\r\n\r\n if ((result = regexp.face_vertex_uv_normal.exec(line)) !== null) {\r\n\r\n // f vertex/uv/normal vertex/uv/normal vertex/uv/normal\r\n // 0 1 2 3 4 5 6 7 8 9 10 11 12\r\n // ['f 1/1/1 2/2/2 3/3/3', '1', '1', '1', '2', '2', '2', '3', '3', '3', undefined, undefined, undefined]\r\n\r\n addFace(state,\r\n result[1], result[4], result[7], result[10],\r\n result[2], result[5], result[8], result[11],\r\n result[3], result[6], result[9], result[12]\r\n );\r\n\r\n } else if ((result = regexp.face_vertex_uv.exec(line)) !== null) {\r\n\r\n // f vertex/uv vertex/uv vertex/uv\r\n // 0 1 2 3 4 5 6 7 8\r\n // ['f 1/1 2/2 3/3', '1', '1', '2', '2', '3', '3', undefined, undefined]\r\n\r\n addFace(state,\r\n result[1], result[3], result[5], result[7],\r\n result[2], result[4], result[6], result[8]\r\n );\r\n\r\n } else if ((result = regexp.face_vertex_normal.exec(line)) !== null) {\r\n\r\n // f vertex//normal vertex//normal vertex//normal\r\n // 0 1 2 3 4 5 6 7 8\r\n // ['f 1//1 2//2 3//3', '1', '1', '2', '2', '3', '3', undefined, undefined]\r\n\r\n addFace(state,\r\n result[1], result[3], result[5], result[7],\r\n undefined, undefined, undefined, undefined,\r\n result[2], result[4], result[6], result[8]\r\n );\r\n\r\n } else if ((result = regexp.face_vertex.exec(line)) !== null) {\r\n\r\n // f vertex vertex vertex\r\n // 0 1 2 3 4\r\n // ['f 1 2 3', '1', '2', '3', undefined]\r\n\r\n addFace(state, result[1], result[2], result[3], result[4]);\r\n } else {\r\n modelNode.error('Unexpected face line: \\'' + line + '\\'');\r\n return;\r\n }\r\n\r\n } else if (lineFirstChar === 'l') {\r\n\r\n var lineParts = line.substring(1).trim().split(' ');\r\n var lineVertices = [], lineUVs = [];\r\n\r\n if (line.indexOf('/') === -1) {\r\n\r\n lineVertices = lineParts;\r\n\r\n } else {\r\n for (var li = 0, llen = lineParts.length; li < llen; li++) {\r\n var parts = lineParts[li].split('/');\r\n if (parts[0] !== '') {\r\n lineVertices.push(parts[0]);\r\n }\r\n if (parts[1] !== '') {\r\n lineUVs.push(parts[1]);\r\n }\r\n }\r\n }\r\n addLineGeometry(state, lineVertices, lineUVs);\r\n\r\n } else if ((result = regexp.object_pattern.exec(line)) !== null) {\r\n\r\n // o object_name\r\n // or\r\n // g group_name\r\n\r\n var id = result[0].substr(1).trim();\r\n startObject(state, id, true);\r\n\r\n } else if (regexp.material_use_pattern.test(line)) {\r\n\r\n // material\r\n\r\n var id = line.substring(7).trim();\r\n state.object.material.id = id;\r\n\r\n } else if (regexp.material_library_pattern.test(line)) {\r\n\r\n // mtl file\r\n\r\n state.materialLibraries[line.substring(7).trim()] = true;\r\n\r\n } else if ((result = regexp.smoothing_pattern.exec(line)) !== null) {\r\n\r\n // smooth shading\r\n\r\n var value = result[1].trim().toLowerCase();\r\n state.object.material.smooth = (value === '1' || value === 'on');\r\n\r\n } else {\r\n\r\n // Handle null terminated files without exception\r\n if (line === '\\0') {\r\n continue;\r\n }\r\n\r\n modelNode.error('Unexpected line: \\'' + line + '\\'');\r\n return;\r\n }\r\n }\r\n\r\n return state;\r\n };\r\n\r\n function getBasePath(src) {\r\n var n = src.lastIndexOf('/');\r\n return (n === -1) ? src : src.substring(0, n + 1);\r\n }\r\n\r\n function startObject(state, id, fromDeclaration) {\r\n if (state.object && state.object.fromDeclaration === false) {\r\n state.object.id = id;\r\n state.object.fromDeclaration = (fromDeclaration !== false);\r\n return;\r\n }\r\n state.object = {\r\n id: id || '',\r\n geometry: {\r\n positions: [],\r\n normals: [],\r\n uv: []\r\n },\r\n material: {\r\n id: '',\r\n smooth: true\r\n },\r\n fromDeclaration: (fromDeclaration !== false)\r\n };\r\n state.objects.push(state.object);\r\n }\r\n\r\n function parseVertexIndex(value, len) {\r\n var index = parseInt(value, 10);\r\n return (index >= 0 ? index - 1 : index + len / 3) * 3;\r\n }\r\n\r\n function parseNormalIndex(value, len) {\r\n var index = parseInt(value, 10);\r\n return (index >= 0 ? index - 1 : index + len / 3) * 3;\r\n }\r\n\r\n function parseUVIndex(value, len) {\r\n var index = parseInt(value, 10);\r\n return (index >= 0 ? index - 1 : index + len / 2) * 2;\r\n }\r\n\r\n function addVertex(state, a, b, c) {\r\n var src = state.positions;\r\n var dst = state.object.geometry.positions;\r\n dst.push(src[a + 0]);\r\n dst.push(src[a + 1]);\r\n dst.push(src[a + 2]);\r\n dst.push(src[b + 0]);\r\n dst.push(src[b + 1]);\r\n dst.push(src[b + 2]);\r\n dst.push(src[c + 0]);\r\n dst.push(src[c + 1]);\r\n dst.push(src[c + 2]);\r\n }\r\n\r\n function addVertexLine(state, a) {\r\n var src = state.positions;\r\n var dst = state.object.geometry.positions;\r\n dst.push(src[a + 0]);\r\n dst.push(src[a + 1]);\r\n dst.push(src[a + 2]);\r\n }\r\n\r\n function addNormal(state, a, b, c) {\r\n var src = state.normals;\r\n var dst = state.object.geometry.normals;\r\n dst.push(src[a + 0]);\r\n dst.push(src[a + 1]);\r\n dst.push(src[a + 2]);\r\n dst.push(src[b + 0]);\r\n dst.push(src[b + 1]);\r\n dst.push(src[b + 2]);\r\n dst.push(src[c + 0]);\r\n dst.push(src[c + 1]);\r\n dst.push(src[c + 2]);\r\n }\r\n\r\n function addUV(state, a, b, c) {\r\n var src = state.uv;\r\n var dst = state.object.geometry.uv;\r\n dst.push(src[a + 0]);\r\n dst.push(src[a + 1]);\r\n dst.push(src[b + 0]);\r\n dst.push(src[b + 1]);\r\n dst.push(src[c + 0]);\r\n dst.push(src[c + 1]);\r\n }\r\n\r\n function addUVLine(state, a) {\r\n var src = state.uv;\r\n var dst = state.object.geometry.uv;\r\n dst.push(src[a + 0]);\r\n dst.push(src[a + 1]);\r\n }\r\n\r\n function addFace(state, a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd) {\r\n var vLen = state.positions.length;\r\n var ia = parseVertexIndex(a, vLen);\r\n var ib = parseVertexIndex(b, vLen);\r\n var ic = parseVertexIndex(c, vLen);\r\n var id;\r\n if (d === undefined) {\r\n addVertex(state, ia, ib, ic);\r\n\r\n } else {\r\n id = parseVertexIndex(d, vLen);\r\n addVertex(state, ia, ib, id);\r\n addVertex(state, ib, ic, id);\r\n }\r\n\r\n if (ua !== undefined) {\r\n\r\n var uvLen = state.uv.length;\r\n\r\n ia = parseUVIndex(ua, uvLen);\r\n ib = parseUVIndex(ub, uvLen);\r\n ic = parseUVIndex(uc, uvLen);\r\n\r\n if (d === undefined) {\r\n addUV(state, ia, ib, ic);\r\n\r\n } else {\r\n id = parseUVIndex(ud, uvLen);\r\n addUV(state, ia, ib, id);\r\n addUV(state, ib, ic, id);\r\n }\r\n }\r\n\r\n if (na !== undefined) {\r\n\r\n // Normals are many times the same. If so, skip function call and parseInt.\r\n\r\n var nLen = state.normals.length;\r\n\r\n ia = parseNormalIndex(na, nLen);\r\n ib = na === nb ? ia : parseNormalIndex(nb, nLen);\r\n ic = na === nc ? ia : parseNormalIndex(nc, nLen);\r\n\r\n if (d === undefined) {\r\n addNormal(state, ia, ib, ic);\r\n\r\n } else {\r\n\r\n id = parseNormalIndex(nd, nLen);\r\n addNormal(state, ia, ib, id);\r\n addNormal(state, ib, ic, id);\r\n }\r\n }\r\n }\r\n\r\n function addLineGeometry(state, positions, uv) {\r\n\r\n state.object.geometry.type = 'Line';\r\n\r\n var vLen = state.positions.length;\r\n var uvLen = state.uv.length;\r\n\r\n for (var vi = 0, l = positions.length; vi < l; vi++) {\r\n addVertexLine(state, parseVertexIndex(positions[vi], vLen));\r\n }\r\n\r\n for (var uvi = 0, uvl = uv.length; uvi < uvl; uvi++) {\r\n addUVLine(state, parseUVIndex(uv[uvi], uvLen));\r\n }\r\n }\r\n})();\r\n\r\n//--------------------------------------------------------------------------------------------\r\n// Loads MTL files listed in parsed state\r\n//--------------------------------------------------------------------------------------------\r\n\r\nfunction loadMTLs(modelNode, state, ok) {\r\n var basePath = state.basePath;\r\n var srcList = Object.keys(state.materialLibraries);\r\n var numToLoad = srcList.length;\r\n for (var i = 0, len = numToLoad; i < len; i++) {\r\n loadMTL(modelNode, basePath, basePath + srcList[i], function () {\r\n if (--numToLoad === 0) {\r\n ok();\r\n }\r\n });\r\n }\r\n}\r\n\r\n//--------------------------------------------------------------------------------------------\r\n// Loads an MTL file\r\n//--------------------------------------------------------------------------------------------\r\n\r\nvar loadMTL = function (modelNode, basePath, src, ok) {\r\n loadFile(src, function (text) {\r\n parseMTL(modelNode, text, basePath);\r\n ok();\r\n },\r\n function (error) {\r\n modelNode.error(error);\r\n ok();\r\n });\r\n};\r\n\r\nvar parseMTL = (function () {\r\n\r\n var delimiter_pattern = /\\s+/;\r\n\r\n return function (modelNode, mtlText, basePath) {\r\n\r\n var lines = mtlText.split('\\n');\r\n var materialCfg = {\r\n id: \"Default\"\r\n };\r\n var needCreate = false;\r\n var line;\r\n var pos;\r\n var key;\r\n var value;\r\n var alpha;\r\n\r\n basePath = basePath || \"\";\r\n\r\n for (var i = 0; i < lines.length; i++) {\r\n\r\n line = lines[i].trim();\r\n\r\n if (line.length === 0 || line.charAt(0) === '#') { // Blank line or comment ignore\r\n continue;\r\n }\r\n\r\n pos = line.indexOf(' ');\r\n\r\n key = (pos >= 0) ? line.substring(0, pos) : line;\r\n key = key.toLowerCase();\r\n\r\n value = (pos >= 0) ? line.substring(pos + 1) : '';\r\n value = value.trim();\r\n\r\n switch (key.toLowerCase()) {\r\n\r\n case \"newmtl\": // New material\r\n //if (needCreate) {\r\n createMaterial(modelNode, materialCfg);\r\n //}\r\n materialCfg = {\r\n id: value\r\n };\r\n needCreate = true;\r\n break;\r\n\r\n case 'ka':\r\n materialCfg.ambient = parseRGB(value);\r\n break;\r\n\r\n case 'kd':\r\n materialCfg.diffuse = parseRGB(value);\r\n break;\r\n\r\n case 'ks':\r\n materialCfg.specular = parseRGB(value);\r\n break;\r\n\r\n case 'map_kd':\r\n if (!materialCfg.diffuseMap) {\r\n materialCfg.diffuseMap = createTexture(modelNode, basePath, value, \"sRGB\");\r\n }\r\n break;\r\n\r\n case 'map_ks':\r\n if (!materialCfg.specularMap) {\r\n materialCfg.specularMap = createTexture(modelNode, basePath, value, \"linear\");\r\n }\r\n break;\r\n\r\n case 'map_bump':\r\n case 'bump':\r\n if (!materialCfg.normalMap) {\r\n materialCfg.normalMap = createTexture(modelNode, basePath, value);\r\n }\r\n break;\r\n\r\n case 'ns':\r\n materialCfg.shininess = parseFloat(value);\r\n break;\r\n\r\n case 'd':\r\n alpha = parseFloat(value);\r\n if (alpha < 1) {\r\n materialCfg.alpha = alpha;\r\n materialCfg.alphaMode = \"blend\";\r\n }\r\n break;\r\n\r\n case 'tr':\r\n alpha = parseFloat(value);\r\n if (alpha > 0) {\r\n materialCfg.alpha = 1 - alpha;\r\n materialCfg.alphaMode = \"blend\";\r\n }\r\n break;\r\n\r\n default:\r\n // modelNode.error(\"Unrecognized token: \" + key);\r\n }\r\n }\r\n\r\n if (needCreate) {\r\n createMaterial(modelNode, materialCfg);\r\n }\r\n };\r\n\r\n function createTexture(modelNode, basePath, value, encoding) {\r\n var textureCfg = {};\r\n var items = value.split(/\\s+/);\r\n var pos = items.indexOf('-bm');\r\n if (pos >= 0) {\r\n //matParams.bumpScale = parseFloat(items[pos + 1]);\r\n items.splice(pos, 2);\r\n }\r\n pos = items.indexOf('-s');\r\n if (pos >= 0) {\r\n textureCfg.scale = [parseFloat(items[pos + 1]), parseFloat(items[pos + 2])];\r\n items.splice(pos, 4); // we expect 3 parameters here!\r\n }\r\n pos = items.indexOf('-o');\r\n if (pos >= 0) {\r\n textureCfg.translate = [parseFloat(items[pos + 1]), parseFloat(items[pos + 2])];\r\n items.splice(pos, 4); // we expect 3 parameters here!\r\n }\r\n textureCfg.src = basePath + items.join(' ').trim();\r\n textureCfg.flipY = true;\r\n textureCfg.encoding = encoding || \"linear\";\r\n //textureCfg.wrapS = self.wrap;\r\n //textureCfg.wrapT = self.wrap;\r\n var texture = new _viewer_scene_materials_Texture_js__WEBPACK_IMPORTED_MODULE_3__.Texture(modelNode, textureCfg);\r\n return texture.id;\r\n }\r\n\r\n function createMaterial(modelNode, materialCfg) {\r\n new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_2__.PhongMaterial(modelNode, materialCfg);\r\n }\r\n\r\n function parseRGB(value) {\r\n var ss = value.split(delimiter_pattern, 3);\r\n return [parseFloat(ss[0]), parseFloat(ss[1]), parseFloat(ss[2])];\r\n }\r\n\r\n})();\r\n//--------------------------------------------------------------------------------------------\r\n// Creates meshes from parsed state\r\n//--------------------------------------------------------------------------------------------\r\n\r\n\r\nfunction createMeshes(modelNode, state) {\r\n\r\n for (var j = 0, k = state.objects.length; j < k; j++) {\r\n\r\n var object = state.objects[j];\r\n var geometry = object.geometry;\r\n var isLine = (geometry.type === 'Line');\r\n\r\n if (geometry.positions.length === 0) {\r\n // Skip o/g line declarations that did not follow with any faces\r\n continue;\r\n }\r\n\r\n var geometryCfg = {\r\n primitive: \"triangles\",\r\n compressGeometry: false\r\n };\r\n\r\n geometryCfg.positions = geometry.positions;\r\n\r\n if (geometry.normals.length > 0) {\r\n geometryCfg.normals = geometry.normals;\r\n }\r\n\r\n if (geometry.uv.length > 0) {\r\n geometryCfg.uv = geometry.uv;\r\n }\r\n\r\n var indices = new Array(geometryCfg.positions.length / 3); // Triangle soup\r\n for (var idx = 0; idx < indices.length; idx++) {\r\n indices[idx] = idx;\r\n }\r\n geometryCfg.indices = indices;\r\n\r\n const origin = tempVec3a;\r\n\r\n (0,_viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__.worldToRTCPositions)(geometry.positions, geometry.positions, origin);\r\n\r\n var readableGeometry = new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_1__.ReadableGeometry(modelNode, geometryCfg);\r\n\r\n var materialId = object.material.id;\r\n var material;\r\n if (materialId && materialId !== \"\") {\r\n material = modelNode.scene.components[materialId];\r\n if (!material) {\r\n modelNode.error(\"Material not found: \" + materialId);\r\n }\r\n } else {\r\n material = new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_2__.PhongMaterial(modelNode, {\r\n //emissive: [0.6, 0.6, 0.0],\r\n diffuse: [0.6, 0.6, 0.6],\r\n backfaces: true\r\n });\r\n\r\n }\r\n\r\n // material.emissive = [Math.random(), Math.random(), Math.random()];\r\n\r\n var mesh = new _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_0__.Mesh(modelNode, {\r\n id: modelNode.id + \"#\" + object.id,\r\n origin: (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0) ? origin : null,\r\n isObject: true,\r\n geometry: readableGeometry,\r\n material: material,\r\n pickable: true\r\n });\r\n\r\n modelNode.addChild(mesh);\r\n }\r\n}\r\n\r\nfunction loadFile(url, ok, err) {\r\n var request = new XMLHttpRequest();\r\n request.open('GET', url, true);\r\n request.addEventListener('load', function (event) {\r\n var response = event.target.response;\r\n if (this.status === 200) {\r\n if (ok) {\r\n ok(response);\r\n }\r\n } else if (this.status === 0) {\r\n // Some browsers return HTTP Status 0 when using non-http protocol\r\n // e.g. 'file://' or 'data://'. Handle as success.\r\n console.warn('loadFile: HTTP Status 0 received.');\r\n if (ok) {\r\n ok(response);\r\n }\r\n } else {\r\n if (err) {\r\n err(event);\r\n }\r\n }\r\n }, false);\r\n\r\n request.addEventListener('error', function (event) {\r\n if (err) {\r\n err(event);\r\n }\r\n }, false);\r\n request.send(null);\r\n}\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/OBJLoaderPlugin/OBJSceneGraphLoader.js?");
1827
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ OBJSceneGraphLoader: () => (/* binding */ OBJSceneGraphLoader)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _viewer_scene_materials_Texture_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../viewer/scene/materials/Texture.js */ \"./src/viewer/scene/materials/Texture.js\");\n/* harmony import */ var _viewer_scene_core_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../viewer/scene/core.js */ \"./src/viewer/scene/core.js\");\n/* harmony import */ var _viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../viewer/scene/math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n\n\n\n\n\n\n\n\nconst tempVec3a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_6__.math.vec3();\n\n/**\n * @private\n */\nclass OBJSceneGraphLoader {\n\t/**\n\t * Loads OBJ and MTL from file(s) into a {@link Node}.\n\t *\n\t * @static\n\t * @param {Node} modelNode Node to load into.\n\t * @param {String} src Path to OBJ file.\n\t * @param {Object} params Loading options.\n\t */\n\tload(modelNode, src, params = {}) {\n\t\t// var spinner = modelNode.scene.canvas.spinner;\n\t\t// spinner.processes++;\n\t\tconst parse = this.parse;\n\t\tloadOBJ(modelNode, src, function (state) {\n\t\t\t// loadMTLs(modelNode, state, function () {\n\t\t\t// \tcreateMeshes(modelNode, state);\n\n\t\t\t// \tspinner.processes--;\n\n\t\t\t// \tcore.scheduleTask(function () {\n\t\t\t// \t\tmodelNode.fire(\"loaded\", true, false);\n\t\t\t// \t});\n\t\t\t// });\n\n\t\t\tparse(modelNode, state, null, null);\n\t\t});\n\t}\n\n\t/**\n\t * Parses OBJ and MTL text strings into a {@link Node}.\n\t *\n\t * @static\n\t * @param {Node} modelNode Node to load into.\n\t * @param {String} objText OBJ text string.\n\t * @param {String} [mtlText] MTL text string.\n\t * @param {String} [basePath] Base path for external resources.\n\t */\n\t// parse(modelNode, objText, mtlText, basePath) {\n\tparse(modelNode, state, mtlText, basePath) {\n\t\t// if (!objText) {\n\t\t// \tthis.warn(\"load() param expected: objText\");\n\t\t// \treturn;\n\t\t// }\n\t\t// var state = parseOBJ(modelNode, objText, null);\n\t\tif (mtlText) {\n\t\t\tparseMTL(modelNode, mtlText, basePath);\n\t\t}\n\t\tcreateMeshes(modelNode, state);\n\t\tmodelNode.src = null;\n\t\tmodelNode.fire(\"loaded\", true, false);\n\n\t\t_viewer_scene_core_js__WEBPACK_IMPORTED_MODULE_4__.core.scheduleTask(function () {\n\t\t\tmodelNode.fire(\"loaded\", true, false);\n\t\t});\n\t}\n}\n\n//--------------------------------------------------------------------------------------------\n// Loads OBJ\n//\n// Parses OBJ into an intermediate state object. The object will contain geometry data\n// and material IDs from which meshes can be created later. The object will also\n// contain a list of filenames of the MTL files referenced by the OBJ, is any.\n//\n// Originally based on the THREE.js OBJ and MTL loaders:\n//\n// https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/OBJLoader.js\n// https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/MTLLoader.js\n//--------------------------------------------------------------------------------------------\n\nvar loadOBJ = function (modelNode, url, ok) {\n\tloadFile(\n\t\turl,\n\t\tfunction (text) {\n\t\t\tvar state = parseOBJ(modelNode, text, url);\n\t\t\tok(state);\n\t\t},\n\t\tfunction (error) {\n\t\t\tmodelNode.error(error);\n\t\t}\n\t);\n};\n\nvar parseOBJ = (function () {\n\tconst regexp = {\n\t\t// v float float float\n\t\tvertex_pattern: /^v\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)/,\n\t\t// vn float float float\n\t\tnormal_pattern: /^vn\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)/,\n\t\t// vt float float\n\t\tuv_pattern: /^vt\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)/,\n\t\t// f vertex vertex vertex\n\t\tface_vertex: /^f\\s+(-?\\d+)\\s+(-?\\d+)\\s+(-?\\d+)(?:\\s+(-?\\d+))?/,\n\t\t// f vertex/uv vertex/uv vertex/uv\n\t\tface_vertex_uv: /^f\\s+(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)(?:\\s+(-?\\d+)\\/(-?\\d+))?/,\n\t\t// f vertex/uv/normal vertex/uv/normal vertex/uv/normal\n\t\tface_vertex_uv_normal:\n\t\t\t/^f\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+)(?:\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))?/,\n\t\t// f vertex//normal vertex//normal vertex//normal\n\t\tface_vertex_normal: /^f\\s+(-?\\d+)\\/\\/(-?\\d+)\\s+(-?\\d+)\\/\\/(-?\\d+)\\s+(-?\\d+)\\/\\/(-?\\d+)(?:\\s+(-?\\d+)\\/\\/(-?\\d+))?/,\n\t\t// o object_name | g group_name\n\t\tobject_pattern: /^[og]\\s*(.+)?/,\n\t\t// s boolean\n\t\tsmoothing_pattern: /^s\\s+(\\d+|on|off)/,\n\t\t// mtllib file_reference\n\t\tmaterial_library_pattern: /^mtllib /,\n\t\t// usemtl material_name\n\t\tmaterial_use_pattern: /^usemtl /\n\t};\n\n\treturn function (modelNode, text, url) {\n\t\turl = url || \"\";\n\n\t\tvar state = {\n\t\t\tsrc: url,\n\t\t\tbasePath: getBasePath(url),\n\t\t\tobjects: [],\n\t\t\tobject: {},\n\t\t\tpositions: [],\n\t\t\tnormals: [],\n\t\t\tuv: [],\n\t\t\tmaterialLibraries: {}\n\t\t};\n\n\t\tstartObject(state, \"\", false);\n\n\t\t// Parts of this parser logic are derived from the THREE.js OBJ loader:\n\t\t// https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/OBJLoader.js\n\n\t\tif (text.indexOf(\"\\r\\n\") !== -1) {\n\t\t\t// This is faster than String.split with regex that splits on both\n\t\t\ttext = text.replace(\"\\r\\n\", \"\\n\");\n\t\t}\n\n\t\tvar lines = text.split(\"\\n\");\n\t\tvar line = \"\",\n\t\t\tlineFirstChar = \"\",\n\t\t\tlineSecondChar = \"\";\n\t\tvar lineLength = 0;\n\t\tvar result = [];\n\n\t\t// Faster to just trim left side of the line. Use if available.\n\t\tvar trimLeft = typeof \"\".trimLeft === \"function\";\n\n\t\tfor (var i = 0, l = lines.length; i < l; i++) {\n\t\t\tline = lines[i];\n\n\t\t\tline = trimLeft ? line.trimLeft() : line.trim();\n\n\t\t\tlineLength = line.length;\n\n\t\t\tif (lineLength === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlineFirstChar = line.charAt(0);\n\n\t\t\tif (lineFirstChar === \"#\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (lineFirstChar === \"v\") {\n\t\t\t\tlineSecondChar = line.charAt(1);\n\n\t\t\t\tif (lineSecondChar === \" \" && (result = regexp.vertex_pattern.exec(line)) !== null) {\n\t\t\t\t\t// 0 1 2 3\n\t\t\t\t\t// ['v 1.0 2.0 3.0', '1.0', '2.0', '3.0']\n\n\t\t\t\t\tstate.positions.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n\t\t\t\t} else if (lineSecondChar === \"n\" && (result = regexp.normal_pattern.exec(line)) !== null) {\n\t\t\t\t\t// 0 1 2 3\n\t\t\t\t\t// ['vn 1.0 2.0 3.0', '1.0', '2.0', '3.0']\n\n\t\t\t\t\tstate.normals.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n\t\t\t\t} else if (lineSecondChar === \"t\" && (result = regexp.uv_pattern.exec(line)) !== null) {\n\t\t\t\t\t// 0 1 2\n\t\t\t\t\t// ['vt 0.1 0.2', '0.1', '0.2']\n\n\t\t\t\t\tstate.uv.push(parseFloat(result[1]), parseFloat(result[2]));\n\t\t\t\t} else {\n\t\t\t\t\tmodelNode.error(\"Unexpected vertex/normal/uv line: '\" + line + \"'\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (lineFirstChar === \"f\") {\n\t\t\t\tif ((result = regexp.face_vertex_uv_normal.exec(line)) !== null) {\n\t\t\t\t\t// f vertex/uv/normal vertex/uv/normal vertex/uv/normal\n\t\t\t\t\t// 0 1 2 3 4 5 6 7 8 9 10 11 12\n\t\t\t\t\t// ['f 1/1/1 2/2/2 3/3/3', '1', '1', '1', '2', '2', '2', '3', '3', '3', undefined, undefined, undefined]\n\n\t\t\t\t\taddFace(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\tresult[1],\n\t\t\t\t\t\tresult[4],\n\t\t\t\t\t\tresult[7],\n\t\t\t\t\t\tresult[10],\n\t\t\t\t\t\tresult[2],\n\t\t\t\t\t\tresult[5],\n\t\t\t\t\t\tresult[8],\n\t\t\t\t\t\tresult[11],\n\t\t\t\t\t\tresult[3],\n\t\t\t\t\t\tresult[6],\n\t\t\t\t\t\tresult[9],\n\t\t\t\t\t\tresult[12]\n\t\t\t\t\t);\n\t\t\t\t} else if ((result = regexp.face_vertex_uv.exec(line)) !== null) {\n\t\t\t\t\t// f vertex/uv vertex/uv vertex/uv\n\t\t\t\t\t// 0 1 2 3 4 5 6 7 8\n\t\t\t\t\t// ['f 1/1 2/2 3/3', '1', '1', '2', '2', '3', '3', undefined, undefined]\n\n\t\t\t\t\taddFace(state, result[1], result[3], result[5], result[7], result[2], result[4], result[6], result[8]);\n\t\t\t\t} else if ((result = regexp.face_vertex_normal.exec(line)) !== null) {\n\t\t\t\t\t// f vertex//normal vertex//normal vertex//normal\n\t\t\t\t\t// 0 1 2 3 4 5 6 7 8\n\t\t\t\t\t// ['f 1//1 2//2 3//3', '1', '1', '2', '2', '3', '3', undefined, undefined]\n\n\t\t\t\t\taddFace(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\tresult[1],\n\t\t\t\t\t\tresult[3],\n\t\t\t\t\t\tresult[5],\n\t\t\t\t\t\tresult[7],\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tresult[2],\n\t\t\t\t\t\tresult[4],\n\t\t\t\t\t\tresult[6],\n\t\t\t\t\t\tresult[8]\n\t\t\t\t\t);\n\t\t\t\t} else if ((result = regexp.face_vertex.exec(line)) !== null) {\n\t\t\t\t\t// f vertex vertex vertex\n\t\t\t\t\t// 0 1 2 3 4\n\t\t\t\t\t// ['f 1 2 3', '1', '2', '3', undefined]\n\n\t\t\t\t\taddFace(state, result[1], result[2], result[3], result[4]);\n\t\t\t\t} else {\n\t\t\t\t\tmodelNode.error(\"Unexpected face line: '\" + line + \"'\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (lineFirstChar === \"l\") {\n\t\t\t\tvar lineParts = line.substring(1).trim().split(\" \");\n\t\t\t\tvar lineVertices = [],\n\t\t\t\t\tlineUVs = [];\n\n\t\t\t\tif (line.indexOf(\"/\") === -1) {\n\t\t\t\t\tlineVertices = lineParts;\n\t\t\t\t} else {\n\t\t\t\t\tfor (var li = 0, llen = lineParts.length; li < llen; li++) {\n\t\t\t\t\t\tvar parts = lineParts[li].split(\"/\");\n\t\t\t\t\t\tif (parts[0] !== \"\") {\n\t\t\t\t\t\t\tlineVertices.push(parts[0]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (parts[1] !== \"\") {\n\t\t\t\t\t\t\tlineUVs.push(parts[1]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\taddLineGeometry(state, lineVertices, lineUVs);\n\t\t\t} else if ((result = regexp.object_pattern.exec(line)) !== null) {\n\t\t\t\t// o object_name\n\t\t\t\t// or\n\t\t\t\t// g group_name\n\n\t\t\t\tvar id = result[0].substr(1).trim();\n\t\t\t\tstartObject(state, id, true);\n\t\t\t} else if (regexp.material_use_pattern.test(line)) {\n\t\t\t\t// material\n\n\t\t\t\tvar id = line.substring(7).trim();\n\t\t\t\tstate.object.material.id = id;\n\t\t\t} else if (regexp.material_library_pattern.test(line)) {\n\t\t\t\t// mtl file\n\n\t\t\t\tstate.materialLibraries[line.substring(7).trim()] = true;\n\t\t\t} else if ((result = regexp.smoothing_pattern.exec(line)) !== null) {\n\t\t\t\t// smooth shading\n\n\t\t\t\tvar value = result[1].trim().toLowerCase();\n\t\t\t\tstate.object.material.smooth = value === \"1\" || value === \"on\";\n\t\t\t} else {\n\t\t\t\t// Handle null terminated files without exception\n\t\t\t\tif (line === \"\\0\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tmodelNode.error(\"Unexpected line: '\" + line + \"'\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\treturn state;\n\t};\n\n\tfunction getBasePath(src) {\n\t\tvar n = src.lastIndexOf(\"/\");\n\t\treturn n === -1 ? src : src.substring(0, n + 1);\n\t}\n\n\tfunction startObject(state, id, fromDeclaration) {\n\t\tif (state.object && state.object.fromDeclaration === false) {\n\t\t\tstate.object.id = id;\n\t\t\tstate.object.fromDeclaration = fromDeclaration !== false;\n\t\t\treturn;\n\t\t}\n\t\tstate.object = {\n\t\t\tid: id || \"\",\n\t\t\tgeometry: {\n\t\t\t\tpositions: [],\n\t\t\t\tnormals: [],\n\t\t\t\tuv: []\n\t\t\t},\n\t\t\tmaterial: {\n\t\t\t\tid: \"\",\n\t\t\t\tsmooth: true\n\t\t\t},\n\t\t\tfromDeclaration: fromDeclaration !== false\n\t\t};\n\t\tstate.objects.push(state.object);\n\t}\n\n\tfunction parseVertexIndex(value, len) {\n\t\tvar index = parseInt(value, 10);\n\t\treturn (index >= 0 ? index - 1 : index + len / 3) * 3;\n\t}\n\n\tfunction parseNormalIndex(value, len) {\n\t\tvar index = parseInt(value, 10);\n\t\treturn (index >= 0 ? index - 1 : index + len / 3) * 3;\n\t}\n\n\tfunction parseUVIndex(value, len) {\n\t\tvar index = parseInt(value, 10);\n\t\treturn (index >= 0 ? index - 1 : index + len / 2) * 2;\n\t}\n\n\tfunction addVertex(state, a, b, c) {\n\t\tvar src = state.positions;\n\t\tvar dst = state.object.geometry.positions;\n\t\tdst.push(src[a + 0]);\n\t\tdst.push(src[a + 1]);\n\t\tdst.push(src[a + 2]);\n\t\tdst.push(src[b + 0]);\n\t\tdst.push(src[b + 1]);\n\t\tdst.push(src[b + 2]);\n\t\tdst.push(src[c + 0]);\n\t\tdst.push(src[c + 1]);\n\t\tdst.push(src[c + 2]);\n\t}\n\n\tfunction addVertexLine(state, a) {\n\t\tvar src = state.positions;\n\t\tvar dst = state.object.geometry.positions;\n\t\tdst.push(src[a + 0]);\n\t\tdst.push(src[a + 1]);\n\t\tdst.push(src[a + 2]);\n\t}\n\n\tfunction addNormal(state, a, b, c) {\n\t\tvar src = state.normals;\n\t\tvar dst = state.object.geometry.normals;\n\t\tdst.push(src[a + 0]);\n\t\tdst.push(src[a + 1]);\n\t\tdst.push(src[a + 2]);\n\t\tdst.push(src[b + 0]);\n\t\tdst.push(src[b + 1]);\n\t\tdst.push(src[b + 2]);\n\t\tdst.push(src[c + 0]);\n\t\tdst.push(src[c + 1]);\n\t\tdst.push(src[c + 2]);\n\t}\n\n\tfunction addUV(state, a, b, c) {\n\t\tvar src = state.uv;\n\t\tvar dst = state.object.geometry.uv;\n\t\tdst.push(src[a + 0]);\n\t\tdst.push(src[a + 1]);\n\t\tdst.push(src[b + 0]);\n\t\tdst.push(src[b + 1]);\n\t\tdst.push(src[c + 0]);\n\t\tdst.push(src[c + 1]);\n\t}\n\n\tfunction addUVLine(state, a) {\n\t\tvar src = state.uv;\n\t\tvar dst = state.object.geometry.uv;\n\t\tdst.push(src[a + 0]);\n\t\tdst.push(src[a + 1]);\n\t}\n\n\tfunction addFace(state, a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd) {\n\t\tvar vLen = state.positions.length;\n\t\tvar ia = parseVertexIndex(a, vLen);\n\t\tvar ib = parseVertexIndex(b, vLen);\n\t\tvar ic = parseVertexIndex(c, vLen);\n\t\tvar id;\n\t\tif (d === undefined) {\n\t\t\taddVertex(state, ia, ib, ic);\n\t\t} else {\n\t\t\tid = parseVertexIndex(d, vLen);\n\t\t\taddVertex(state, ia, ib, id);\n\t\t\taddVertex(state, ib, ic, id);\n\t\t}\n\n\t\tif (ua !== undefined) {\n\t\t\tvar uvLen = state.uv.length;\n\n\t\t\tia = parseUVIndex(ua, uvLen);\n\t\t\tib = parseUVIndex(ub, uvLen);\n\t\t\tic = parseUVIndex(uc, uvLen);\n\n\t\t\tif (d === undefined) {\n\t\t\t\taddUV(state, ia, ib, ic);\n\t\t\t} else {\n\t\t\t\tid = parseUVIndex(ud, uvLen);\n\t\t\t\taddUV(state, ia, ib, id);\n\t\t\t\taddUV(state, ib, ic, id);\n\t\t\t}\n\t\t}\n\n\t\tif (na !== undefined) {\n\t\t\t// Normals are many times the same. If so, skip function call and parseInt.\n\n\t\t\tvar nLen = state.normals.length;\n\n\t\t\tia = parseNormalIndex(na, nLen);\n\t\t\tib = na === nb ? ia : parseNormalIndex(nb, nLen);\n\t\t\tic = na === nc ? ia : parseNormalIndex(nc, nLen);\n\n\t\t\tif (d === undefined) {\n\t\t\t\taddNormal(state, ia, ib, ic);\n\t\t\t} else {\n\t\t\t\tid = parseNormalIndex(nd, nLen);\n\t\t\t\taddNormal(state, ia, ib, id);\n\t\t\t\taddNormal(state, ib, ic, id);\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction addLineGeometry(state, positions, uv) {\n\t\tstate.object.geometry.type = \"Line\";\n\n\t\tvar vLen = state.positions.length;\n\t\tvar uvLen = state.uv.length;\n\n\t\tfor (var vi = 0, l = positions.length; vi < l; vi++) {\n\t\t\taddVertexLine(state, parseVertexIndex(positions[vi], vLen));\n\t\t}\n\n\t\tfor (var uvi = 0, uvl = uv.length; uvi < uvl; uvi++) {\n\t\t\taddUVLine(state, parseUVIndex(uv[uvi], uvLen));\n\t\t}\n\t}\n})();\n\n//--------------------------------------------------------------------------------------------\n// Loads MTL files listed in parsed state\n//--------------------------------------------------------------------------------------------\n\nfunction loadMTLs(modelNode, state, ok) {\n\tvar basePath = state.basePath;\n\tvar srcList = Object.keys(state.materialLibraries);\n\tvar numToLoad = srcList.length;\n\tfor (var i = 0, len = numToLoad; i < len; i++) {\n\t\tloadMTL(modelNode, basePath, basePath + srcList[i], function () {\n\t\t\tif (--numToLoad === 0) {\n\t\t\t\tok();\n\t\t\t}\n\t\t});\n\t}\n}\n\n//--------------------------------------------------------------------------------------------\n// Loads an MTL file\n//--------------------------------------------------------------------------------------------\n\nvar loadMTL = function (modelNode, basePath, src, ok) {\n\tloadFile(\n\t\tsrc,\n\t\tfunction (text) {\n\t\t\tparseMTL(modelNode, text, basePath);\n\t\t\tok();\n\t\t},\n\t\tfunction (error) {\n\t\t\tmodelNode.error(error);\n\t\t\tok();\n\t\t}\n\t);\n};\n\nvar parseMTL = (function () {\n\tvar delimiter_pattern = /\\s+/;\n\n\treturn function (modelNode, mtlText, basePath) {\n\t\tvar lines = mtlText.split(\"\\n\");\n\t\tvar materialCfg = {\n\t\t\tid: \"Default\"\n\t\t};\n\t\tvar needCreate = false;\n\t\tvar line;\n\t\tvar pos;\n\t\tvar key;\n\t\tvar value;\n\t\tvar alpha;\n\n\t\tbasePath = basePath || \"\";\n\n\t\tfor (var i = 0; i < lines.length; i++) {\n\t\t\tline = lines[i].trim();\n\n\t\t\tif (line.length === 0 || line.charAt(0) === \"#\") {\n\t\t\t\t// Blank line or comment ignore\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpos = line.indexOf(\" \");\n\n\t\t\tkey = pos >= 0 ? line.substring(0, pos) : line;\n\t\t\tkey = key.toLowerCase();\n\n\t\t\tvalue = pos >= 0 ? line.substring(pos + 1) : \"\";\n\t\t\tvalue = value.trim();\n\n\t\t\tswitch (key.toLowerCase()) {\n\t\t\t\tcase \"newmtl\": // New material\n\t\t\t\t\t//if (needCreate) {\n\t\t\t\t\tcreateMaterial(modelNode, materialCfg);\n\t\t\t\t\t//}\n\t\t\t\t\tmaterialCfg = {\n\t\t\t\t\t\tid: value\n\t\t\t\t\t};\n\t\t\t\t\tneedCreate = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"ka\":\n\t\t\t\t\tmaterialCfg.ambient = parseRGB(value);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"kd\":\n\t\t\t\t\tmaterialCfg.diffuse = parseRGB(value);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"ks\":\n\t\t\t\t\tmaterialCfg.specular = parseRGB(value);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"map_kd\":\n\t\t\t\t\tif (!materialCfg.diffuseMap) {\n\t\t\t\t\t\tmaterialCfg.diffuseMap = createTexture(modelNode, basePath, value, \"sRGB\");\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"map_ks\":\n\t\t\t\t\tif (!materialCfg.specularMap) {\n\t\t\t\t\t\tmaterialCfg.specularMap = createTexture(modelNode, basePath, value, \"linear\");\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"map_bump\":\n\t\t\t\tcase \"bump\":\n\t\t\t\t\tif (!materialCfg.normalMap) {\n\t\t\t\t\t\tmaterialCfg.normalMap = createTexture(modelNode, basePath, value);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"ns\":\n\t\t\t\t\tmaterialCfg.shininess = parseFloat(value);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"d\":\n\t\t\t\t\talpha = parseFloat(value);\n\t\t\t\t\tif (alpha < 1) {\n\t\t\t\t\t\tmaterialCfg.alpha = alpha;\n\t\t\t\t\t\tmaterialCfg.alphaMode = \"blend\";\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"tr\":\n\t\t\t\t\talpha = parseFloat(value);\n\t\t\t\t\tif (alpha > 0) {\n\t\t\t\t\t\tmaterialCfg.alpha = 1 - alpha;\n\t\t\t\t\t\tmaterialCfg.alphaMode = \"blend\";\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t// modelNode.error(\"Unrecognized token: \" + key);\n\t\t\t}\n\t\t}\n\n\t\tif (needCreate) {\n\t\t\tcreateMaterial(modelNode, materialCfg);\n\t\t}\n\t};\n\n\tfunction createTexture(modelNode, basePath, value, encoding) {\n\t\tvar textureCfg = {};\n\t\tvar items = value.split(/\\s+/);\n\t\tvar pos = items.indexOf(\"-bm\");\n\t\tif (pos >= 0) {\n\t\t\t//matParams.bumpScale = parseFloat(items[pos + 1]);\n\t\t\titems.splice(pos, 2);\n\t\t}\n\t\tpos = items.indexOf(\"-s\");\n\t\tif (pos >= 0) {\n\t\t\ttextureCfg.scale = [parseFloat(items[pos + 1]), parseFloat(items[pos + 2])];\n\t\t\titems.splice(pos, 4); // we expect 3 parameters here!\n\t\t}\n\t\tpos = items.indexOf(\"-o\");\n\t\tif (pos >= 0) {\n\t\t\ttextureCfg.translate = [parseFloat(items[pos + 1]), parseFloat(items[pos + 2])];\n\t\t\titems.splice(pos, 4); // we expect 3 parameters here!\n\t\t}\n\t\ttextureCfg.src = basePath + items.join(\" \").trim();\n\t\ttextureCfg.flipY = true;\n\t\ttextureCfg.encoding = encoding || \"linear\";\n\t\t//textureCfg.wrapS = self.wrap;\n\t\t//textureCfg.wrapT = self.wrap;\n\t\tvar texture = new _viewer_scene_materials_Texture_js__WEBPACK_IMPORTED_MODULE_3__.Texture(modelNode, textureCfg);\n\t\treturn texture.id;\n\t}\n\n\tfunction createMaterial(modelNode, materialCfg) {\n\t\tnew _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_2__.PhongMaterial(modelNode, materialCfg);\n\t}\n\n\tfunction parseRGB(value) {\n\t\tvar ss = value.split(delimiter_pattern, 3);\n\t\treturn [parseFloat(ss[0]), parseFloat(ss[1]), parseFloat(ss[2])];\n\t}\n})();\n//--------------------------------------------------------------------------------------------\n// Creates meshes from parsed state\n//--------------------------------------------------------------------------------------------\n\nfunction createMeshes(modelNode, state) {\n\tfor (var j = 0, k = state.objects.length; j < k; j++) {\n\t\tvar object = state.objects[j];\n\t\tvar geometry = object.geometry;\n\t\tvar isLine = geometry.type === \"Line\";\n\n\t\tif (geometry.positions.length === 0) {\n\t\t\t// Skip o/g line declarations that did not follow with any faces\n\t\t\tcontinue;\n\t\t}\n\n\t\tvar geometryCfg = {\n\t\t\tprimitive: \"triangles\",\n\t\t\tcompressGeometry: false\n\t\t};\n\n\t\tgeometryCfg.positions = geometry.positions;\n\n\t\tif (geometry.normals.length > 0) {\n\t\t\tgeometryCfg.normals = geometry.normals;\n\t\t}\n\n\t\tif (geometry.uv.length > 0) {\n\t\t\tgeometryCfg.uv = geometry.uv;\n\t\t}\n\n\t\tvar indices = new Array(geometryCfg.positions.length / 3); // Triangle soup\n\t\tfor (var idx = 0; idx < indices.length; idx++) {\n\t\t\tindices[idx] = idx;\n\t\t}\n\t\tgeometryCfg.indices = indices;\n\n\t\tconst origin = tempVec3a;\n\n\t\t(0,_viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__.worldToRTCPositions)(geometry.positions, geometry.positions, origin);\n\n\t\tvar readableGeometry = new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_1__.ReadableGeometry(modelNode, geometryCfg);\n\n\t\tvar materialId = object.material.id;\n\t\tvar material;\n\t\tif (materialId && materialId !== \"\") {\n\t\t\tmaterial = modelNode.scene.components[materialId];\n\t\t\tif (!material) {\n\t\t\t\t// modelNode.error(\"Material not found: \" + materialId);\n\t\t\t} else {\n\t\t\t\tmaterial = new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_2__.PhongMaterial(modelNode, {\n\t\t\t\t\temissive: [0.6, 0.6, 0.0],\n\t\t\t\t\tdiffuse: [0.6, 0.6, 0.6],\n\t\t\t\t\tspecular: [1.0, 1.0, 1.0],\n\t\t\t\t\tbackfaces: true\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tmaterial = new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_2__.PhongMaterial(modelNode, {\n\t\t\t\t//emissive: [0.6, 0.6, 0.0],\n\t\t\t\tdiffuse: [0.6, 0.6, 0.6],\n\t\t\t\tbackfaces: true\n\t\t\t});\n\t\t}\n\n\t\t// material.emissive = [Math.random(), Math.random(), Math.random()];\n\n\t\tvar mesh = new _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_0__.Mesh(modelNode, {\n\t\t\tid: modelNode.id + \"#\" + object.id,\n\t\t\torigin: origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0 ? origin : null,\n\t\t\tisObject: true,\n\t\t\tgeometry: readableGeometry,\n\t\t\tmaterial: material,\n\t\t\tpickable: true\n\t\t});\n\n\t\tmodelNode.addChild(mesh);\n\t}\n}\n\nfunction loadFile(url, ok, err) {\n\tvar request = new XMLHttpRequest();\n\trequest.open(\"GET\", url, true);\n\trequest.addEventListener(\n\t\t\"load\",\n\t\tfunction (event) {\n\t\t\tvar response = event.target.response;\n\t\t\tif (this.status === 200) {\n\t\t\t\tif (ok) {\n\t\t\t\t\tok(response);\n\t\t\t\t}\n\t\t\t} else if (this.status === 0) {\n\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\t\t\t\tconsole.warn(\"loadFile: HTTP Status 0 received.\");\n\t\t\t\tif (ok) {\n\t\t\t\t\tok(response);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (err) {\n\t\t\t\t\terr(event);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tfalse\n\t);\n\n\trequest.addEventListener(\n\t\t\"error\",\n\t\tfunction (event) {\n\t\t\tif (err) {\n\t\t\t\terr(event);\n\t\t\t}\n\t\t},\n\t\tfalse\n\t);\n\trequest.send(null);\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/OBJLoaderPlugin/OBJSceneGraphLoader.js?");
1828
1828
 
1829
1829
  /***/ }),
1830
1830
 
@@ -1878,6 +1878,16 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1878
1878
 
1879
1879
  /***/ }),
1880
1880
 
1881
+ /***/ "./src/plugins/SectionPlanesPlugin/Box.js":
1882
+ /*!************************************************!*\
1883
+ !*** ./src/plugins/SectionPlanesPlugin/Box.js ***!
1884
+ \************************************************/
1885
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1886
+
1887
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Box: () => (/* binding */ Box)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../viewer/scene/materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildBoxGeometry_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildBoxGeometry.js */ \"./src/viewer/scene/geometry/builders/buildBoxGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_EdgeMaterial_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../viewer/scene/materials/EdgeMaterial.js */ \"./src/viewer/scene/materials/EdgeMaterial.js\");\n/* harmony import */ var _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../viewer/scene/materials/EmphasisMaterial.js */ \"./src/viewer/scene/materials/EmphasisMaterial.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Renders a 3D plane within an {@link Overview} to indicate its {@link SectionPlane}'s current position and orientation.\r\n *\r\n * @private\r\n */\r\nclass Box {\r\n\t/** @private */\r\n\tconstructor(overview, overviewScene, sectionBox) {\r\n\t\t/**\r\n\t\t * The ID of this SectionPlanesOverviewPlane.\r\n\t\t *\r\n\t\t * @type {String}\r\n\t\t */\r\n\t\tthis.id = sectionPlane.id;\r\n\r\n\t\t/**\r\n\t\t * The {@link SectionPlane} represented by this SectionPlanesOverviewPlane.\r\n\t\t *\r\n\t\t * @type {SectionPlane}\r\n\t\t */\r\n\t\tthis._sectionBox = sectionBox;\r\n\r\n\t\tthis._mesh = new _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_1__.Mesh(overviewScene, {\r\n\t\t\tid: sectionPlane.id,\r\n\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_2__.ReadableGeometry(\r\n\t\t\t\toverviewScene,\r\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildBoxGeometry_js__WEBPACK_IMPORTED_MODULE_4__.buildBoxGeometry)({\r\n\t\t\t\t\txSize: 0.5,\r\n\t\t\t\t\tySize: 0.5,\r\n\t\t\t\t\tzSize: 0.001\r\n\t\t\t\t})\r\n\t\t\t),\r\n\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_3__.PhongMaterial(overviewScene, {\r\n\t\t\t\temissive: [1, 1, 1],\r\n\t\t\t\tdiffuse: [0, 0, 0],\r\n\t\t\t\tbackfaces: false\r\n\t\t\t}),\r\n\t\t\tedgeMaterial: new _viewer_scene_materials_EdgeMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EdgeMaterial(overviewScene, {\r\n\t\t\t\tedgeColor: [0.0, 0.0, 0.0],\r\n\t\t\t\tedgeAlpha: 1.0,\r\n\t\t\t\tedgeWidth: 1\r\n\t\t\t}),\r\n\t\t\thighlightMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_6__.EmphasisMaterial(overviewScene, {\r\n\t\t\t\tfill: true,\r\n\t\t\t\tfillColor: [0.5, 1, 0.5],\r\n\t\t\t\tfillAlpha: 0.7,\r\n\t\t\t\tedges: true,\r\n\t\t\t\tedgeColor: [0.0, 0.0, 0.0],\r\n\t\t\t\tedgeAlpha: 1.0,\r\n\t\t\t\tedgeWidth: 1\r\n\t\t\t}),\r\n\t\t\tselectedMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_6__.EmphasisMaterial(overviewScene, {\r\n\t\t\t\tfill: true,\r\n\t\t\t\tfillColor: [0, 0, 1],\r\n\t\t\t\tfillAlpha: 0.7,\r\n\t\t\t\tedges: true,\r\n\t\t\t\tedgeColor: [1.0, 0.0, 0.0],\r\n\t\t\t\tedgeAlpha: 1.0,\r\n\t\t\t\tedgeWidth: 1\r\n\t\t\t}),\r\n\t\t\thighlighted: true,\r\n\t\t\tscale: [3, 3, 3],\r\n\t\t\tposition: [0, 0, 0],\r\n\t\t\trotation: [0, 0, 0],\r\n\t\t\topacity: 0.3,\r\n\t\t\tedges: true\r\n\t\t});\r\n\r\n\t\t{\r\n\t\t\tconst vec = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 0]);\r\n\t\t\tconst pos2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\t\tconst zeroVec = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 1]);\r\n\t\t\tconst quat = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4(4);\r\n\t\t\tconst pos3 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n\t\t\tconst update = () => {\r\n\t\t\t\tconst origin = this._sectionBox.scene.center;\r\n\r\n\t\t\t\tconst negDir = [-this._sectionBox.dir[0], -this._sectionBox.dir[1], -this._sectionBox.dir[2]];\r\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(origin, this._sectionBox.pos, vec);\r\n\t\t\t\tconst dist = -_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(negDir, vec);\r\n\r\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(negDir);\r\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(negDir, dist, pos2);\r\n\t\t\t\tconst quaternion = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3PairToQuaternion(zeroVec, this._sectionBox.dir, quat);\r\n\r\n\t\t\t\tpos3[0] = pos2[0] * 0.1;\r\n\t\t\t\tpos3[1] = pos2[1] * 0.1;\r\n\t\t\t\tpos3[2] = pos2[2] * 0.1;\r\n\r\n\t\t\t\tthis._mesh.quaternion = quaternion;\r\n\t\t\t\tthis._mesh.position = pos3;\r\n\t\t\t};\r\n\r\n\t\t\tthis._onSectionPlanePos = this._sectionBox.on(\"pos\", update);\r\n\t\t\tthis._onSectionPlaneDir = this._sectionBox.on(\"dir\", update);\r\n\r\n\t\t\t// update();\r\n\t\t}\r\n\r\n\t\tthis._highlighted = false;\r\n\t\tthis._selected = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if this SectionPlanesOverviewPlane is highlighted.\r\n\t *\r\n\t * @type {Boolean}\r\n\t * @private\r\n\t */\r\n\tsetHighlighted(highlighted) {\r\n\t\tthis._highlighted = !!highlighted;\r\n\t\tthis._mesh.highlighted = this._highlighted;\r\n\t\tthis._mesh.highlightMaterial.fillColor = highlighted ? [0, 0.7, 0] : [0, 0, 0];\r\n\t\t// this._selectedMesh.highlighted = true;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if this SectionPlanesOverviewPlane is highlighted.\r\n\t *\r\n\t * @type {Boolean}\r\n\t * @private\r\n\t */\r\n\tgetHighlighted() {\r\n\t\treturn this._highlighted;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if this SectionPlanesOverviewPlane is selected.\r\n\t *\r\n\t * @type {Boolean}\r\n\t * @private\r\n\t */\r\n\tsetSelected(selected) {\r\n\t\tthis._selected = !!selected;\r\n\t\tthis._mesh.edgeMaterial.edgeWidth = selected ? 3 : 1;\r\n\t\tthis._mesh.highlightMaterial.edgeWidth = selected ? 3 : 1;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if this SectionPlanesOverviewPlane is selected.\r\n\t *\r\n\t * @type {Boolean}\r\n\t * @private\r\n\t */\r\n\tgetSelected() {\r\n\t\treturn this._selected;\r\n\t}\r\n\r\n\t/** @private */\r\n\tdestroy() {\r\n\t\tthis._sectionBox.off(this._onSectionPlanePos);\r\n\t\tthis._sectionBox.off(this._onSectionPlaneDir);\r\n\t\tthis._mesh.destroy();\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SectionPlanesPlugin/Box.js?");
1888
+
1889
+ /***/ }),
1890
+
1881
1891
  /***/ "./src/plugins/SectionPlanesPlugin/ClippingBox.js":
1882
1892
  /*!********************************************************!*\
1883
1893
  !*** ./src/plugins/SectionPlanesPlugin/ClippingBox.js ***!
@@ -1894,7 +1904,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1894
1904
  \**********************************************************/
1895
1905
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1896
1906
 
1897
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ClippingPlane: () => (/* binding */ ClippingPlane)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildCylinderGeometry.js */ \"./src/viewer/scene/geometry/builders/buildCylinderGeometry.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildTorusGeometry.js */ \"./src/viewer/scene/geometry/builders/buildTorusGeometry.js\");\n/* harmony import */ var _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../viewer/scene/geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../viewer/scene/materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../viewer/scene/materials/EmphasisMaterial.js */ \"./src/viewer/scene/materials/EmphasisMaterial.js\");\n/* harmony import */ var _viewer_scene_nodes_Node_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../viewer/scene/nodes/Node.js */ \"./src/viewer/scene/nodes/Node.js\");\n/* harmony import */ var _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../viewer/scene/mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildSphereGeometry.js */ \"./src/viewer/scene/geometry/builders/buildSphereGeometry.js\");\n/* harmony import */ var _viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../viewer/scene/math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst zeroVec = new Float64Array([0, 0, 1]);\nconst quat = new Float64Array(4);\n\n/**\n * Controls a {@link SectionPlane} with mouse and touch input.\n *\n * @private\n */\nclass ClippingPlane {\n\t/** @private */\n\tconstructor(plugin, cfg) {\n\t\t/**\n\t\t * ID of this Control.\n\t\t *\n\t\t * SectionPlaneControls are mapped by this ID in {@link SectionPlanesPlugin#sectionPlaneControls}.\n\t\t *\n\t\t * @property id\n\t\t * @type {String|Number}\n\t\t */\n\t\tthis.id = null;\n\t\tthis.type = \"plane\";\n\n\t\tthis._viewer = plugin.viewer;\n\t\tthis._scene = plugin.viewer.scene;\n\n\t\tthis._controlFillColor = !!cfg && !!cfg.controlFillColor ? cfg.controlFillColor : [0.1, 0.4, 0.99];\n\t\tthis._planeSize = !!cfg && !!cfg.planeSize ? cfg.planeSize : 1;\n\t\tthis._controlSize = !!cfg && !!cfg.controlSize ? cfg.controlSize : 0.07;\n\t\tthis._planeOpacity = !!cfg && !!cfg.planeOpacity ? cfg.planeOpacity : 0.4;\n\n\t\tthis._visible = false;\n\t\tthis._pos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3(); // Full-precision position of the center of the Control\n\t\tthis._origin = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\tthis._rtcPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\n\t\tthis._baseDir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3(); // Saves direction of clip plane when we start dragging an arrow or ring.\n\t\tthis._rootNode = null; // Root of Node graph that represents this control in the 3D scene\n\t\tthis._displayMeshes = null; // Meshes that are always visible\n\t\tthis._affordanceMeshes = null; // Meshes displayed momentarily for affordance\n\n\t\tthis._ignoreNextSectionPlaneDirUpdate = false;\n\n\t\tthis._createNodes();\n\t\tthis._bindEvents();\n\t}\n\n\t/**\n\t * Builds the Entities that represent this Control.\n\t * @private\n\t */\n\t_createNodes() {\n\t\tconst NO_STATE_INHERIT = false;\n\t\tconst scene = this._viewer.scene;\n\n\t\tthis._rootNode = new _viewer_scene_nodes_Node_js__WEBPACK_IMPORTED_MODULE_6__.Node(scene, {\n\t\t\tposition: [0, 0, 0],\n\t\t\tscale: [5, 5, 5],\n\t\t\tisObject: false\n\t\t});\n\n\t\tconst rootNode = this._rootNode;\n\n\t\tthis._displayMeshes = {\n\t\t\tplane: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(rootNode, {\n\t\t\t\t\t\tprimitive: \"triangles\",\n\t\t\t\t\t\tpositions: [\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.0,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.0, // 0\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.0,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.0, // 1\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.0,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.0, // 2\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.0,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.0 // 3\n\t\t\t\t\t\t],\n\t\t\t\t\t\tindices: [0, 1, 2, 2, 3, 0]\n\t\t\t\t\t}),\n\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t\t\temissive: [0, 0, 0],\n\t\t\t\t\t\tdiffuse: this._controlFillColor,\n\t\t\t\t\t\tbackfaces: true\n\t\t\t\t\t}),\n\t\t\t\t\topacity: this._planeOpacity,\n\t\t\t\t\tghosted: true,\n\t\t\t\t\tghostMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t\t\tedges: false,\n\t\t\t\t\t\tfilled: true,\n\t\t\t\t\t\tfillColor: this._controlFillColor ? this._controlFillColor : [0.1, 0.4, 0.99],\n\t\t\t\t\t\tfillAlpha: 0.1,\n\t\t\t\t\t\tbackfaces: true\n\t\t\t\t\t}),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tscale: [2.4 * this._planeSize, 2.4 * this._planeSize, 1 * this._planeSize],\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t)\n\t\t};\n\n\t\tthis._affordanceMeshes = {\n\t\t\t// plane: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\tgeometry: new ReadableGeometry(rootNode, {\n\t\t\t// \t\t\tprimitive: \"triangles\",\n\t\t\t// \t\t\tpositions: [\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t0.0,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t0.0, // 0\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t0.0,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t0.0, // 1\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t-0.0,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t-0.0, // 2\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t-0.0,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t-0.0 // 3\n\t\t\t// \t\t\t],\n\t\t\t// \t\t\tindices: [0, 1, 2, 2, 3, 0]\n\t\t\t// \t\t}),\n\t\t\t// \t\tmaterial: new PhongMaterial(rootNode, {\n\t\t\t// \t\t\temissive: [0, 0, 0],\n\t\t\t// \t\t\tdiffuse: this._controlFillColor,\n\t\t\t// \t\t\tbackfaces: true\n\t\t\t// \t\t}),\n\t\t\t// \t\topacity: this._planeOpacity,\n\t\t\t// \t\tghosted: true,\n\t\t\t// \t\tghostMaterial: new EmphasisMaterial(rootNode, {\n\t\t\t// \t\t\tedges: false,\n\t\t\t// \t\t\tfilled: true,\n\t\t\t// \t\t\tfillColor: this._controlFillColor,\n\t\t\t// \t\t\tfillAlpha: 0.1,\n\t\t\t// \t\t\tbackfaces: true\n\t\t\t// \t\t}),\n\t\t\t// \t\tpickable: true,\n\t\t\t// \t\tcollidable: true,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tscale: [2.4 * this._planeSize, 2.4 * this._planeSize, 1 * this._planeSize],\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// )\n\t\t};\n\t}\n\n\t/**\n\t * Called by SectionPlanesPlugin to assign this Control to a SectionPlane.\n\t * SectionPlanesPlugin keeps SectionPlaneControls in a reuse pool.\n\t * Call with a null or undefined value to disconnect the Control ffrom whatever SectionPlane it was assigned to.\n\t * @private\n\t */\n\t_setSectionPlane(sectionPlane) {\n\t\tif (this._sectionPlane) {\n\t\t\tthis._sectionPlane.off(this._onSectionPlanePos);\n\t\t\tthis._sectionPlane.off(this._onSectionPlaneDir);\n\t\t\tthis._onSectionPlanePos = null;\n\t\t\tthis._onSectionPlaneDir = null;\n\t\t\tthis._sectionPlane = null;\n\t\t}\n\t\tif (sectionPlane) {\n\t\t\tthis.id = sectionPlane.id;\n\t\t\tthis._setPos(sectionPlane.pos);\n\t\t\tthis._setDir(sectionPlane.dir);\n\t\t\tthis._sectionPlane = sectionPlane;\n\t\t\tsectionPlane.control = this;\n\t\t\tthis._onSectionPlanePos = sectionPlane.on(\"pos\", () => {\n\t\t\t\tthis._setPos(this._sectionPlane.pos);\n\t\t\t});\n\t\t\tthis._onSectionPlaneDir = sectionPlane.on(\"dir\", () => {\n\t\t\t\tif (!this._ignoreNextSectionPlaneDirUpdate) {\n\t\t\t\t\tthis._setDir(this._sectionPlane.dir);\n\t\t\t\t} else {\n\t\t\t\t\tthis._ignoreNextSectionPlaneDirUpdate = false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Gets the {@link SectionPlane} controlled by this Control.\n\t * @returns {SectionPlane} The SectionPlane.\n\t */\n\tget sectionPlane() {\n\t\treturn this._sectionPlane;\n\t}\n\n\t/**\n\t * 设置剖切面位置\n\t * @param {any} value\n\t */\n\tset pos(posRate) {\n\t\tif (posRate < 0 || posRate > 100) return;\n\n\t\tconst { aabb } = this._scene;\n\t\tconst { look } = this._scene.camera;\n\t\tconst xRange = aabb[3] - aabb[0]; //前后\n\t\tconst yRange = aabb[4] - aabb[1]; //上下\n\t\tconst zRange = aabb[5] - aabb[2]; //左右\n\n\t\tconst newSectionPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\tnewSectionPos[0] = this.pos[0];\n\t\tnewSectionPos[1] = this.pos[1];\n\t\tnewSectionPos[2] = this.pos[2];\n\n\t\tconst { dir } = this._sectionPlane;\n\t\tlet rateDis;\n\t\tif (dir[0] != 0) {\n\t\t\trateDis = (posRate / 100) * xRange;\n\t\t\tnewSectionPos[0] = look[0] - xRange / 2 + rateDis; // console.log(\"xRange\", rateDis, rateDis + aabb[0]);\n\t\t} else if (dir[1] != 0) {\n\t\t\trateDis = (posRate / 100) * yRange;\n\t\t\tnewSectionPos[1] = look[1] - yRange / 2 + rateDis; // console.log(\"yRange\", rateDis, rateDis + aabb[1]);\n\t\t} else if (dir[2] != 0) {\n\t\t\trateDis = (posRate / 100) * zRange;\n\t\t\tnewSectionPos[2] = look[2] - zRange / 2 + rateDis; // console.log(\"zRange\", rateDis, rateDis + aabb[2]);\n\t\t}\n\n\t\tthis._sectionPlane.pos = newSectionPos;\n\t}\n\n\tget pos() {\n\t\treturn this._pos;\n\t}\n\n\t/** @private */\n\t_setPos(xyz) {\n\t\tthis._pos.set(xyz);\n\t\t(0,_viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_9__.worldToRTCPos)(this._pos, this._origin, this._rtcPos);\n\t\tthis._rootNode.origin = this._origin;\n\t\tthis._rootNode.position = this._rtcPos;\n\t}\n\n\t/** @private */\n\t_setDir(xyz) {\n\t\tthis._baseDir.set(xyz);\n\t\tthis._rootNode.quaternion = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3PairToQuaternion(zeroVec, xyz, quat);\n\t}\n\n\t_setSectionPlaneDir(dir) {\n\t\tif (this._sectionPlane) {\n\t\t\tthis._ignoreNextSectionPlaneDirUpdate = true;\n\t\t\tthis._sectionPlane.dir = dir;\n\t\t}\n\t}\n\n\t/**\n\t * Sets if this Control is visible.\n\t *\n\t * @type {Boolean}\n\t */\n\tsetVisible(visible = true) {\n\t\tif (this._visible === visible) {\n\t\t\treturn;\n\t\t}\n\t\tthis._visible = visible;\n\t\tvar id;\n\t\tfor (id in this._displayMeshes) {\n\t\t\tif (this._displayMeshes.hasOwnProperty(id)) {\n\t\t\t\tthis._displayMeshes[id].visible = visible;\n\t\t\t}\n\t\t}\n\t\tif (!visible) {\n\t\t\tfor (id in this._affordanceMeshes) {\n\t\t\t\tif (this._affordanceMeshes.hasOwnProperty(id)) {\n\t\t\t\t\tthis._affordanceMeshes[id].visible = visible;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets if this Control is visible.\n\t *\n\t * @type {Boolean}\n\t */\n\tgetVisible() {\n\t\treturn this._visible;\n\t}\n\n\t/**\n\t * Sets if this Control is culled. This is called by SectionPlanesPlugin to\n\t * temporarily hide the Control while a snapshot is being taken by Viewer#getSnapshot().\n\t * @param culled\n\t */\n\tsetCulled(culled) {\n\t\tvar id;\n\t\tfor (id in this._displayMeshes) {\n\t\t\tif (this._displayMeshes.hasOwnProperty(id)) {\n\t\t\t\tthis._displayMeshes[id].culled = culled;\n\t\t\t}\n\t\t}\n\t\tif (!culled) {\n\t\t\tfor (id in this._affordanceMeshes) {\n\t\t\t\tif (this._affordanceMeshes.hasOwnProperty(id)) {\n\t\t\t\t\tthis._affordanceMeshes[id].culled = culled;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t_bindEvents() {\n\t\tconst self = this;\n\n\t\tvar grabbed = false;\n\n\t\tconst DRAG_ACTIONS = {\n\t\t\tnone: -1,\n\t\t\txTranslate: 0,\n\t\t\tyTranslate: 1,\n\t\t\tzTranslate: 2,\n\t\t\txRotate: 3,\n\t\t\tyRotate: 4,\n\t\t\tzRotate: 5\n\t\t};\n\n\t\tconst rootNode = this._rootNode;\n\n\t\tvar nextDragAction = null; // As we hover grabbed an arrow or hoop, self is the action we would do if we then dragged it.\n\t\tvar dragAction = null; // Action we're doing while we drag an arrow or hoop.\n\t\tconst lastCanvasPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec2();\n\t\tthis.lastCanvasPos = lastCanvasPos;\n\t\tconst xBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([1, 0, 0]);\n\t\tconst yBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 1, 0]);\n\t\tconst zBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 1]);\n\n\t\tconst canvas = this._viewer.scene.canvas.canvas;\n\t\tconst camera = this._viewer.camera;\n\t\tconst scene = this._viewer.scene;\n\n\t\t{\n\t\t\t// Keep gizmo screen size constant\n\n\t\t\tconst tempVec3a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 0]);\n\n\t\t\tlet distDirty = true;\n\t\t\tlet lastDist = -1;\n\n\t\t\tthis._onCameraViewMatrix = scene.camera.on(\"viewMatrix\", () => {\n\t\t\t\tdistDirty = true;\n\t\t\t});\n\n\t\t\tthis._onCameraProjMatrix = scene.camera.on(\"projMatrix\", () => {\n\t\t\t\tdistDirty = true;\n\t\t\t});\n\n\t\t\tthis._onSceneTick = scene.on(\"tick\", () => {\n\t\t\t\tconst dist = Math.abs(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(scene.camera.eye, this._pos, tempVec3a)));\n\n\t\t\t\tif (dist !== lastDist) {\n\t\t\t\t\tif (camera.projection === \"perspective\") {\n\t\t\t\t\t\tconst worldSize = Math.tan(camera.perspective.fov * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD) * dist;\n\t\t\t\t\t\t// const size = this._controlSize * worldSize;\n\t\t\t\t\t\t// rootNode.scale = [size, size, size];\n\t\t\t\t\t\tlastDist = dist;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (camera.projection === \"ortho\") {\n\t\t\t\t\tconst worldSize = camera.ortho.scale / 10;\n\t\t\t\t\t// const size = worldSize;\n\t\t\t\t\t// rootNode.scale = [size, size, size];\n\t\t\t\t\tlastDist = dist;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tconst getClickCoordsWithinElement = (function () {\n\t\t\tconst canvasPos = new Float64Array(2);\n\t\t\treturn function (event) {\n\t\t\t\tif (!event) {\n\t\t\t\t\tevent = window.event;\n\t\t\t\t\tcanvasPos[0] = event.x;\n\t\t\t\t\tcanvasPos[1] = event.y;\n\t\t\t\t} else {\n\t\t\t\t\tvar element = event.target;\n\t\t\t\t\tvar totalOffsetLeft = 0;\n\t\t\t\t\tvar totalOffsetTop = 0;\n\n\t\t\t\t\twhile (element.offsetParent) {\n\t\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\n\t\t\t\t\t\ttotalOffsetTop += element.offsetTop;\n\t\t\t\t\t\telement = element.offsetParent;\n\t\t\t\t\t}\n\t\t\t\t\tcanvasPos[0] = event.pageX - totalOffsetLeft;\n\t\t\t\t\tcanvasPos[1] = event.pageY - totalOffsetTop;\n\t\t\t\t}\n\t\t\t\treturn canvasPos;\n\t\t\t};\n\t\t})();\n\n\t\tconst getTouchCoordsWithinElement = (function () {\n\t\t\tconst canvasPos = new Float64Array(2);\n\t\t\treturn function (event) {\n\t\t\t\tif (!event) {\n\t\t\t\t\tevent = window.event;\n\t\t\t\t}\n\t\t\t\tif (event.touches && event.touches.length) {\n\t\t\t\t\t// 如果有触摸事件,使用第一个触摸点的坐标\n\t\t\t\t\tcanvasPos[0] = event.touches[0].pageX;\n\t\t\t\t\tcanvasPos[1] = event.touches[0].pageY;\n\t\t\t\t} else {\n\t\t\t\t\t// 否则,假设是鼠标事件\n\t\t\t\t\tvar element = event.target;\n\t\t\t\t\tvar totalOffsetLeft = 0;\n\t\t\t\t\tvar totalOffsetTop = 0;\n\n\t\t\t\t\twhile (element.offsetParent) {\n\t\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\n\t\t\t\t\t\ttotalOffsetTop += element.offsetTop;\n\t\t\t\t\t\telement = element.offsetParent;\n\t\t\t\t\t}\n\t\t\t\t\tcanvasPos[0] = event.pageX - totalOffsetLeft;\n\t\t\t\t\tcanvasPos[1] = event.pageY - totalOffsetTop;\n\t\t\t\t}\n\t\t\t\treturn canvasPos;\n\t\t\t};\n\t\t})();\n\n\t\t//转换为世界坐标\n\t\tconst localToWorldVec = (function () {\n\t\t\tconst mat = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function (localVec, worldVec) {\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.quaternionToMat4(self._rootNode.quaternion, mat);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(mat, localVec, worldVec);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(worldVec);\n\t\t\t\treturn worldVec;\n\t\t\t};\n\t\t})();\n\n\t\tvar getTranslationPlane = (function () {\n\t\t\tconst planeNormal = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\treturn function (worldAxis) {\n\t\t\t\tconst absX = Math.abs(worldAxis[0]);\n\t\t\t\tif (absX > Math.abs(worldAxis[1]) && absX > Math.abs(worldAxis[2])) {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(worldAxis, [0, 1, 0], planeNormal);\n\t\t\t\t} else {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(worldAxis, [1, 0, 0], planeNormal);\n\t\t\t\t}\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(planeNormal, worldAxis, planeNormal);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(planeNormal);\n\t\t\t\treturn planeNormal;\n\t\t\t};\n\t\t})();\n\n\t\t//拖拽平面\n\t\tconst dragTranslateSectionPlane = (function () {\n\t\t\tconst p1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst p2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst worldAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\treturn function (baseAxis, fromMouse, toMouse) {\n\t\t\t\tlocalToWorldVec(baseAxis, worldAxis);\n\t\t\t\tconst planeNormal = getTranslationPlane(worldAxis, fromMouse, toMouse);\n\t\t\t\tgetPointerPlaneIntersect(fromMouse, planeNormal, p1);\n\t\t\t\tgetPointerPlaneIntersect(toMouse, planeNormal, p2);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(p2, p1);\n\t\t\t\tconst dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p2, worldAxis);\n\t\t\t\tself._pos[0] += worldAxis[0] * dot;\n\t\t\t\tself._pos[1] += worldAxis[1] * dot;\n\t\t\t\tself._pos[2] += worldAxis[2] * dot;\n\t\t\t\tself._rootNode.position = self._pos;\n\t\t\t\tif (self._sectionPlane) {\n\t\t\t\t\tself._sectionPlane.pos = self._pos;\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\n\t\tvar getPointerPlaneIntersect = (function () {\n\t\t\tconst dir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4([0, 0, 0, 1]);\n\t\t\tconst matrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function (mouse, axis, dest, offset) {\n\t\t\t\toffset = offset || 0;\n\t\t\t\tdir[0] = (mouse[0] / canvas.width) * 2.0 - 1.0;\n\t\t\t\tdir[1] = -((mouse[1] / canvas.height) * 2.0 - 1.0);\n\t\t\t\tdir[2] = 0.0;\n\t\t\t\tdir[3] = 1.0;\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(camera.projMatrix, camera.viewMatrix, matrix); // Unproject norm device coords to view coords\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(matrix);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec4(matrix, dir, dir);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec4Scalar(dir, 1.0 / dir[3]); // This is now point A on the ray in world space\n\t\t\t\tvar rayO = camera.eye; // The direction\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec4(dir, rayO, dir);\n\t\t\t\tconst origin = self._sectionPlane.pos; // Plane origin:\n\t\t\t\tvar d = -_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(origin, axis) - offset;\n\t\t\t\tvar dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(axis, dir);\n\t\t\t\tif (Math.abs(dot) > 0.005) {\n\t\t\t\t\tvar t = -(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(axis, rayO) + d) / dot;\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(dir, t, dest);\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(dest, rayO);\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(dest, origin, dest);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t};\n\t\t})();\n\n\t\t{\n\t\t\tvar mouseDownLeft;\n\t\t\tvar mouseDownMiddle;\n\t\t\tvar mouseDownRight;\n\t\t\tvar down = false;\n\t\t\t// var lastAffordanceMesh;\n\n\t\t\tthis._onCameraControlHover = this._viewer.cameraControl.on(\"hoverEnter\", (hit) => {\n\t\t\t\tif (!this._visible) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (down) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tgrabbed = false;\n\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t// \tlastAffordanceMesh.visible = false;\n\t\t\t\t// }\n\t\t\t\t// var affordanceMesh;\n\t\t\t\tconst meshId = hit.entity.id;\n\t\t\t\tswitch (meshId) {\n\t\t\t\t\tcase this._displayMeshes.plane.id:\n\t\t\t\t\t\t// affordanceMesh = this._affordanceMeshes.plane;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\t\treturn; // Not clicked an arrow or hoop\n\t\t\t\t}\n\t\t\t\t// if (affordanceMesh) {\n\t\t\t\t// \taffordanceMesh.visible = true;\n\t\t\t\t// }\n\t\t\t\t// lastAffordanceMesh = affordanceMesh;\n\t\t\t\tgrabbed = true;\n\t\t\t});\n\n\t\t\tthis._onCameraControlHoverLeave = this._viewer.cameraControl.on(\"hoverOutEntity\", (hit) => {\n\t\t\t\tif (!this._visible) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t// \tlastAffordanceMesh.visible = false;\n\t\t\t\t// }\n\t\t\t\t// lastAffordanceMesh = null;\n\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t});\n\n\t\t\t//mousedown\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mousedown\",\n\t\t\t\t(this._canvasMouseDownListener = (e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (!this._visible || !grabbed) return;\n\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = false;\n\t\t\t\t\tswitch (e.which) {\n\t\t\t\t\t\tcase 1: // Left button\n\t\t\t\t\t\t\tmouseDownLeft = true;\n\t\t\t\t\t\t\tdown = true;\n\t\t\t\t\t\t\tvar canvasPos = getClickCoordsWithinElement(e); //获取鼠标点击对应坐标\n\t\t\t\t\t\t\tdragAction = nextDragAction;\n\t\t\t\t\t\t\tlastCanvasPos[0] = canvasPos[0];\n\t\t\t\t\t\t\tlastCanvasPos[1] = canvasPos[1];\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t);\n\t\t\t//mousemove\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mousemove\",\n\t\t\t\t(this._canvasMouseMoveListener = (e) => {\n\t\t\t\t\tif (!this._visible) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!down) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar canvasPos = getClickCoordsWithinElement(e);\n\t\t\t\t\tconst x = canvasPos[0];\n\t\t\t\t\tconst y = canvasPos[1];\n\n\t\t\t\t\tswitch (dragAction) {\n\t\t\t\t\t\tcase DRAG_ACTIONS.xTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlastCanvasPos[0] = x;\n\t\t\t\t\tlastCanvasPos[1] = y;\n\t\t\t\t})\n\t\t\t);\n\t\t\t//mouseup\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mouseup\",\n\t\t\t\t(this._canvasMouseUpListener = (e) => {\n\t\t\t\t\tif (!this._visible) return;\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = true;\n\t\t\t\t\tif (!down) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tswitch (e.which) {\n\t\t\t\t\t\tcase 1: // Left button\n\t\t\t\t\t\t\tmouseDownLeft = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 2: // Middle/both buttons\n\t\t\t\t\t\t\tmouseDownMiddle = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 3: // Right button\n\t\t\t\t\t\t\tmouseDownRight = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdown = false;\n\t\t\t\t\tgrabbed = false;\n\t\t\t\t})\n\t\t\t);\n\n\t\t\t//wheel\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"wheel\",\n\t\t\t\t(this._canvasWheelListener = (e) => {\n\t\t\t\t\tif (!this._visible) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar delta = Math.max(-1, Math.min(1, -e.deltaY * 40));\n\t\t\t\t\tif (delta === 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t);\n\n\t\t\tthis._onCameraControlHover = this._viewer.cameraControl.on(\"touchEntity\", (hit) => {\n\t\t\t\tif (!this._visible || down || grabbed) return;\n\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t// \tlastAffordanceMesh.visible = false;\n\t\t\t\t// }\n\t\t\t\tvar affordanceMesh;\n\t\t\t\tconst meshId = hit.entity.id;\n\t\t\t\tswitch (meshId) {\n\t\t\t\t\tcase this._displayMeshes.plane.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.plane;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\t\treturn; // Not clicked an arrow or hoop\n\t\t\t\t}\n\t\t\t\tif (affordanceMesh) {\n\t\t\t\t\taffordanceMesh.visible = true;\n\t\t\t\t}\n\t\t\t\t// lastAffordanceMesh = affordanceMesh;\n\t\t\t\tgrabbed = true;\n\t\t\t\tdown = true;\n\t\t\t});\n\t\t\t//touchstart\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchstart\",\n\t\t\t\t(this._canvasMouseDownListener = (e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (!this._visible || !grabbed || !down) return;\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = false;\n\t\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t\t// \tlastAffordanceMesh.visible = true;\n\t\t\t\t\t// }\n\t\t\t\t\tvar canvasPos = getTouchCoordsWithinElement(e);\n\t\t\t\t\tdragAction = nextDragAction;\n\t\t\t\t\tlastCanvasPos[0] = canvasPos[0];\n\t\t\t\t\tlastCanvasPos[1] = canvasPos[1];\n\t\t\t\t})\n\t\t\t);\n\t\t\t//touchmove\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchmove\",\n\t\t\t\t(this._canvasMouseMoveListener = (e) => {\n\t\t\t\t\tif (!this._visible || !down || !grabbed) return;\n\n\t\t\t\t\tvar canvasPos = getTouchCoordsWithinElement(e);\n\t\t\t\t\tconst x = canvasPos[0];\n\t\t\t\t\tconst y = canvasPos[1];\n\n\t\t\t\t\tswitch (dragAction) {\n\t\t\t\t\t\tcase DRAG_ACTIONS.xTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlastCanvasPos[0] = x;\n\t\t\t\t\tlastCanvasPos[1] = y;\n\t\t\t\t})\n\t\t\t);\n\t\t\t//touchend\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchend\",\n\t\t\t\t(this._canvasTouchEndListener = (e) => {\n\t\t\t\t\tif (!this._visible) return;\n\t\t\t\t\tif (grabbed) this._viewer.cameraControl.pointerEnabled = true;\n\t\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t\t// \tlastAffordanceMesh.visible = false;\n\t\t\t\t\t// }\n\t\t\t\t\t// lastAffordanceMesh = null;\n\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\tdown = false;\n\t\t\t\t\tgrabbed = false;\n\t\t\t\t})\n\t\t\t);\n\t\t\tcanvas.addEventListener(\"touchcancel\", this._canvasTouchEndListener);\n\t\t}\n\t}\n\n\t_destroy() {\n\t\tthis._unbindEvents();\n\t\tthis._destroyNodes();\n\t}\n\n\t_unbindEvents() {\n\t\tconst viewer = this._viewer;\n\t\tconst scene = viewer.scene;\n\t\tconst canvas = scene.canvas.canvas;\n\t\tconst camera = viewer.camera;\n\t\tconst cameraControl = viewer.cameraControl;\n\n\t\tscene.off(this._onSceneTick);\n\n\t\tcanvas.removeEventListener(\"mousedown\", this._canvasMouseDownListener);\n\t\tcanvas.removeEventListener(\"mousemove\", this._canvasMouseMoveListener);\n\t\tcanvas.removeEventListener(\"mouseup\", this._canvasMouseUpListener);\n\t\tcanvas.removeEventListener(\"wheel\", this._canvasWheelListener);\n\t\tcanvas.removeEventListener(\"touchend\", this._canvasTouchEndListener);\n\t\tcanvas.removeEventListener(\"touchcancel\", this._canvasTouchEndListener);\n\n\t\tcamera.off(this._onCameraViewMatrix);\n\t\tcamera.off(this._onCameraProjMatrix);\n\n\t\tcameraControl.off(this._onCameraControlHover);\n\t\tcameraControl.off(this._onCameraControlHoverLeave);\n\t}\n\n\t_destroyNodes() {\n\t\tthis._setSectionPlane(null);\n\t\tthis._rootNode.destroy();\n\t\tthis._displayMeshes = {};\n\t\tthis._affordanceMeshes = {};\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SectionPlanesPlugin/ClippingPlane.js?");
1907
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ClippingPlane: () => (/* binding */ ClippingPlane)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildCylinderGeometry.js */ \"./src/viewer/scene/geometry/builders/buildCylinderGeometry.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildTorusGeometry.js */ \"./src/viewer/scene/geometry/builders/buildTorusGeometry.js\");\n/* harmony import */ var _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../viewer/scene/geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../viewer/scene/materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../viewer/scene/materials/EmphasisMaterial.js */ \"./src/viewer/scene/materials/EmphasisMaterial.js\");\n/* harmony import */ var _viewer_scene_nodes_Node_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../viewer/scene/nodes/Node.js */ \"./src/viewer/scene/nodes/Node.js\");\n/* harmony import */ var _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../viewer/scene/mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildSphereGeometry.js */ \"./src/viewer/scene/geometry/builders/buildSphereGeometry.js\");\n/* harmony import */ var _viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../viewer/scene/math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst zeroVec = new Float64Array([0, 0, 1]);\nconst quat = new Float64Array(4);\n\n/**\n * Controls a {@link SectionPlane} with mouse and touch input.\n *\n * @private\n */\nclass ClippingPlane {\n\t/** @private */\n\tconstructor(plugin, cfg) {\n\t\t/**\n\t\t * ID of this Control.\n\t\t *\n\t\t * SectionPlaneControls are mapped by this ID in {@link SectionPlanesPlugin#sectionPlaneControls}.\n\t\t *\n\t\t * @property id\n\t\t * @type {String|Number}\n\t\t */\n\t\tthis.id = null;\n\t\tthis.type = \"plane\";\n\n\t\tthis._viewer = plugin.viewer;\n\t\tthis._scene = plugin.viewer.scene;\n\n\t\tthis._controlFillColor = !!cfg && !!cfg.controlFillColor ? cfg.controlFillColor : [0.1, 0.4, 0.99];\n\t\tthis._planeSize = !!cfg && !!cfg.planeSize ? cfg.planeSize : 1;\n\t\tthis._controlSize = !!cfg && !!cfg.controlSize ? cfg.controlSize : 0.07;\n\t\tthis._planeOpacity = !!cfg && !!cfg.planeOpacity ? cfg.planeOpacity : 0.4;\n\n\t\tthis._visible = false;\n\t\tthis._pos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3(); // Full-precision position of the center of the Control\n\t\tthis._origin = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\tthis._rtcPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\n\t\tthis._baseDir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3(); // Saves direction of clip plane when we start dragging an arrow or ring.\n\t\tthis._rootNode = null; // Root of Node graph that represents this control in the 3D scene\n\t\tthis._displayMeshes = null; // Meshes that are always visible\n\t\tthis._affordanceMeshes = null; // Meshes displayed momentarily for affordance\n\n\t\tthis._ignoreNextSectionPlaneDirUpdate = false;\n\n\t\tthis._createNodes();\n\t\tthis._bindEvents();\n\t}\n\n\t/**\n\t * Builds the Entities that represent this Control.\n\t * @private\n\t */\n\t_createNodes() {\n\t\tconst NO_STATE_INHERIT = false;\n\t\tconst scene = this._viewer.scene;\n\n\t\tthis._rootNode = new _viewer_scene_nodes_Node_js__WEBPACK_IMPORTED_MODULE_6__.Node(scene, {\n\t\t\tposition: [0, 0, 0],\n\t\t\tscale: [5, 5, 5],\n\t\t\tisObject: false\n\t\t});\n\n\t\tconst rootNode = this._rootNode;\n\n\t\tthis._displayMeshes = {\n\t\t\tplane: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(rootNode, {\n\t\t\t\t\t\tprimitive: \"triangles\",\n\t\t\t\t\t\tpositions: [\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.0,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.0, // 0\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.0,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.0, // 1\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.0,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.0, // 2\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.0,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.0 // 3\n\t\t\t\t\t\t],\n\t\t\t\t\t\tindices: [0, 1, 2, 2, 3, 0]\n\t\t\t\t\t}),\n\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t\t\temissive: [0, 0, 0],\n\t\t\t\t\t\tdiffuse: this._controlFillColor,\n\t\t\t\t\t\tbackfaces: true\n\t\t\t\t\t}),\n\t\t\t\t\topacity: this._planeOpacity,\n\t\t\t\t\tghosted: true,\n\t\t\t\t\tghostMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t\t\tedges: false,\n\t\t\t\t\t\tfilled: true,\n\t\t\t\t\t\tfillColor: this._controlFillColor ? this._controlFillColor : [0.1, 0.4, 0.99],\n\t\t\t\t\t\tfillAlpha: 0.1,\n\t\t\t\t\t\tbackfaces: true\n\t\t\t\t\t}),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tscale: [2.4 * this._planeSize, 2.4 * this._planeSize, 1 * this._planeSize],\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t)\n\t\t};\n\n\t\tthis._affordanceMeshes = {\n\t\t\t// plane: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\tgeometry: new ReadableGeometry(rootNode, {\n\t\t\t// \t\t\tprimitive: \"triangles\",\n\t\t\t// \t\t\tpositions: [\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t0.0,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t0.0, // 0\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t0.0,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t0.0, // 1\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t-0.0,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t-0.0, // 2\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t-0.0,\n\t\t\t// \t\t\t\t-0.5,\n\t\t\t// \t\t\t\t0.5,\n\t\t\t// \t\t\t\t-0.0 // 3\n\t\t\t// \t\t\t],\n\t\t\t// \t\t\tindices: [0, 1, 2, 2, 3, 0]\n\t\t\t// \t\t}),\n\t\t\t// \t\tmaterial: new PhongMaterial(rootNode, {\n\t\t\t// \t\t\temissive: [0, 0, 0],\n\t\t\t// \t\t\tdiffuse: this._controlFillColor,\n\t\t\t// \t\t\tbackfaces: true\n\t\t\t// \t\t}),\n\t\t\t// \t\topacity: this._planeOpacity,\n\t\t\t// \t\tghosted: true,\n\t\t\t// \t\tghostMaterial: new EmphasisMaterial(rootNode, {\n\t\t\t// \t\t\tedges: false,\n\t\t\t// \t\t\tfilled: true,\n\t\t\t// \t\t\tfillColor: this._controlFillColor,\n\t\t\t// \t\t\tfillAlpha: 0.1,\n\t\t\t// \t\t\tbackfaces: true\n\t\t\t// \t\t}),\n\t\t\t// \t\tpickable: true,\n\t\t\t// \t\tcollidable: true,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tscale: [2.4 * this._planeSize, 2.4 * this._planeSize, 1 * this._planeSize],\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// )\n\t\t};\n\t}\n\n\t/**\n\t * Called by SectionPlanesPlugin to assign this Control to a SectionPlane.\n\t * SectionPlanesPlugin keeps SectionPlaneControls in a reuse pool.\n\t * Call with a null or undefined value to disconnect the Control ffrom whatever SectionPlane it was assigned to.\n\t * @private\n\t */\n\t_setSectionPlane(sectionPlane) {\n\t\tif (this._sectionPlane) {\n\t\t\tthis._sectionPlane.off(this._onSectionPlanePos);\n\t\t\tthis._sectionPlane.off(this._onSectionPlaneDir);\n\t\t\tthis._onSectionPlanePos = null;\n\t\t\tthis._onSectionPlaneDir = null;\n\t\t\tthis._sectionPlane = null;\n\t\t}\n\t\tif (sectionPlane) {\n\t\t\tthis.id = sectionPlane.id;\n\t\t\tthis._setPos(sectionPlane.pos);\n\t\t\tthis._setDir(sectionPlane.dir);\n\t\t\tthis._sectionPlane = sectionPlane;\n\t\t\tsectionPlane.control = this;\n\t\t\tthis._onSectionPlanePos = sectionPlane.on(\"pos\", () => {\n\t\t\t\tthis._setPos(this._sectionPlane.pos);\n\t\t\t});\n\t\t\tthis._onSectionPlaneDir = sectionPlane.on(\"dir\", () => {\n\t\t\t\tif (!this._ignoreNextSectionPlaneDirUpdate) {\n\t\t\t\t\tthis._setDir(this._sectionPlane.dir);\n\t\t\t\t} else {\n\t\t\t\t\tthis._ignoreNextSectionPlaneDirUpdate = false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Gets the {@link SectionPlane} controlled by this Control.\n\t * @returns {SectionPlane} The SectionPlane.\n\t */\n\tget sectionPlane() {\n\t\treturn this._sectionPlane;\n\t}\n\n\t/**\n\t * 设置剖切面位置\n\t * @param {any} value\n\t */\n\tset pos(posRate) {\n\t\tif (posRate < 0 || posRate > 100) return;\n\n\t\tconst { aabb } = this._scene;\n\t\tconst { center } = this._scene;\n\t\tconst xRange = aabb[3] - aabb[0]; //前后\n\t\tconst yRange = aabb[4] - aabb[1]; //上下\n\t\tconst zRange = aabb[5] - aabb[2]; //左右\n\n\t\tconst newSectionPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\tnewSectionPos[0] = this.pos[0];\n\t\tnewSectionPos[1] = this.pos[1];\n\t\tnewSectionPos[2] = this.pos[2];\n\n\t\tconst { dir } = this._sectionPlane;\n\t\tlet rateDis;\n\t\tif (dir[0] != 0) {\n\t\t\trateDis = (posRate / 100) * xRange;\n\t\t\tnewSectionPos[0] = center[0] - xRange / 2 + rateDis; // console.log(\"xRange\", rateDis, rateDis + aabb[0]);\n\t\t} else if (dir[1] != 0) {\n\t\t\trateDis = (posRate / 100) * yRange;\n\t\t\tnewSectionPos[1] = center[1] - yRange / 2 + rateDis; // console.log(\"yRange\", rateDis, rateDis + aabb[1]);\n\t\t} else if (dir[2] != 0) {\n\t\t\trateDis = (posRate / 100) * zRange;\n\t\t\tnewSectionPos[2] = center[2] - zRange / 2 + rateDis; // console.log(\"zRange\", rateDis, rateDis + aabb[2]);\n\t\t}\n\n\t\tthis._sectionPlane.pos = newSectionPos;\n\t}\n\n\tget pos() {\n\t\treturn this._pos;\n\t}\n\n\t/** @private */\n\t_setPos(xyz) {\n\t\tthis._pos.set(xyz);\n\t\t(0,_viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_9__.worldToRTCPos)(this._pos, this._origin, this._rtcPos);\n\t\tthis._rootNode.origin = this._origin;\n\t\tthis._rootNode.position = this._rtcPos;\n\t}\n\n\t/** @private */\n\t_setDir(xyz) {\n\t\tthis._baseDir.set(xyz);\n\t\tthis._rootNode.quaternion = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3PairToQuaternion(zeroVec, xyz, quat);\n\t}\n\n\t_setSectionPlaneDir(dir) {\n\t\tif (this._sectionPlane) {\n\t\t\tthis._ignoreNextSectionPlaneDirUpdate = true;\n\t\t\tthis._sectionPlane.dir = dir;\n\t\t}\n\t}\n\n\t/**\n\t * Sets if this Control is visible.\n\t *\n\t * @type {Boolean}\n\t */\n\tsetVisible(visible = true) {\n\t\tif (this._visible === visible) {\n\t\t\treturn;\n\t\t}\n\t\tthis._visible = visible;\n\t\tvar id;\n\t\tfor (id in this._displayMeshes) {\n\t\t\tif (this._displayMeshes.hasOwnProperty(id)) {\n\t\t\t\tthis._displayMeshes[id].visible = visible;\n\t\t\t}\n\t\t}\n\t\tif (!visible) {\n\t\t\tfor (id in this._affordanceMeshes) {\n\t\t\t\tif (this._affordanceMeshes.hasOwnProperty(id)) {\n\t\t\t\t\tthis._affordanceMeshes[id].visible = visible;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets if this Control is visible.\n\t *\n\t * @type {Boolean}\n\t */\n\tgetVisible() {\n\t\treturn this._visible;\n\t}\n\n\t/**\n\t * Sets if this Control is culled. This is called by SectionPlanesPlugin to\n\t * temporarily hide the Control while a snapshot is being taken by Viewer#getSnapshot().\n\t * @param culled\n\t */\n\tsetCulled(culled) {\n\t\tvar id;\n\t\tfor (id in this._displayMeshes) {\n\t\t\tif (this._displayMeshes.hasOwnProperty(id)) {\n\t\t\t\tthis._displayMeshes[id].culled = culled;\n\t\t\t}\n\t\t}\n\t\tif (!culled) {\n\t\t\tfor (id in this._affordanceMeshes) {\n\t\t\t\tif (this._affordanceMeshes.hasOwnProperty(id)) {\n\t\t\t\t\tthis._affordanceMeshes[id].culled = culled;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t_bindEvents() {\n\t\tconst self = this;\n\n\t\tvar grabbed = false;\n\n\t\tconst DRAG_ACTIONS = {\n\t\t\tnone: -1,\n\t\t\txTranslate: 0,\n\t\t\tyTranslate: 1,\n\t\t\tzTranslate: 2,\n\t\t\txRotate: 3,\n\t\t\tyRotate: 4,\n\t\t\tzRotate: 5\n\t\t};\n\n\t\tconst rootNode = this._rootNode;\n\n\t\tvar nextDragAction = null; // As we hover grabbed an arrow or hoop, self is the action we would do if we then dragged it.\n\t\tvar dragAction = null; // Action we're doing while we drag an arrow or hoop.\n\t\tconst lastCanvasPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec2();\n\t\tthis.lastCanvasPos = lastCanvasPos;\n\t\tconst xBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([1, 0, 0]);\n\t\tconst yBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 1, 0]);\n\t\tconst zBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 1]);\n\n\t\tconst canvas = this._viewer.scene.canvas.canvas;\n\t\tconst camera = this._viewer.camera;\n\t\tconst scene = this._viewer.scene;\n\n\t\t{\n\t\t\t// Keep gizmo screen size constant\n\n\t\t\tconst tempVec3a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 0]);\n\n\t\t\tlet distDirty = true;\n\t\t\tlet lastDist = -1;\n\n\t\t\tthis._onCameraViewMatrix = scene.camera.on(\"viewMatrix\", () => {\n\t\t\t\tdistDirty = true;\n\t\t\t});\n\n\t\t\tthis._onCameraProjMatrix = scene.camera.on(\"projMatrix\", () => {\n\t\t\t\tdistDirty = true;\n\t\t\t});\n\n\t\t\tthis._onSceneTick = scene.on(\"tick\", () => {\n\t\t\t\tconst dist = Math.abs(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(scene.camera.eye, this._pos, tempVec3a)));\n\n\t\t\t\tif (dist !== lastDist) {\n\t\t\t\t\tif (camera.projection === \"perspective\") {\n\t\t\t\t\t\tconst worldSize = Math.tan(camera.perspective.fov * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD) * dist;\n\t\t\t\t\t\t// const size = this._controlSize * worldSize;\n\t\t\t\t\t\t// rootNode.scale = [size, size, size];\n\t\t\t\t\t\tlastDist = dist;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (camera.projection === \"ortho\") {\n\t\t\t\t\tconst worldSize = camera.ortho.scale / 10;\n\t\t\t\t\t// const size = worldSize;\n\t\t\t\t\t// rootNode.scale = [size, size, size];\n\t\t\t\t\tlastDist = dist;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tconst getClickCoordsWithinElement = (function () {\n\t\t\tconst canvasPos = new Float64Array(2);\n\t\t\treturn function (event) {\n\t\t\t\tif (!event) {\n\t\t\t\t\tevent = window.event;\n\t\t\t\t\tcanvasPos[0] = event.x;\n\t\t\t\t\tcanvasPos[1] = event.y;\n\t\t\t\t} else {\n\t\t\t\t\tvar element = event.target;\n\t\t\t\t\tvar totalOffsetLeft = 0;\n\t\t\t\t\tvar totalOffsetTop = 0;\n\n\t\t\t\t\twhile (element.offsetParent) {\n\t\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\n\t\t\t\t\t\ttotalOffsetTop += element.offsetTop;\n\t\t\t\t\t\telement = element.offsetParent;\n\t\t\t\t\t}\n\t\t\t\t\tcanvasPos[0] = event.pageX - totalOffsetLeft;\n\t\t\t\t\tcanvasPos[1] = event.pageY - totalOffsetTop;\n\t\t\t\t}\n\t\t\t\treturn canvasPos;\n\t\t\t};\n\t\t})();\n\n\t\tconst getTouchCoordsWithinElement = (function () {\n\t\t\tconst canvasPos = new Float64Array(2);\n\t\t\treturn function (event) {\n\t\t\t\tif (!event) {\n\t\t\t\t\tevent = window.event;\n\t\t\t\t}\n\t\t\t\tif (event.touches && event.touches.length) {\n\t\t\t\t\t// 如果有触摸事件,使用第一个触摸点的坐标\n\t\t\t\t\tcanvasPos[0] = event.touches[0].pageX;\n\t\t\t\t\tcanvasPos[1] = event.touches[0].pageY;\n\t\t\t\t} else {\n\t\t\t\t\t// 否则,假设是鼠标事件\n\t\t\t\t\tvar element = event.target;\n\t\t\t\t\tvar totalOffsetLeft = 0;\n\t\t\t\t\tvar totalOffsetTop = 0;\n\n\t\t\t\t\twhile (element.offsetParent) {\n\t\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\n\t\t\t\t\t\ttotalOffsetTop += element.offsetTop;\n\t\t\t\t\t\telement = element.offsetParent;\n\t\t\t\t\t}\n\t\t\t\t\tcanvasPos[0] = event.pageX - totalOffsetLeft;\n\t\t\t\t\tcanvasPos[1] = event.pageY - totalOffsetTop;\n\t\t\t\t}\n\t\t\t\treturn canvasPos;\n\t\t\t};\n\t\t})();\n\n\t\t//转换为世界坐标\n\t\tconst localToWorldVec = (function () {\n\t\t\tconst mat = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function (localVec, worldVec) {\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.quaternionToMat4(self._rootNode.quaternion, mat);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(mat, localVec, worldVec);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(worldVec);\n\t\t\t\treturn worldVec;\n\t\t\t};\n\t\t})();\n\n\t\tvar getTranslationPlane = (function () {\n\t\t\tconst planeNormal = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\treturn function (worldAxis) {\n\t\t\t\tconst absX = Math.abs(worldAxis[0]);\n\t\t\t\tif (absX > Math.abs(worldAxis[1]) && absX > Math.abs(worldAxis[2])) {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(worldAxis, [0, 1, 0], planeNormal);\n\t\t\t\t} else {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(worldAxis, [1, 0, 0], planeNormal);\n\t\t\t\t}\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(planeNormal, worldAxis, planeNormal);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(planeNormal);\n\t\t\t\treturn planeNormal;\n\t\t\t};\n\t\t})();\n\n\t\t//拖拽平面\n\t\tconst dragTranslateSectionPlane = (function () {\n\t\t\tconst p1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst p2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst worldAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\treturn function (baseAxis, fromMouse, toMouse) {\n\t\t\t\tlocalToWorldVec(baseAxis, worldAxis);\n\t\t\t\tconst planeNormal = getTranslationPlane(worldAxis, fromMouse, toMouse);\n\t\t\t\tgetPointerPlaneIntersect(fromMouse, planeNormal, p1);\n\t\t\t\tgetPointerPlaneIntersect(toMouse, planeNormal, p2);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(p2, p1);\n\t\t\t\tconst dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p2, worldAxis);\n\t\t\t\tself._pos[0] += worldAxis[0] * dot;\n\t\t\t\tself._pos[1] += worldAxis[1] * dot;\n\t\t\t\tself._pos[2] += worldAxis[2] * dot;\n\t\t\t\tself._rootNode.position = self._pos;\n\t\t\t\tif (self._sectionPlane) {\n\t\t\t\t\tself._sectionPlane.pos = self._pos;\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\n\t\tvar getPointerPlaneIntersect = (function () {\n\t\t\tconst dir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4([0, 0, 0, 1]);\n\t\t\tconst matrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function (mouse, axis, dest, offset) {\n\t\t\t\toffset = offset || 0;\n\t\t\t\tdir[0] = (mouse[0] / canvas.width) * 2.0 - 1.0;\n\t\t\t\tdir[1] = -((mouse[1] / canvas.height) * 2.0 - 1.0);\n\t\t\t\tdir[2] = 0.0;\n\t\t\t\tdir[3] = 1.0;\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(camera.projMatrix, camera.viewMatrix, matrix); // Unproject norm device coords to view coords\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(matrix);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec4(matrix, dir, dir);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec4Scalar(dir, 1.0 / dir[3]); // This is now point A on the ray in world space\n\t\t\t\tvar rayO = camera.eye; // The direction\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec4(dir, rayO, dir);\n\t\t\t\tconst origin = self._sectionPlane.pos; // Plane origin:\n\t\t\t\tvar d = -_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(origin, axis) - offset;\n\t\t\t\tvar dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(axis, dir);\n\t\t\t\tif (Math.abs(dot) > 0.005) {\n\t\t\t\t\tvar t = -(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(axis, rayO) + d) / dot;\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(dir, t, dest);\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(dest, rayO);\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(dest, origin, dest);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t};\n\t\t})();\n\n\t\t{\n\t\t\tvar mouseDownLeft;\n\t\t\tvar mouseDownMiddle;\n\t\t\tvar mouseDownRight;\n\t\t\tvar down = false;\n\t\t\t// var lastAffordanceMesh;\n\n\t\t\tthis._onCameraControlHover = this._viewer.cameraControl.on(\"hoverEnter\", (hit) => {\n\t\t\t\tif (!this._visible) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (down) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tgrabbed = false;\n\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t// \tlastAffordanceMesh.visible = false;\n\t\t\t\t// }\n\t\t\t\t// var affordanceMesh;\n\t\t\t\tconst meshId = hit.entity.id;\n\t\t\t\tswitch (meshId) {\n\t\t\t\t\tcase this._displayMeshes.plane.id:\n\t\t\t\t\t\t// affordanceMesh = this._affordanceMeshes.plane;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\t\treturn; // Not clicked an arrow or hoop\n\t\t\t\t}\n\t\t\t\t// if (affordanceMesh) {\n\t\t\t\t// \taffordanceMesh.visible = true;\n\t\t\t\t// }\n\t\t\t\t// lastAffordanceMesh = affordanceMesh;\n\t\t\t\tgrabbed = true;\n\t\t\t});\n\n\t\t\tthis._onCameraControlHoverLeave = this._viewer.cameraControl.on(\"hoverOutEntity\", (hit) => {\n\t\t\t\tif (!this._visible) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t// \tlastAffordanceMesh.visible = false;\n\t\t\t\t// }\n\t\t\t\t// lastAffordanceMesh = null;\n\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t});\n\n\t\t\t//mousedown\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mousedown\",\n\t\t\t\t(this._canvasMouseDownListener = (e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (!this._visible || !grabbed) return;\n\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = false;\n\t\t\t\t\tswitch (e.which) {\n\t\t\t\t\t\tcase 1: // Left button\n\t\t\t\t\t\t\tmouseDownLeft = true;\n\t\t\t\t\t\t\tdown = true;\n\t\t\t\t\t\t\tvar canvasPos = getClickCoordsWithinElement(e); //获取鼠标点击对应坐标\n\t\t\t\t\t\t\tdragAction = nextDragAction;\n\t\t\t\t\t\t\tlastCanvasPos[0] = canvasPos[0];\n\t\t\t\t\t\t\tlastCanvasPos[1] = canvasPos[1];\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t);\n\t\t\t//mousemove\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mousemove\",\n\t\t\t\t(this._canvasMouseMoveListener = (e) => {\n\t\t\t\t\tif (!this._visible) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!down) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar canvasPos = getClickCoordsWithinElement(e);\n\t\t\t\t\tconst x = canvasPos[0];\n\t\t\t\t\tconst y = canvasPos[1];\n\n\t\t\t\t\tswitch (dragAction) {\n\t\t\t\t\t\tcase DRAG_ACTIONS.xTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlastCanvasPos[0] = x;\n\t\t\t\t\tlastCanvasPos[1] = y;\n\t\t\t\t})\n\t\t\t);\n\t\t\t//mouseup\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mouseup\",\n\t\t\t\t(this._canvasMouseUpListener = (e) => {\n\t\t\t\t\tif (!this._visible) return;\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = true;\n\t\t\t\t\tif (!down) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tswitch (e.which) {\n\t\t\t\t\t\tcase 1: // Left button\n\t\t\t\t\t\t\tmouseDownLeft = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 2: // Middle/both buttons\n\t\t\t\t\t\t\tmouseDownMiddle = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 3: // Right button\n\t\t\t\t\t\t\tmouseDownRight = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdown = false;\n\t\t\t\t\tgrabbed = false;\n\t\t\t\t})\n\t\t\t);\n\n\t\t\t//wheel\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"wheel\",\n\t\t\t\t(this._canvasWheelListener = (e) => {\n\t\t\t\t\tif (!this._visible) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar delta = Math.max(-1, Math.min(1, -e.deltaY * 40));\n\t\t\t\t\tif (delta === 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t);\n\n\t\t\tthis._onCameraControlHover = this._viewer.cameraControl.on(\"touchEntity\", (hit) => {\n\t\t\t\tif (!this._visible || down || grabbed) return;\n\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t// \tlastAffordanceMesh.visible = false;\n\t\t\t\t// }\n\t\t\t\tvar affordanceMesh;\n\t\t\t\tconst meshId = hit.entity.id;\n\t\t\t\tswitch (meshId) {\n\t\t\t\t\tcase this._displayMeshes.plane.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.plane;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\t\treturn; // Not clicked an arrow or hoop\n\t\t\t\t}\n\t\t\t\tif (affordanceMesh) {\n\t\t\t\t\taffordanceMesh.visible = true;\n\t\t\t\t}\n\t\t\t\t// lastAffordanceMesh = affordanceMesh;\n\t\t\t\tgrabbed = true;\n\t\t\t\tdown = true;\n\t\t\t});\n\t\t\t//touchstart\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchstart\",\n\t\t\t\t(this._canvasMouseDownListener = (e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (!this._visible || !grabbed || !down) return;\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = false;\n\t\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t\t// \tlastAffordanceMesh.visible = true;\n\t\t\t\t\t// }\n\t\t\t\t\tvar canvasPos = getTouchCoordsWithinElement(e);\n\t\t\t\t\tdragAction = nextDragAction;\n\t\t\t\t\tlastCanvasPos[0] = canvasPos[0];\n\t\t\t\t\tlastCanvasPos[1] = canvasPos[1];\n\t\t\t\t})\n\t\t\t);\n\t\t\t//touchmove\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchmove\",\n\t\t\t\t(this._canvasMouseMoveListener = (e) => {\n\t\t\t\t\tif (!this._visible || !down || !grabbed) return;\n\n\t\t\t\t\tvar canvasPos = getTouchCoordsWithinElement(e);\n\t\t\t\t\tconst x = canvasPos[0];\n\t\t\t\t\tconst y = canvasPos[1];\n\n\t\t\t\t\tswitch (dragAction) {\n\t\t\t\t\t\tcase DRAG_ACTIONS.xTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlastCanvasPos[0] = x;\n\t\t\t\t\tlastCanvasPos[1] = y;\n\t\t\t\t})\n\t\t\t);\n\t\t\t//touchend\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchend\",\n\t\t\t\t(this._canvasTouchEndListener = (e) => {\n\t\t\t\t\tif (!this._visible) return;\n\t\t\t\t\tif (grabbed) this._viewer.cameraControl.pointerEnabled = true;\n\t\t\t\t\t// if (lastAffordanceMesh) {\n\t\t\t\t\t// \tlastAffordanceMesh.visible = false;\n\t\t\t\t\t// }\n\t\t\t\t\t// lastAffordanceMesh = null;\n\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\tdown = false;\n\t\t\t\t\tgrabbed = false;\n\t\t\t\t})\n\t\t\t);\n\t\t\tcanvas.addEventListener(\"touchcancel\", this._canvasTouchEndListener);\n\t\t}\n\t}\n\n\t_destroy() {\n\t\tthis._unbindEvents();\n\t\tthis._destroyNodes();\n\t}\n\n\t_unbindEvents() {\n\t\tconst viewer = this._viewer;\n\t\tconst scene = viewer.scene;\n\t\tconst canvas = scene.canvas.canvas;\n\t\tconst camera = viewer.camera;\n\t\tconst cameraControl = viewer.cameraControl;\n\n\t\tscene.off(this._onSceneTick);\n\n\t\tcanvas.removeEventListener(\"mousedown\", this._canvasMouseDownListener);\n\t\tcanvas.removeEventListener(\"mousemove\", this._canvasMouseMoveListener);\n\t\tcanvas.removeEventListener(\"mouseup\", this._canvasMouseUpListener);\n\t\tcanvas.removeEventListener(\"wheel\", this._canvasWheelListener);\n\t\tcanvas.removeEventListener(\"touchend\", this._canvasTouchEndListener);\n\t\tcanvas.removeEventListener(\"touchcancel\", this._canvasTouchEndListener);\n\n\t\tcamera.off(this._onCameraViewMatrix);\n\t\tcamera.off(this._onCameraProjMatrix);\n\n\t\tcameraControl.off(this._onCameraControlHover);\n\t\tcameraControl.off(this._onCameraControlHoverLeave);\n\t}\n\n\t_destroyNodes() {\n\t\tthis._setSectionPlane(null);\n\t\tthis._rootNode.destroy();\n\t\tthis._displayMeshes = {};\n\t\tthis._affordanceMeshes = {};\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SectionPlanesPlugin/ClippingPlane.js?");
1898
1908
 
1899
1909
  /***/ }),
1900
1910
 
@@ -1904,7 +1914,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1904
1914
  \****************************************************/
1905
1915
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1906
1916
 
1907
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Control: () => (/* binding */ Control)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildCylinderGeometry.js */ \"./src/viewer/scene/geometry/builders/buildCylinderGeometry.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildTorusGeometry.js */ \"./src/viewer/scene/geometry/builders/buildTorusGeometry.js\");\n/* harmony import */ var _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../viewer/scene/geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../viewer/scene/materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../viewer/scene/materials/EmphasisMaterial.js */ \"./src/viewer/scene/materials/EmphasisMaterial.js\");\n/* harmony import */ var _viewer_scene_nodes_Node_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../viewer/scene/nodes/Node.js */ \"./src/viewer/scene/nodes/Node.js\");\n/* harmony import */ var _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../viewer/scene/mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildSphereGeometry.js */ \"./src/viewer/scene/geometry/builders/buildSphereGeometry.js\");\n/* harmony import */ var _viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../viewer/scene/math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst zeroVec = new Float64Array([0, 0, 1]);\nconst quat = new Float64Array(4);\n\n/**\n * Controls a {@link SectionPlane} with mouse and touch input.\n *\n * @private\n */\nclass Control {\n\t/** @private */\n\tconstructor(plugin) {\n\t\t/**\n\t\t * ID of this Control.\n\t\t *\n\t\t * SectionPlaneControls are mapped by this ID in {@link SectionPlanesPlugin#sectionPlaneControls}.\n\t\t *\n\t\t * @property id\n\t\t * @type {String|Number}\n\t\t */\n\t\tthis.id = null;\n\t\tthis.type = \"control\";\n\n\t\tthis._viewer = plugin.viewer;\n\t\tthis._scene = plugin.viewer.scene;\n\n\t\tthis._visible = false;\n\t\tthis._pos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3(); // Full-precision position of the center of the Control\n\t\tthis._origin = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\tthis._rtcPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\n\t\tthis._baseDir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3(); // Saves direction of clip plane when we start dragging an arrow or ring.\n\t\tthis._rootNode = null; // Root of Node graph that represents this control in the 3D scene\n\t\tthis._displayMeshes = null; // Meshes that are always visible\n\t\tthis._affordanceMeshes = null; // Meshes displayed momentarily for affordance\n\n\t\tthis._ignoreNextSectionPlaneDirUpdate = false;\n\n\t\tthis._createNodes();\n\t\tthis._bindEvents();\n\t}\n\n\t/**\n\t * Called by SectionPlanesPlugin to assign this Control to a SectionPlane.\n\t * SectionPlanesPlugin keeps SectionPlaneControls in a reuse pool.\n\t * Call with a null or undefined value to disconnect the Control ffrom whatever SectionPlane it was assigned to.\n\t * @private\n\t */\n\t_setSectionPlane(sectionPlane) {\n\t\tif (this._sectionPlane) {\n\t\t\tthis._sectionPlane.off(this._onSectionPlanePos);\n\t\t\tthis._sectionPlane.off(this._onSectionPlaneDir);\n\t\t\tthis._onSectionPlanePos = null;\n\t\t\tthis._onSectionPlaneDir = null;\n\t\t\tthis._sectionPlane = null;\n\t\t}\n\t\tif (sectionPlane) {\n\t\t\tthis.id = sectionPlane.id;\n\t\t\tthis._setPos(sectionPlane.pos);\n\t\t\tthis._setDir(sectionPlane.dir);\n\t\t\tthis._sectionPlane = sectionPlane;\n\t\t\tthis._onSectionPlanePos = sectionPlane.on(\"pos\", () => {\n\t\t\t\tthis._setPos(this._sectionPlane.pos);\n\t\t\t});\n\t\t\tthis._onSectionPlaneDir = sectionPlane.on(\"dir\", () => {\n\t\t\t\tif (!this._ignoreNextSectionPlaneDirUpdate) {\n\t\t\t\t\tthis._setDir(this._sectionPlane.dir);\n\t\t\t\t} else {\n\t\t\t\t\tthis._ignoreNextSectionPlaneDirUpdate = false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Gets the {@link SectionPlane} controlled by this Control.\n\t * @returns {SectionPlane} The SectionPlane.\n\t */\n\tget sectionPlane() {\n\t\treturn this._sectionPlane;\n\t}\n\n\t/**\n\t * 设置剖切面位置\n\t * @param {any} value\n\t */\n\tset pos(posRate) {\n\t\tif (posRate < 0 || posRate > 100) return;\n\n\t\tconst { aabb } = this._scene;\n\t\tconst { look } = this._scene.camera;\n\t\tconst xRange = aabb[3] - aabb[0]; //前后\n\t\tconst yRange = aabb[4] - aabb[1]; //上下\n\t\tconst zRange = aabb[5] - aabb[2]; //左右\n\n\t\tconst newSectionPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\tnewSectionPos[0] = this.pos[0];\n\t\tnewSectionPos[1] = this.pos[1];\n\t\tnewSectionPos[2] = this.pos[2];\n\n\t\tconst { dir } = this._sectionPlane;\n\t\tlet rateDis;\n\t\tif (dir[0] != 0) {\n\t\t\trateDis = (posRate / 100) * xRange;\n\t\t\tnewSectionPos[0] = look[0] - xRange / 2 + rateDis;\n\t\t} else if (dir[1] != 0) {\n\t\t\trateDis = (posRate / 100) * yRange;\n\t\t\tnewSectionPos[1] = look[1] - yRange / 2 + rateDis;\n\t\t} else if (dir[2] != 0) {\n\t\t\trateDis = (posRate / 100) * zRange;\n\t\t\tnewSectionPos[2] = look[2] - zRange / 2 + rateDis;\n\t\t}\n\n\t\tthis._sectionPlane.pos = newSectionPos;\n\t}\n\n\tget pos() {\n\t\treturn this._pos;\n\t}\n\n\t/** @private */\n\t_setPos(xyz) {\n\t\tthis._pos.set(xyz);\n\n\t\t(0,_viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_9__.worldToRTCPos)(this._pos, this._origin, this._rtcPos);\n\n\t\tthis._rootNode.origin = this._origin;\n\t\tthis._rootNode.position = this._rtcPos;\n\t}\n\n\t/** @private */\n\t_setDir(xyz) {\n\t\tthis._baseDir.set(xyz);\n\t\tthis._rootNode.quaternion = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3PairToQuaternion(zeroVec, xyz, quat);\n\t}\n\n\t_setSectionPlaneDir(dir) {\n\t\tif (this._sectionPlane) {\n\t\t\tthis._ignoreNextSectionPlaneDirUpdate = true;\n\t\t\tthis._sectionPlane.dir = dir;\n\t\t}\n\t}\n\n\t/**\n\t * Sets if this Control is visible.\n\t *\n\t * @type {Boolean}\n\t */\n\tsetVisible(visible = true) {\n\t\tif (this._visible === visible) {\n\t\t\treturn;\n\t\t}\n\t\tthis._visible = visible;\n\t\tvar id;\n\t\tfor (id in this._displayMeshes) {\n\t\t\tif (this._displayMeshes.hasOwnProperty(id)) {\n\t\t\t\tthis._displayMeshes[id].visible = visible;\n\t\t\t}\n\t\t}\n\t\tif (!visible) {\n\t\t\tfor (id in this._affordanceMeshes) {\n\t\t\t\tif (this._affordanceMeshes.hasOwnProperty(id)) {\n\t\t\t\t\tthis._affordanceMeshes[id].visible = visible;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets if this Control is visible.\n\t *\n\t * @type {Boolean}\n\t */\n\tgetVisible() {\n\t\treturn this._visible;\n\t}\n\n\t/**\n\t * Sets if this Control is culled. This is called by SectionPlanesPlugin to\n\t * temporarily hide the Control while a snapshot is being taken by Viewer#getSnapshot().\n\t * @param culled\n\t */\n\tsetCulled(culled) {\n\t\tvar id;\n\t\tfor (id in this._displayMeshes) {\n\t\t\tif (this._displayMeshes.hasOwnProperty(id)) {\n\t\t\t\tthis._displayMeshes[id].culled = culled;\n\t\t\t}\n\t\t}\n\t\tif (!culled) {\n\t\t\tfor (id in this._affordanceMeshes) {\n\t\t\t\tif (this._affordanceMeshes.hasOwnProperty(id)) {\n\t\t\t\t\tthis._affordanceMeshes[id].culled = culled;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Builds the Entities that represent this Control.\n\t * @private\n\t */\n\t_createNodes() {\n\t\tconst NO_STATE_INHERIT = false;\n\t\tconst scene = this._viewer.scene;\n\t\tconst radius = 1.0;\n\t\tconst handleTubeRadius = 0.06;\n\t\tconst hoopRadius = radius - 0.2;\n\t\tconst tubeRadius = 0.01;\n\t\tconst arrowRadius = 0.07;\n\n\t\tthis._rootNode = new _viewer_scene_nodes_Node_js__WEBPACK_IMPORTED_MODULE_6__.Node(scene, {\n\t\t\tposition: [0, 0, 0],\n\t\t\tscale: [5, 5, 5],\n\t\t\tisObject: false\n\t\t});\n\n\t\tconst rootNode = this._rootNode;\n\n\t\tconst shapes = {\n\t\t\t// Reusable geometries\n\n\t\t\tarrowHead: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: 0.001,\n\t\t\t\t\tradiusBottom: arrowRadius,\n\t\t\t\t\tradialSegments: 32,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: 0.2,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t),\n\n\t\t\tarrowHeadBig: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: 0.001,\n\t\t\t\t\tradiusBottom: 0.09,\n\t\t\t\t\tradialSegments: 32,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: 0.25,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t),\n\n\t\t\tarrowHeadHandle: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: 0.09,\n\t\t\t\t\tradiusBottom: 0.09,\n\t\t\t\t\tradialSegments: 8,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: 0.37,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t),\n\n\t\t\tcurve: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\tradius: hoopRadius,\n\t\t\t\t\ttube: tubeRadius,\n\t\t\t\t\tradialSegments: 64,\n\t\t\t\t\ttubeSegments: 14,\n\t\t\t\t\tarc: (Math.PI * 2.0) / 4.0\n\t\t\t\t})\n\t\t\t),\n\n\t\t\tcurveHandle: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\tradius: hoopRadius,\n\t\t\t\t\ttube: handleTubeRadius,\n\t\t\t\t\tradialSegments: 64,\n\t\t\t\t\ttubeSegments: 14,\n\t\t\t\t\tarc: (Math.PI * 2.0) / 4.0\n\t\t\t\t})\n\t\t\t),\n\n\t\t\thoop: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\tradius: hoopRadius,\n\t\t\t\t\ttube: tubeRadius,\n\t\t\t\t\tradialSegments: 64,\n\t\t\t\t\ttubeSegments: 8,\n\t\t\t\t\tarc: Math.PI * 2.0\n\t\t\t\t})\n\t\t\t),\n\n\t\t\taxis: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: tubeRadius,\n\t\t\t\t\tradiusBottom: tubeRadius,\n\t\t\t\t\tradialSegments: 20,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: radius,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t),\n\n\t\t\taxisHandle: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: 0.08,\n\t\t\t\t\tradiusBottom: 0.08,\n\t\t\t\t\tradialSegments: 20,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: radius,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t)\n\t\t};\n\n\t\tconst materials = {\n\t\t\t// Reusable materials\n\n\t\t\tpickable: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t// Invisible material for pickable handles, which define a pickable 3D area\n\t\t\t\tdiffuse: [1, 1, 0],\n\t\t\t\talpha: 0, // Invisible\n\t\t\t\talphaMode: \"blend\"\n\t\t\t}),\n\n\t\t\tred: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\tdiffuse: [1, 0.0, 0.0],\n\t\t\t\temissive: [1, 0.0, 0.0],\n\t\t\t\tambient: [0.0, 0.0, 0.0],\n\t\t\t\tspecular: [0.6, 0.6, 0.3],\n\t\t\t\tshininess: 80,\n\t\t\t\tlineWidth: 2\n\t\t\t}),\n\n\t\t\thighlightRed: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t// Emphasis for red rotation affordance hoop\n\t\t\t\tedges: false,\n\t\t\t\tfill: true,\n\t\t\t\tfillColor: [1, 0, 0],\n\t\t\t\tfillAlpha: 0.6\n\t\t\t}),\n\n\t\t\tgreen: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\tdiffuse: [0.0, 1, 0.0],\n\t\t\t\temissive: [0.0, 1, 0.0],\n\t\t\t\tambient: [0.0, 0.0, 0.0],\n\t\t\t\tspecular: [0.6, 0.6, 0.3],\n\t\t\t\tshininess: 80,\n\t\t\t\tlineWidth: 2\n\t\t\t}),\n\n\t\t\thighlightGreen: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t// Emphasis for green rotation affordance hoop\n\t\t\t\tedges: false,\n\t\t\t\tfill: true,\n\t\t\t\tfillColor: [0, 1, 0],\n\t\t\t\tfillAlpha: 0.6\n\t\t\t}),\n\n\t\t\tblue: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\tdiffuse: [0.0, 0.0, 1],\n\t\t\t\temissive: [0.0, 0.0, 1],\n\t\t\t\tambient: [0.0, 0.0, 0.0],\n\t\t\t\tspecular: [0.6, 0.6, 0.3],\n\t\t\t\tshininess: 80,\n\t\t\t\tlineWidth: 2\n\t\t\t}),\n\n\t\t\thighlightBlue: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t// Emphasis for blue rotation affordance hoop\n\t\t\t\tedges: false,\n\t\t\t\tfill: true,\n\t\t\t\tfillColor: [0, 0, 1],\n\t\t\t\tfillAlpha: 0.2\n\t\t\t}),\n\n\t\t\tcenter: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\tdiffuse: [0.0, 0.0, 0.0],\n\t\t\t\temissive: [0, 0, 0],\n\t\t\t\tambient: [0.0, 0.0, 0.0],\n\t\t\t\tspecular: [0.6, 0.6, 0.3],\n\t\t\t\tshininess: 80\n\t\t\t}),\n\n\t\t\thighlightBall: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\tedges: false,\n\t\t\t\tfill: true,\n\t\t\t\tfillColor: [0.5, 0.5, 0.5],\n\t\t\t\tfillAlpha: 0.5,\n\t\t\t\tvertices: false\n\t\t\t}),\n\n\t\t\thighlightPlane: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\tedges: true,\n\t\t\t\tedgeWidth: 3,\n\t\t\t\tfill: false,\n\t\t\t\tfillColor: [0.5, 0.5, 0.5],\n\t\t\t\tfillAlpha: 0.5,\n\t\t\t\tvertices: false\n\t\t\t})\n\t\t};\n\n\t\tthis._displayMeshes = {\n\t\t\tplane: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(rootNode, {\n\t\t\t\t\t\tprimitive: \"triangles\",\n\t\t\t\t\t\tpositions: [\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.0,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.0, // 0\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.0,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.0, // 1\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.0,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.0, // 2\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.0,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.0 // 3\n\t\t\t\t\t\t],\n\t\t\t\t\t\tindices: [0, 1, 2, 2, 3, 0]\n\t\t\t\t\t}),\n\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t\t\temissive: [0, 0.0, 0],\n\t\t\t\t\t\tdiffuse: [0, 0, 0],\n\t\t\t\t\t\tbackfaces: true\n\t\t\t\t\t}),\n\t\t\t\t\topacity: 0.6,\n\t\t\t\t\tghosted: true,\n\t\t\t\t\tghostMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t\t\tedges: false,\n\t\t\t\t\t\tfilled: true,\n\t\t\t\t\t\tfillColor: [1, 1, 0],\n\t\t\t\t\t\tedgeColor: [0, 0, 0],\n\t\t\t\t\t\tfillAlpha: 0.1,\n\t\t\t\t\t\tbackfaces: true\n\t\t\t\t\t}),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tscale: [2.4, 2.4, 1],\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tplaneFrame: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Visible frame\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\t\t\trootNode,\n\t\t\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\t\t\tcenter: [0, 0, 0],\n\t\t\t\t\t\t\tradius: 1.7,\n\t\t\t\t\t\t\ttube: tubeRadius * 2,\n\t\t\t\t\t\t\tradialSegments: 4,\n\t\t\t\t\t\t\ttubeSegments: 4,\n\t\t\t\t\t\t\tarc: Math.PI * 2.0\n\t\t\t\t\t\t})\n\t\t\t\t\t),\n\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t\t\temissive: [0, 0, 0],\n\t\t\t\t\t\tdiffuse: [0, 0, 0],\n\t\t\t\t\t\tspecular: [0, 0, 0],\n\t\t\t\t\t\tshininess: 0\n\t\t\t\t\t}),\n\t\t\t\t\t//highlighted: true,\n\t\t\t\t\thighlightMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t\t\tedges: false,\n\t\t\t\t\t\tedgeColor: [0.0, 0.0, 0.0],\n\t\t\t\t\t\tfilled: true,\n\t\t\t\t\t\tfillColor: [0.8, 0.8, 0.8],\n\t\t\t\t\t\tfillAlpha: 1.0\n\t\t\t\t\t}),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tscale: [1, 1, 0.1],\n\t\t\t\t\trotation: [0, 0, 45],\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\txCurve: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Red hoop about Y-axis\n\t\t\t\t\tgeometry: shapes.curve,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst rotate2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 1, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(270 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate1, rotate2, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txCurveHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Red hoop about Y-axis\n\t\t\t\t\tgeometry: shapes.curveHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst rotate2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 1, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(270 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate1, rotate2, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txCurveArrow1: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, -0.07, -0.8, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst scale = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.scaleMat4v([0.6, 0.6, 0.6], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(0 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(translate, scale, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()), rotate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txCurveArrow2: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0.0, -0.8, -0.07, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst scale = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.scaleMat4v([0.6, 0.6, 0.6], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(translate, scale, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()), rotate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\tyCurve: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.curve,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\trotation: [-90, 0, 0],\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyCurveHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.curveHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\trotation: [-90, 0, 0],\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyCurveArrow1: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0.07, 0, -0.8, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst scale = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.scaleMat4v([0.6, 0.6, 0.6], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(translate, scale, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()), rotate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyCurveArrow2: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0.8, 0.0, -0.07, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst scale = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.scaleMat4v([0.6, 0.6, 0.6], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(translate, scale, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()), rotate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\t// zCurve: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\t// Blue hoop about Z-axis\n\t\t\t// \t\tgeometry: shapes.curve,\n\t\t\t// \t\tmaterial: materials.blue,\n\t\t\t// \t\tmatrix: math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4()),\n\t\t\t// \t\tpickable: false,\n\t\t\t// \t\tcollidable: true,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// ),\n\n\t\t\t// zCurveHandle: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\tgeometry: shapes.curveHandle,\n\t\t\t// \t\tmaterial: materials.pickable,\n\t\t\t// \t\tmatrix: math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4()),\n\t\t\t// \t\tpickable: true,\n\t\t\t// \t\tcollidable: true,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// ),\n\n\t\t\t// zCurveCurveArrow1: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\tgeometry: shapes.arrowHead,\n\t\t\t// \t\tmaterial: materials.blue,\n\t\t\t// \t\tmatrix: (function () {\n\t\t\t// \t\t\tconst translate = math.translateMat4c(0.8, -0.07, 0, math.identityMat4());\n\t\t\t// \t\t\tconst scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());\n\t\t\t// \t\t\treturn math.mulMat4(translate, scale, math.identityMat4());\n\t\t\t// \t\t})(),\n\t\t\t// \t\tpickable: true,\n\t\t\t// \t\tcollidable: true,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// ),\n\n\t\t\t// zCurveArrow2: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\tgeometry: shapes.arrowHead,\n\t\t\t// \t\tmaterial: materials.blue,\n\t\t\t// \t\tmatrix: (function () {\n\t\t\t// \t\t\tconst translate = math.translateMat4c(0.05, -0.8, 0, math.identityMat4());\n\t\t\t// \t\t\tconst scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());\n\t\t\t// \t\t\tconst rotate = math.rotationMat4v(90 * math.DEGTORAD, [0, 0, 1], math.identityMat4());\n\t\t\t// \t\t\treturn math.mulMat4(math.mulMat4(translate, scale, math.identityMat4()), rotate, math.identityMat4());\n\t\t\t// \t\t})(),\n\t\t\t// \t\tpickable: true,\n\t\t\t// \t\tcollidable: true,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// ),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\tcenter: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\t\t\trootNode,\n\t\t\t\t\t\t(0,_viewer_scene_geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_8__.buildSphereGeometry)({\n\t\t\t\t\t\t\tradius: 0.05\n\t\t\t\t\t\t})\n\t\t\t\t\t),\n\t\t\t\t\tmaterial: materials.center,\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\txAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txAxisArrowHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txAxis: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axis,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius / 2, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txAxisHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axisHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius / 2, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\tyAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(180 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyAxisArrowHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(180 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\topacity: 0.2,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyShaft: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axis,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tposition: [0, -radius / 2, 0],\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyShaftHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axisHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tposition: [0, -radius / 2, 0],\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\tzAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.blue,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0.8, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzAxisArrowHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0.8, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzShaft: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axis,\n\t\t\t\t\tmaterial: materials.blue,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius / 2, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzAxisHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axisHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius / 2, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t)\n\t\t};\n\n\t\tthis._affordanceMeshes = {\n\t\t\tplaneFrame: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\t\t\trootNode,\n\t\t\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\t\t\tcenter: [0, 0, 0],\n\t\t\t\t\t\t\tradius: 2,\n\t\t\t\t\t\t\ttube: tubeRadius,\n\t\t\t\t\t\t\tradialSegments: 4,\n\t\t\t\t\t\t\ttubeSegments: 4,\n\t\t\t\t\t\t\tarc: Math.PI * 2.0\n\t\t\t\t\t\t})\n\t\t\t\t\t),\n\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t\t\tambient: [1, 1, 1],\n\t\t\t\t\t\tdiffuse: [0, 0, 0],\n\t\t\t\t\t\temissive: [1, 1, 0]\n\t\t\t\t\t}),\n\t\t\t\t\thighlighted: true,\n\t\t\t\t\thighlightMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t\t\tedges: false,\n\t\t\t\t\t\tfilled: true,\n\t\t\t\t\t\tfillColor: [1, 1, 0],\n\t\t\t\t\t\tfillAlpha: 1.0\n\t\t\t\t\t}),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tscale: [1, 1, 1],\n\t\t\t\t\trotation: [0, 0, 45],\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txHoop: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Full\n\t\t\t\t\tgeometry: shapes.hoop,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\thighlighted: true,\n\t\t\t\t\thighlightMaterial: materials.highlightRed,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst rotate2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 1, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(270 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate1, rotate2, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyHoop: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.hoop,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\thighlighted: true,\n\t\t\t\t\thighlightMaterial: materials.highlightGreen,\n\t\t\t\t\trotation: [-90, 0, 0],\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzHoop: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Blue hoop about Z-axis\n\t\t\t\t\tgeometry: shapes.hoop,\n\t\t\t\t\tmaterial: materials.blue,\n\t\t\t\t\thighlighted: true,\n\t\t\t\t\thighlightMaterial: materials.highlightBlue,\n\t\t\t\t\tmatrix: _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(180 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadBig,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadBig,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(180 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadBig,\n\t\t\t\t\tmaterial: materials.blue,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0.8, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: true,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t)\n\t\t};\n\t}\n\n\t_bindEvents() {\n\t\tconst self = this;\n\n\t\tvar grabbed = false;\n\n\t\tconst DRAG_ACTIONS = {\n\t\t\tnone: -1,\n\t\t\txTranslate: 0,\n\t\t\tyTranslate: 1,\n\t\t\tzTranslate: 2,\n\t\t\txRotate: 3,\n\t\t\tyRotate: 4,\n\t\t\tzRotate: 5\n\t\t};\n\n\t\tconst rootNode = this._rootNode;\n\n\t\tvar nextDragAction = null; // As we hover grabbed an arrow or hoop, self is the action we would do if we then dragged it.\n\t\tvar dragAction = null; // Action we're doing while we drag an arrow or hoop.\n\t\tconst lastCanvasPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec2();\n\n\t\tconst xBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([1, 0, 0]);\n\t\tconst yBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 1, 0]);\n\t\tconst zBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 1]);\n\n\t\tconst canvas = this._viewer.scene.canvas.canvas;\n\t\tconst camera = this._viewer.camera;\n\t\tconst scene = this._viewer.scene;\n\n\t\t{\n\t\t\t// Keep gizmo screen size constant\n\n\t\t\tconst tempVec3a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 0]);\n\n\t\t\tlet distDirty = true;\n\t\t\tlet lastDist = -1;\n\n\t\t\tthis._onCameraViewMatrix = scene.camera.on(\"viewMatrix\", () => {\n\t\t\t\tdistDirty = true;\n\t\t\t});\n\n\t\t\tthis._onCameraProjMatrix = scene.camera.on(\"projMatrix\", () => {\n\t\t\t\tdistDirty = true;\n\t\t\t});\n\n\t\t\tthis._onSceneTick = scene.on(\"tick\", () => {\n\t\t\t\tconst dist = Math.abs(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(scene.camera.eye, this._pos, tempVec3a)));\n\n\t\t\t\tif (dist !== lastDist) {\n\t\t\t\t\tif (camera.projection === \"perspective\") {\n\t\t\t\t\t\tconst worldSize = Math.tan(camera.perspective.fov * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD) * dist;\n\t\t\t\t\t\tconst size = 0.07 * worldSize;\n\t\t\t\t\t\trootNode.scale = [size, size, size];\n\t\t\t\t\t\tlastDist = dist;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (camera.projection === \"ortho\") {\n\t\t\t\t\tconst worldSize = camera.ortho.scale / 10;\n\t\t\t\t\tconst size = worldSize;\n\t\t\t\t\trootNode.scale = [size, size, size];\n\t\t\t\t\tlastDist = dist;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tconst getClickCoordsWithinElement = (function () {\n\t\t\tconst canvasPos = new Float64Array(2);\n\t\t\treturn function (event) {\n\t\t\t\tif (!event) {\n\t\t\t\t\tevent = window.event;\n\t\t\t\t\tcanvasPos[0] = event.x;\n\t\t\t\t\tcanvasPos[1] = event.y;\n\t\t\t\t} else {\n\t\t\t\t\tvar element = event.target;\n\t\t\t\t\tvar totalOffsetLeft = 0;\n\t\t\t\t\tvar totalOffsetTop = 0;\n\n\t\t\t\t\twhile (element.offsetParent) {\n\t\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\n\t\t\t\t\t\ttotalOffsetTop += element.offsetTop;\n\t\t\t\t\t\telement = element.offsetParent;\n\t\t\t\t\t}\n\t\t\t\t\tcanvasPos[0] = event.pageX - totalOffsetLeft;\n\t\t\t\t\tcanvasPos[1] = event.pageY - totalOffsetTop;\n\t\t\t\t}\n\t\t\t\treturn canvasPos;\n\t\t\t};\n\t\t})();\n\n\t\tconst getTouchCoordsWithinElement = (function () {\n\t\t\tconst canvasPos = new Float64Array(2);\n\t\t\treturn function (event) {\n\t\t\t\tif (!event) {\n\t\t\t\t\tevent = window.event;\n\t\t\t\t}\n\t\t\t\tif (event.touches && event.touches.length) {\n\t\t\t\t\t// 如果有触摸事件,使用第一个触摸点的坐标\n\t\t\t\t\tcanvasPos[0] = event.touches[0].pageX;\n\t\t\t\t\tcanvasPos[1] = event.touches[0].pageY;\n\t\t\t\t} else {\n\t\t\t\t\t// 否则,假设是鼠标事件\n\t\t\t\t\tvar element = event.target;\n\t\t\t\t\tvar totalOffsetLeft = 0;\n\t\t\t\t\tvar totalOffsetTop = 0;\n\n\t\t\t\t\twhile (element.offsetParent) {\n\t\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\n\t\t\t\t\t\ttotalOffsetTop += element.offsetTop;\n\t\t\t\t\t\telement = element.offsetParent;\n\t\t\t\t\t}\n\t\t\t\t\tcanvasPos[0] = event.pageX - totalOffsetLeft;\n\t\t\t\t\tcanvasPos[1] = event.pageY - totalOffsetTop;\n\t\t\t\t}\n\t\t\t\treturn canvasPos;\n\t\t\t};\n\t\t})();\n\n\t\tconst localToWorldVec = (function () {\n\t\t\tconst mat = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function (localVec, worldVec) {\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.quaternionToMat4(self._rootNode.quaternion, mat);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(mat, localVec, worldVec);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(worldVec);\n\t\t\t\treturn worldVec;\n\t\t\t};\n\t\t})();\n\n\t\tvar getTranslationPlane = (function () {\n\t\t\tconst planeNormal = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\treturn function (worldAxis) {\n\t\t\t\tconst absX = Math.abs(worldAxis[0]);\n\t\t\t\tif (absX > Math.abs(worldAxis[1]) && absX > Math.abs(worldAxis[2])) {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(worldAxis, [0, 1, 0], planeNormal);\n\t\t\t\t} else {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(worldAxis, [1, 0, 0], planeNormal);\n\t\t\t\t}\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(planeNormal, worldAxis, planeNormal);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(planeNormal);\n\t\t\t\treturn planeNormal;\n\t\t\t};\n\t\t})();\n\n\t\tconst dragTranslateSectionPlane = (function () {\n\t\t\tconst p1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst p2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst worldAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\treturn function (baseAxis, fromMouse, toMouse) {\n\t\t\t\tlocalToWorldVec(baseAxis, worldAxis);\n\t\t\t\tconst planeNormal = getTranslationPlane(worldAxis, fromMouse, toMouse);\n\t\t\t\tgetPointerPlaneIntersect(fromMouse, planeNormal, p1);\n\t\t\t\tgetPointerPlaneIntersect(toMouse, planeNormal, p2);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(p2, p1);\n\t\t\t\tconst dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p2, worldAxis);\n\t\t\t\tself._pos[0] += worldAxis[0] * dot;\n\t\t\t\tself._pos[1] += worldAxis[1] * dot;\n\t\t\t\tself._pos[2] += worldAxis[2] * dot;\n\t\t\t\tself._rootNode.position = self._pos;\n\t\t\t\tif (self._sectionPlane) {\n\t\t\t\t\tself._sectionPlane.pos = self._pos;\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\n\t\tvar dragRotateSectionPlane = (function () {\n\t\t\tconst p1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\tconst p2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\tconst c = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\tconst worldAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\treturn function (baseAxis, fromMouse, toMouse) {\n\t\t\t\tlocalToWorldVec(baseAxis, worldAxis);\n\t\t\t\tconst hasData =\n\t\t\t\t\tgetPointerPlaneIntersect(fromMouse, worldAxis, p1) && getPointerPlaneIntersect(toMouse, worldAxis, p2);\n\t\t\t\tif (!hasData) {\n\t\t\t\t\t// Find intersections with view plane and project down to origin\n\t\t\t\t\tconst planeNormal = getTranslationPlane(worldAxis, fromMouse, toMouse);\n\t\t\t\t\tgetPointerPlaneIntersect(fromMouse, planeNormal, p1, 1); // Ensure plane moves closer to camera so angles become workable\n\t\t\t\t\tgetPointerPlaneIntersect(toMouse, planeNormal, p2, 1);\n\t\t\t\t\tvar dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p1, worldAxis);\n\t\t\t\t\tp1[0] -= dot * worldAxis[0];\n\t\t\t\t\tp1[1] -= dot * worldAxis[1];\n\t\t\t\t\tp1[2] -= dot * worldAxis[2];\n\t\t\t\t\tdot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p2, worldAxis);\n\t\t\t\t\tp2[0] -= dot * worldAxis[0];\n\t\t\t\t\tp2[1] -= dot * worldAxis[1];\n\t\t\t\t\tp2[2] -= dot * worldAxis[2];\n\t\t\t\t}\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(p1);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(p2);\n\t\t\t\tdot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p1, p2);\n\t\t\t\tdot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.clamp(dot, -1.0, 1.0); // Rounding errors cause dot to exceed allowed range\n\t\t\t\tvar incDegrees = Math.acos(dot) * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.RADTODEG;\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(p1, p2, c);\n\t\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(c, worldAxis) < 0.0) {\n\t\t\t\t\tincDegrees = -incDegrees;\n\t\t\t\t}\n\t\t\t\tself._rootNode.rotate(baseAxis, incDegrees);\n\t\t\t\trotateSectionPlane();\n\t\t\t};\n\t\t})();\n\n\t\tvar getPointerPlaneIntersect = (function () {\n\t\t\tconst dir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4([0, 0, 0, 1]);\n\t\t\tconst matrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function (mouse, axis, dest, offset) {\n\t\t\t\toffset = offset || 0;\n\t\t\t\tdir[0] = (mouse[0] / canvas.width) * 2.0 - 1.0;\n\t\t\t\tdir[1] = -((mouse[1] / canvas.height) * 2.0 - 1.0);\n\t\t\t\tdir[2] = 0.0;\n\t\t\t\tdir[3] = 1.0;\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(camera.projMatrix, camera.viewMatrix, matrix); // Unproject norm device coords to view coords\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(matrix);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec4(matrix, dir, dir);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec4Scalar(dir, 1.0 / dir[3]); // This is now point A on the ray in world space\n\t\t\t\tvar rayO = camera.eye; // The direction\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec4(dir, rayO, dir);\n\t\t\t\tconst origin = self._sectionPlane.pos; // Plane origin:\n\t\t\t\tvar d = -_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(origin, axis) - offset;\n\t\t\t\tvar dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(axis, dir);\n\t\t\t\tif (Math.abs(dot) > 0.005) {\n\t\t\t\t\tvar t = -(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(axis, rayO) + d) / dot;\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(dir, t, dest);\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(dest, rayO);\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(dest, origin, dest);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t};\n\t\t})();\n\n\t\tconst rotateSectionPlane = (function () {\n\t\t\tconst dir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst mat = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function () {\n\t\t\t\tif (self.sectionPlane) {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.quaternionToMat4(rootNode.quaternion, mat); // << ---\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(mat, [0, 0, 1], dir);\n\t\t\t\t\tself._setSectionPlaneDir(dir);\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\n\t\t{\n\t\t\tvar mouseDownLeft;\n\t\t\tvar mouseDownMiddle;\n\t\t\tvar mouseDownRight;\n\t\t\tvar down = false;\n\t\t\tvar lastAffordanceMesh;\n\n\t\t\tthis._onCameraControlHover = this._viewer.cameraControl.on(\"hoverEnter\", (hit) => {\n\t\t\t\tif (!this._visible) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (down) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tgrabbed = false;\n\t\t\t\tif (lastAffordanceMesh) {\n\t\t\t\t\tlastAffordanceMesh.visible = false;\n\t\t\t\t}\n\t\t\t\tvar affordanceMesh;\n\t\t\t\tconst meshId = hit.entity.id;\n\t\t\t\tswitch (meshId) {\n\t\t\t\t\tcase this._displayMeshes.xAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.xAxisHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yShaftHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.zAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.zAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.zAxisHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.zAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.xCurveHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xHoop;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xRotate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yCurveHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yHoop;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yRotate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t// case this._displayMeshes.zCurveHandle.id:\n\t\t\t\t\t// \taffordanceMesh = this._affordanceMeshes.zHoop;\n\t\t\t\t\t// \tnextDragAction = DRAG_ACTIONS.zRotate;\n\t\t\t\t\t// \tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\t\treturn; // Not clicked an arrow or hoop\n\t\t\t\t}\n\t\t\t\tif (affordanceMesh) {\n\t\t\t\t\taffordanceMesh.visible = true;\n\t\t\t\t}\n\t\t\t\tlastAffordanceMesh = affordanceMesh;\n\t\t\t\tgrabbed = true;\n\t\t\t});\n\n\t\t\tthis._onCameraControlHoverLeave = this._viewer.cameraControl.on(\"hoverOutEntity\", (hit) => {\n\t\t\t\tif (!this._visible) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (lastAffordanceMesh) {\n\t\t\t\t\tlastAffordanceMesh.visible = false;\n\t\t\t\t}\n\t\t\t\tlastAffordanceMesh = null;\n\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t});\n\n\t\t\t//mousedown\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mousedown\",\n\t\t\t\t(this._canvasMouseDownListener = (e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (!this._visible || !grabbed) return;\n\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = false;\n\t\t\t\t\tswitch (e.which) {\n\t\t\t\t\t\tcase 1: // Left button\n\t\t\t\t\t\t\tmouseDownLeft = true;\n\t\t\t\t\t\t\tdown = true;\n\t\t\t\t\t\t\tvar canvasPos = getClickCoordsWithinElement(e);\n\t\t\t\t\t\t\tdragAction = nextDragAction;\n\t\t\t\t\t\t\tlastCanvasPos[0] = canvasPos[0];\n\t\t\t\t\t\t\tlastCanvasPos[1] = canvasPos[1];\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t);\n\t\t\t//mousemove\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mousemove\",\n\t\t\t\t(this._canvasMouseMoveListener = (e) => {\n\t\t\t\t\tif (!this._visible) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!down) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar canvasPos = getClickCoordsWithinElement(e);\n\t\t\t\t\tconst x = canvasPos[0];\n\t\t\t\t\tconst y = canvasPos[1];\n\n\t\t\t\t\tswitch (dragAction) {\n\t\t\t\t\t\tcase DRAG_ACTIONS.xTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.xRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlastCanvasPos[0] = x;\n\t\t\t\t\tlastCanvasPos[1] = y;\n\t\t\t\t})\n\t\t\t);\n\t\t\t//mouseup\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mouseup\",\n\t\t\t\t(this._canvasMouseUpListener = (e) => {\n\t\t\t\t\tif (!this._visible) return;\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = true;\n\t\t\t\t\tif (!down) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tswitch (e.which) {\n\t\t\t\t\t\tcase 1: // Left button\n\t\t\t\t\t\t\tmouseDownLeft = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 2: // Middle/both buttons\n\t\t\t\t\t\t\tmouseDownMiddle = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 3: // Right button\n\t\t\t\t\t\t\tmouseDownRight = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdown = false;\n\t\t\t\t\tgrabbed = false;\n\t\t\t\t})\n\t\t\t);\n\n\t\t\t//wheel\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"wheel\",\n\t\t\t\t(this._canvasWheelListener = (e) => {\n\t\t\t\t\tif (!this._visible) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar delta = Math.max(-1, Math.min(1, -e.deltaY * 40));\n\t\t\t\t\tif (delta === 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t);\n\n\t\t\tthis._onCameraControlHover = this._viewer.cameraControl.on(\"touchEntity\", (hit) => {\n\t\t\t\tif (!this._visible || down || grabbed) return;\n\t\t\t\tgrabbed = false;\n\t\t\t\tif (lastAffordanceMesh) {\n\t\t\t\t\tlastAffordanceMesh.visible = false;\n\t\t\t\t}\n\t\t\t\tvar affordanceMesh;\n\t\t\t\tconst meshId = hit.entity.id;\n\t\t\t\tswitch (meshId) {\n\t\t\t\t\tcase this._displayMeshes.xAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.xAxisHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yShaftHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.zAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.zAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.zAxisHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.zAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.xCurveHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xHoop;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xRotate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yCurveHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yHoop;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yRotate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t// case this._displayMeshes.zCurveHandle.id:\n\t\t\t\t\t// \taffordanceMesh = this._affordanceMeshes.zHoop;\n\t\t\t\t\t// \tnextDragAction = DRAG_ACTIONS.zRotate;\n\t\t\t\t\t// \tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\t\treturn; // Not clicked an arrow or hoop\n\t\t\t\t}\n\t\t\t\tif (affordanceMesh) {\n\t\t\t\t\taffordanceMesh.visible = true;\n\t\t\t\t}\n\t\t\t\tlastAffordanceMesh = affordanceMesh;\n\t\t\t\tgrabbed = true;\n\t\t\t});\n\t\t\t//touchstart\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchstart\",\n\t\t\t\t(this._canvasMouseDownListener = (e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (!this._visible || !grabbed) return;\n\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = false;\n\t\t\t\t\tdown = true;\n\t\t\t\t\tvar canvasPos = getTouchCoordsWithinElement(e);\n\t\t\t\t\tdragAction = nextDragAction;\n\t\t\t\t\tlastCanvasPos[0] = canvasPos[0];\n\t\t\t\t\tlastCanvasPos[1] = canvasPos[1];\n\t\t\t\t})\n\t\t\t);\n\t\t\t//touchmove\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchmove\",\n\t\t\t\t(this._canvasMouseMoveListener = (e) => {\n\t\t\t\t\tif (!this._visible || !down) return;\n\n\t\t\t\t\tvar canvasPos = getTouchCoordsWithinElement(e);\n\t\t\t\t\tconst x = canvasPos[0];\n\t\t\t\t\tconst y = canvasPos[1];\n\n\t\t\t\t\tswitch (dragAction) {\n\t\t\t\t\t\tcase DRAG_ACTIONS.xTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.xRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlastCanvasPos[0] = x;\n\t\t\t\t\tlastCanvasPos[1] = y;\n\t\t\t\t})\n\t\t\t);\n\t\t\t//touchend\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchend\",\n\t\t\t\t(this._canvasTouchEndListener = (e) => {\n\t\t\t\t\tif (!this._visible) return;\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = true;\n\t\t\t\t\tif (lastAffordanceMesh) {\n\t\t\t\t\t\tlastAffordanceMesh.visible = false;\n\t\t\t\t\t}\n\t\t\t\t\tlastAffordanceMesh = null;\n\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\tdown = false;\n\t\t\t\t\tgrabbed = false;\n\t\t\t\t})\n\t\t\t);\n\t\t\tcanvas.addEventListener(\"touchcancel\", this._canvasTouchEndListener);\n\t\t}\n\t}\n\n\t_destroy() {\n\t\tthis._unbindEvents();\n\t\tthis._destroyNodes();\n\t}\n\n\t_unbindEvents() {\n\t\tconst viewer = this._viewer;\n\t\tconst scene = viewer.scene;\n\t\tconst canvas = scene.canvas.canvas;\n\t\tconst camera = viewer.camera;\n\t\tconst cameraControl = viewer.cameraControl;\n\n\t\tscene.off(this._onSceneTick);\n\n\t\tcanvas.removeEventListener(\"mousedown\", this._canvasMouseDownListener);\n\t\tcanvas.removeEventListener(\"mousemove\", this._canvasMouseMoveListener);\n\t\tcanvas.removeEventListener(\"mouseup\", this._canvasMouseUpListener);\n\t\tcanvas.removeEventListener(\"wheel\", this._canvasWheelListener);\n\t\tcanvas.removeEventListener(\"touchend\", this._canvasTouchEndListener);\n\t\tcanvas.removeEventListener(\"touchcancel\", this._canvasTouchEndListener);\n\n\t\tcamera.off(this._onCameraViewMatrix);\n\t\tcamera.off(this._onCameraProjMatrix);\n\n\t\tcameraControl.off(this._onCameraControlHover);\n\t\tcameraControl.off(this._onCameraControlHoverLeave);\n\t}\n\n\t_destroyNodes() {\n\t\tthis._setSectionPlane(null);\n\t\tthis._rootNode.destroy();\n\t\tthis._displayMeshes = {};\n\t\tthis._affordanceMeshes = {};\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SectionPlanesPlugin/Control.js?");
1917
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Control: () => (/* binding */ Control)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildCylinderGeometry.js */ \"./src/viewer/scene/geometry/builders/buildCylinderGeometry.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildTorusGeometry.js */ \"./src/viewer/scene/geometry/builders/buildTorusGeometry.js\");\n/* harmony import */ var _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../viewer/scene/geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../viewer/scene/materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../viewer/scene/materials/EmphasisMaterial.js */ \"./src/viewer/scene/materials/EmphasisMaterial.js\");\n/* harmony import */ var _viewer_scene_nodes_Node_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../viewer/scene/nodes/Node.js */ \"./src/viewer/scene/nodes/Node.js\");\n/* harmony import */ var _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../viewer/scene/mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _viewer_scene_geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../viewer/scene/geometry/builders/buildSphereGeometry.js */ \"./src/viewer/scene/geometry/builders/buildSphereGeometry.js\");\n/* harmony import */ var _viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../viewer/scene/math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst zeroVec = new Float64Array([0, 0, 1]);\nconst quat = new Float64Array(4);\n\n/**\n * Controls a {@link SectionPlane} with mouse and touch input.\n *\n * @private\n */\nclass Control {\n\t/** @private */\n\tconstructor(plugin) {\n\t\t/**\n\t\t * ID of this Control.\n\t\t *\n\t\t * SectionPlaneControls are mapped by this ID in {@link SectionPlanesPlugin#sectionPlaneControls}.\n\t\t *\n\t\t * @property id\n\t\t * @type {String|Number}\n\t\t */\n\t\tthis.id = null;\n\t\tthis.type = \"control\";\n\n\t\tthis._viewer = plugin.viewer;\n\t\tthis._scene = plugin.viewer.scene;\n\n\t\tthis._visible = false;\n\t\tthis._pos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3(); // Full-precision position of the center of the Control\n\t\tthis._origin = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\tthis._rtcPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\n\t\tthis._baseDir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3(); // Saves direction of clip plane when we start dragging an arrow or ring.\n\t\tthis._rootNode = null; // Root of Node graph that represents this control in the 3D scene\n\t\tthis._displayMeshes = null; // Meshes that are always visible\n\t\tthis._affordanceMeshes = null; // Meshes displayed momentarily for affordance\n\n\t\tthis._ignoreNextSectionPlaneDirUpdate = false;\n\n\t\tthis._createNodes();\n\t\tthis._bindEvents();\n\t}\n\n\t/**\n\t * Called by SectionPlanesPlugin to assign this Control to a SectionPlane.\n\t * SectionPlanesPlugin keeps SectionPlaneControls in a reuse pool.\n\t * Call with a null or undefined value to disconnect the Control ffrom whatever SectionPlane it was assigned to.\n\t * @private\n\t */\n\t_setSectionPlane(sectionPlane) {\n\t\tif (this._sectionPlane) {\n\t\t\tthis._sectionPlane.off(this._onSectionPlanePos);\n\t\t\tthis._sectionPlane.off(this._onSectionPlaneDir);\n\t\t\tthis._onSectionPlanePos = null;\n\t\t\tthis._onSectionPlaneDir = null;\n\t\t\tthis._sectionPlane = null;\n\t\t}\n\t\tif (sectionPlane) {\n\t\t\tthis.id = sectionPlane.id;\n\t\t\tthis._setPos(sectionPlane.pos);\n\t\t\tthis._setDir(sectionPlane.dir);\n\t\t\tthis._sectionPlane = sectionPlane;\n\t\t\tthis._onSectionPlanePos = sectionPlane.on(\"pos\", () => {\n\t\t\t\tthis._setPos(this._sectionPlane.pos);\n\t\t\t});\n\t\t\tthis._onSectionPlaneDir = sectionPlane.on(\"dir\", () => {\n\t\t\t\tif (!this._ignoreNextSectionPlaneDirUpdate) {\n\t\t\t\t\tthis._setDir(this._sectionPlane.dir);\n\t\t\t\t} else {\n\t\t\t\t\tthis._ignoreNextSectionPlaneDirUpdate = false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Gets the {@link SectionPlane} controlled by this Control.\n\t * @returns {SectionPlane} The SectionPlane.\n\t */\n\tget sectionPlane() {\n\t\treturn this._sectionPlane;\n\t}\n\n\t/**\n\t * 设置剖切面位置\n\t * @param {any} value\n\t */\n\tset pos(posRate) {\n\t\tif (posRate < 0 || posRate > 100) return;\n\n\t\tconst { aabb } = this._scene;\n\t\tconst { look } = this._scene.camera;\n\t\tconst xRange = aabb[3] - aabb[0]; //前后\n\t\tconst yRange = aabb[4] - aabb[1]; //上下\n\t\tconst zRange = aabb[5] - aabb[2]; //左右\n\n\t\tconst newSectionPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\tnewSectionPos[0] = this.pos[0];\n\t\tnewSectionPos[1] = this.pos[1];\n\t\tnewSectionPos[2] = this.pos[2];\n\n\t\tconst { dir } = this._sectionPlane;\n\t\tlet rateDis;\n\t\tif (dir[0] != 0) {\n\t\t\trateDis = (posRate / 100) * xRange;\n\t\t\tnewSectionPos[0] = look[0] - xRange / 2 + rateDis;\n\t\t} else if (dir[1] != 0) {\n\t\t\trateDis = (posRate / 100) * yRange;\n\t\t\tnewSectionPos[1] = look[1] - yRange / 2 + rateDis;\n\t\t} else if (dir[2] != 0) {\n\t\t\trateDis = (posRate / 100) * zRange;\n\t\t\tnewSectionPos[2] = look[2] - zRange / 2 + rateDis;\n\t\t}\n\n\t\tthis._sectionPlane.pos = newSectionPos;\n\t}\n\n\tget pos() {\n\t\treturn this._pos;\n\t}\n\n\t/** @private */\n\t_setPos(xyz) {\n\t\tthis._pos.set(xyz);\n\n\t\t(0,_viewer_scene_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_9__.worldToRTCPos)(this._pos, this._origin, this._rtcPos);\n\n\t\tthis._rootNode.origin = this._origin;\n\t\tthis._rootNode.position = this._rtcPos;\n\t}\n\n\t/** @private */\n\t_setDir(xyz) {\n\t\tthis._baseDir.set(xyz);\n\t\tthis._rootNode.quaternion = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3PairToQuaternion(zeroVec, xyz, quat);\n\t}\n\n\t_setSectionPlaneDir(dir) {\n\t\tif (this._sectionPlane) {\n\t\t\tthis._ignoreNextSectionPlaneDirUpdate = true;\n\t\t\tthis._sectionPlane.dir = dir;\n\t\t}\n\t}\n\n\t/**\n\t * Sets if this Control is visible.\n\t *\n\t * @type {Boolean}\n\t */\n\tsetVisible(visible = true) {\n\t\tif (this._visible === visible) {\n\t\t\treturn;\n\t\t}\n\t\tthis._visible = visible;\n\t\tvar id;\n\t\tfor (id in this._displayMeshes) {\n\t\t\tif (this._displayMeshes.hasOwnProperty(id)) {\n\t\t\t\tthis._displayMeshes[id].visible = visible;\n\t\t\t}\n\t\t}\n\t\tif (!visible) {\n\t\t\tfor (id in this._affordanceMeshes) {\n\t\t\t\tif (this._affordanceMeshes.hasOwnProperty(id)) {\n\t\t\t\t\tthis._affordanceMeshes[id].visible = visible;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets if this Control is visible.\n\t *\n\t * @type {Boolean}\n\t */\n\tgetVisible() {\n\t\treturn this._visible;\n\t}\n\n\t/**\n\t * Sets if this Control is culled. This is called by SectionPlanesPlugin to\n\t * temporarily hide the Control while a snapshot is being taken by Viewer#getSnapshot().\n\t * @param culled\n\t */\n\tsetCulled(culled) {\n\t\tvar id;\n\t\tfor (id in this._displayMeshes) {\n\t\t\tif (this._displayMeshes.hasOwnProperty(id)) {\n\t\t\t\tthis._displayMeshes[id].culled = culled;\n\t\t\t}\n\t\t}\n\t\tif (!culled) {\n\t\t\tfor (id in this._affordanceMeshes) {\n\t\t\t\tif (this._affordanceMeshes.hasOwnProperty(id)) {\n\t\t\t\t\tthis._affordanceMeshes[id].culled = culled;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Builds the Entities that represent this Control.\n\t * @private\n\t */\n\t_createNodes() {\n\t\tconst NO_STATE_INHERIT = false;\n\t\tconst scene = this._viewer.scene;\n\t\tconst radius = 1.0;\n\t\tconst handleTubeRadius = 0.06;\n\t\tconst hoopRadius = radius - 0.2;\n\t\tconst tubeRadius = 0.01;\n\t\tconst arrowRadius = 0.07;\n\n\t\tthis._rootNode = new _viewer_scene_nodes_Node_js__WEBPACK_IMPORTED_MODULE_6__.Node(scene, {\n\t\t\tposition: [0, 0, 0],\n\t\t\tscale: [5, 5, 5],\n\t\t\tisObject: false\n\t\t});\n\n\t\tconst rootNode = this._rootNode;\n\n\t\tconst shapes = {\n\t\t\t// Reusable geometries\n\n\t\t\tarrowHead: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: 0.001,\n\t\t\t\t\tradiusBottom: arrowRadius,\n\t\t\t\t\tradialSegments: 32,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: 0.2,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t),\n\n\t\t\tarrowHeadBig: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: 0.001,\n\t\t\t\t\tradiusBottom: 0.09,\n\t\t\t\t\tradialSegments: 32,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: 0.25,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t),\n\n\t\t\tarrowHeadHandle: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: 0.09,\n\t\t\t\t\tradiusBottom: 0.09,\n\t\t\t\t\tradialSegments: 8,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: 0.37,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t),\n\n\t\t\tcurve: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\tradius: hoopRadius,\n\t\t\t\t\ttube: tubeRadius,\n\t\t\t\t\tradialSegments: 64,\n\t\t\t\t\ttubeSegments: 14,\n\t\t\t\t\tarc: (Math.PI * 2.0) / 4.0\n\t\t\t\t})\n\t\t\t),\n\n\t\t\tcurveHandle: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\tradius: hoopRadius,\n\t\t\t\t\ttube: handleTubeRadius,\n\t\t\t\t\tradialSegments: 64,\n\t\t\t\t\ttubeSegments: 14,\n\t\t\t\t\tarc: (Math.PI * 2.0) / 4.0\n\t\t\t\t})\n\t\t\t),\n\n\t\t\thoop: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\tradius: hoopRadius,\n\t\t\t\t\ttube: tubeRadius,\n\t\t\t\t\tradialSegments: 64,\n\t\t\t\t\ttubeSegments: 8,\n\t\t\t\t\tarc: Math.PI * 2.0\n\t\t\t\t})\n\t\t\t),\n\n\t\t\taxis: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: tubeRadius,\n\t\t\t\t\tradiusBottom: tubeRadius,\n\t\t\t\t\tradialSegments: 20,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: radius,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t),\n\n\t\t\taxisHandle: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\trootNode,\n\t\t\t\t(0,_viewer_scene_geometry_builders_buildCylinderGeometry_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry)({\n\t\t\t\t\tradiusTop: 0.08,\n\t\t\t\t\tradiusBottom: 0.08,\n\t\t\t\t\tradialSegments: 20,\n\t\t\t\t\theightSegments: 1,\n\t\t\t\t\theight: radius,\n\t\t\t\t\topenEnded: false\n\t\t\t\t})\n\t\t\t)\n\t\t};\n\n\t\tconst materials = {\n\t\t\t// Reusable materials\n\n\t\t\tpickable: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t// Invisible material for pickable handles, which define a pickable 3D area\n\t\t\t\tdiffuse: [1, 1, 0],\n\t\t\t\talpha: 0, // Invisible\n\t\t\t\talphaMode: \"blend\"\n\t\t\t}),\n\n\t\t\tred: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\tdiffuse: [1, 0.0, 0.0],\n\t\t\t\temissive: [1, 0.0, 0.0],\n\t\t\t\tambient: [0.0, 0.0, 0.0],\n\t\t\t\tspecular: [0.6, 0.6, 0.3],\n\t\t\t\tshininess: 80,\n\t\t\t\tlineWidth: 2\n\t\t\t}),\n\n\t\t\thighlightRed: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t// Emphasis for red rotation affordance hoop\n\t\t\t\tedges: false,\n\t\t\t\tfill: true,\n\t\t\t\tfillColor: [1, 0, 0],\n\t\t\t\tfillAlpha: 0.6\n\t\t\t}),\n\n\t\t\tgreen: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\tdiffuse: [0.0, 1, 0.0],\n\t\t\t\temissive: [0.0, 1, 0.0],\n\t\t\t\tambient: [0.0, 0.0, 0.0],\n\t\t\t\tspecular: [0.6, 0.6, 0.3],\n\t\t\t\tshininess: 80,\n\t\t\t\tlineWidth: 2\n\t\t\t}),\n\n\t\t\thighlightGreen: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t// Emphasis for green rotation affordance hoop\n\t\t\t\tedges: false,\n\t\t\t\tfill: true,\n\t\t\t\tfillColor: [0, 1, 0],\n\t\t\t\tfillAlpha: 0.6\n\t\t\t}),\n\n\t\t\tblue: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\tdiffuse: [0.0, 0.0, 1],\n\t\t\t\temissive: [0.0, 0.0, 1],\n\t\t\t\tambient: [0.0, 0.0, 0.0],\n\t\t\t\tspecular: [0.6, 0.6, 0.3],\n\t\t\t\tshininess: 80,\n\t\t\t\tlineWidth: 2\n\t\t\t}),\n\n\t\t\thighlightBlue: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t// Emphasis for blue rotation affordance hoop\n\t\t\t\tedges: false,\n\t\t\t\tfill: true,\n\t\t\t\tfillColor: [0, 0, 1],\n\t\t\t\tfillAlpha: 0.2\n\t\t\t}),\n\n\t\t\tcenter: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\tdiffuse: [0.0, 0.0, 0.0],\n\t\t\t\temissive: [0, 0, 0],\n\t\t\t\tambient: [0.0, 0.0, 0.0],\n\t\t\t\tspecular: [0.6, 0.6, 0.3],\n\t\t\t\tshininess: 80\n\t\t\t}),\n\n\t\t\thighlightBall: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\tedges: false,\n\t\t\t\tfill: true,\n\t\t\t\tfillColor: [0.5, 0.5, 0.5],\n\t\t\t\tfillAlpha: 0.5,\n\t\t\t\tvertices: false\n\t\t\t}),\n\n\t\t\thighlightPlane: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\tedges: true,\n\t\t\t\tedgeWidth: 3,\n\t\t\t\tfill: false,\n\t\t\t\tfillColor: [0.5, 0.5, 0.5],\n\t\t\t\tfillAlpha: 0.5,\n\t\t\t\tvertices: false\n\t\t\t})\n\t\t};\n\n\t\tthis._displayMeshes = {\n\t\t\tplane: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(rootNode, {\n\t\t\t\t\t\tprimitive: \"triangles\",\n\t\t\t\t\t\tpositions: [\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.0,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.0, // 0\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.0,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.0, // 1\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.0,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.0, // 2\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t-0.0,\n\t\t\t\t\t\t\t-0.5,\n\t\t\t\t\t\t\t0.5,\n\t\t\t\t\t\t\t-0.0 // 3\n\t\t\t\t\t\t],\n\t\t\t\t\t\tindices: [0, 1, 2, 2, 3, 0]\n\t\t\t\t\t}),\n\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t\t\temissive: [0, 0.0, 0],\n\t\t\t\t\t\tdiffuse: [0, 0, 0],\n\t\t\t\t\t\tbackfaces: true\n\t\t\t\t\t}),\n\t\t\t\t\topacity: 0.6,\n\t\t\t\t\tghosted: true,\n\t\t\t\t\tghostMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t\t\tedges: false,\n\t\t\t\t\t\tfilled: true,\n\t\t\t\t\t\tfillColor: [1, 1, 0],\n\t\t\t\t\t\tedgeColor: [0, 0, 0],\n\t\t\t\t\t\tfillAlpha: 0.1,\n\t\t\t\t\t\tbackfaces: true\n\t\t\t\t\t}),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tscale: [2.4, 2.4, 1],\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tplaneFrame: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Visible frame\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\t\t\trootNode,\n\t\t\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\t\t\tcenter: [0, 0, 0],\n\t\t\t\t\t\t\tradius: 1.7,\n\t\t\t\t\t\t\ttube: tubeRadius * 2,\n\t\t\t\t\t\t\tradialSegments: 4,\n\t\t\t\t\t\t\ttubeSegments: 4,\n\t\t\t\t\t\t\tarc: Math.PI * 2.0\n\t\t\t\t\t\t})\n\t\t\t\t\t),\n\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t\t\temissive: [0, 0, 0],\n\t\t\t\t\t\tdiffuse: [0, 0, 0],\n\t\t\t\t\t\tspecular: [0, 0, 0],\n\t\t\t\t\t\tshininess: 0\n\t\t\t\t\t}),\n\t\t\t\t\t//highlighted: true,\n\t\t\t\t\thighlightMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t\t\tedges: false,\n\t\t\t\t\t\tedgeColor: [0.0, 0.0, 0.0],\n\t\t\t\t\t\tfilled: true,\n\t\t\t\t\t\tfillColor: [0.8, 0.8, 0.8],\n\t\t\t\t\t\tfillAlpha: 1.0\n\t\t\t\t\t}),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tscale: [1, 1, 0.1],\n\t\t\t\t\trotation: [0, 0, 45],\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\txCurve: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Red hoop about Y-axis\n\t\t\t\t\tgeometry: shapes.curve,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst rotate2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 1, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(270 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate1, rotate2, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txCurveHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Red hoop about Y-axis\n\t\t\t\t\tgeometry: shapes.curveHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst rotate2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 1, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(270 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate1, rotate2, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txCurveArrow1: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, -0.07, -0.8, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst scale = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.scaleMat4v([0.6, 0.6, 0.6], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(0 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(translate, scale, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()), rotate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txCurveArrow2: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0.0, -0.8, -0.07, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst scale = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.scaleMat4v([0.6, 0.6, 0.6], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(translate, scale, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()), rotate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\tyCurve: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.curve,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\trotation: [-90, 0, 0],\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyCurveHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.curveHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\trotation: [-90, 0, 0],\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyCurveArrow1: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0.07, 0, -0.8, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst scale = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.scaleMat4v([0.6, 0.6, 0.6], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(translate, scale, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()), rotate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyCurveArrow2: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0.8, 0.0, -0.07, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst scale = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.scaleMat4v([0.6, 0.6, 0.6], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(translate, scale, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()), rotate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\t// zCurve: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\t// Blue hoop about Z-axis\n\t\t\t// \t\tgeometry: shapes.curve,\n\t\t\t// \t\tmaterial: materials.blue,\n\t\t\t// \t\tmatrix: math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4()),\n\t\t\t// \t\tpickable: false,\n\t\t\t// \t\tcollidable: false,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// ),\n\n\t\t\t// zCurveHandle: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\tgeometry: shapes.curveHandle,\n\t\t\t// \t\tmaterial: materials.pickable,\n\t\t\t// \t\tmatrix: math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4()),\n\t\t\t// \t\tpickable: true,\n\t\t\t// \t\tcollidable: false,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// ),\n\n\t\t\t// zCurveCurveArrow1: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\tgeometry: shapes.arrowHead,\n\t\t\t// \t\tmaterial: materials.blue,\n\t\t\t// \t\tmatrix: (function () {\n\t\t\t// \t\t\tconst translate = math.translateMat4c(0.8, -0.07, 0, math.identityMat4());\n\t\t\t// \t\t\tconst scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());\n\t\t\t// \t\t\treturn math.mulMat4(translate, scale, math.identityMat4());\n\t\t\t// \t\t})(),\n\t\t\t// \t\tpickable: true,\n\t\t\t// \t\tcollidable: false,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// ),\n\n\t\t\t// zCurveArrow2: rootNode.addChild(\n\t\t\t// \tnew Mesh(rootNode, {\n\t\t\t// \t\tgeometry: shapes.arrowHead,\n\t\t\t// \t\tmaterial: materials.blue,\n\t\t\t// \t\tmatrix: (function () {\n\t\t\t// \t\t\tconst translate = math.translateMat4c(0.05, -0.8, 0, math.identityMat4());\n\t\t\t// \t\t\tconst scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());\n\t\t\t// \t\t\tconst rotate = math.rotationMat4v(90 * math.DEGTORAD, [0, 0, 1], math.identityMat4());\n\t\t\t// \t\t\treturn math.mulMat4(math.mulMat4(translate, scale, math.identityMat4()), rotate, math.identityMat4());\n\t\t\t// \t\t})(),\n\t\t\t// \t\tpickable: true,\n\t\t\t// \t\tcollidable: false,\n\t\t\t// \t\tclippable: false,\n\t\t\t// \t\tvisible: false,\n\t\t\t// \t\tisObject: false\n\t\t\t// \t}),\n\t\t\t// \tNO_STATE_INHERIT\n\t\t\t// ),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\tcenter: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\t\t\trootNode,\n\t\t\t\t\t\t(0,_viewer_scene_geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_8__.buildSphereGeometry)({\n\t\t\t\t\t\t\tradius: 0.05\n\t\t\t\t\t\t})\n\t\t\t\t\t),\n\t\t\t\t\tmaterial: materials.center,\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\txAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txAxisArrowHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txAxis: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axis,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius / 2, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txAxisHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axisHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius / 2, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\tyAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(180 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyAxisArrowHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(180 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\topacity: 0.2,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyShaft: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axis,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tposition: [0, -radius / 2, 0],\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyShaftHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axisHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tposition: [0, -radius / 2, 0],\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t//----------------------------------------------------------------------------------------------------------\n\n\t\t\tzAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHead,\n\t\t\t\t\tmaterial: materials.blue,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0.8, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzAxisArrowHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0.8, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzShaft: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axis,\n\t\t\t\t\tmaterial: materials.blue,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius / 2, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzAxisHandle: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.axisHandle,\n\t\t\t\t\tmaterial: materials.pickable,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius / 2, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tpickable: true,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t)\n\t\t};\n\n\t\tthis._affordanceMeshes = {\n\t\t\tplaneFrame: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: new _viewer_scene_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_3__.ReadableGeometry(\n\t\t\t\t\t\trootNode,\n\t\t\t\t\t\t(0,_viewer_scene_geometry_builders_buildTorusGeometry_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry)({\n\t\t\t\t\t\t\tcenter: [0, 0, 0],\n\t\t\t\t\t\t\tradius: 2,\n\t\t\t\t\t\t\ttube: tubeRadius,\n\t\t\t\t\t\t\tradialSegments: 4,\n\t\t\t\t\t\t\ttubeSegments: 4,\n\t\t\t\t\t\t\tarc: Math.PI * 2.0\n\t\t\t\t\t\t})\n\t\t\t\t\t),\n\t\t\t\t\tmaterial: new _viewer_scene_materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_4__.PhongMaterial(rootNode, {\n\t\t\t\t\t\tambient: [1, 1, 1],\n\t\t\t\t\t\tdiffuse: [0, 0, 0],\n\t\t\t\t\t\temissive: [1, 1, 0]\n\t\t\t\t\t}),\n\t\t\t\t\thighlighted: true,\n\t\t\t\t\thighlightMaterial: new _viewer_scene_materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_5__.EmphasisMaterial(rootNode, {\n\t\t\t\t\t\tedges: false,\n\t\t\t\t\t\tfilled: true,\n\t\t\t\t\t\tfillColor: [1, 1, 0],\n\t\t\t\t\t\tfillAlpha: 1.0\n\t\t\t\t\t}),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tscale: [1, 1, 1],\n\t\t\t\t\trotation: [0, 0, 45],\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txHoop: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Full\n\t\t\t\t\tgeometry: shapes.hoop,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\thighlighted: true,\n\t\t\t\t\thighlightMaterial: materials.highlightRed,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst rotate2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 1, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(270 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate1, rotate2, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyHoop: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.hoop,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\thighlighted: true,\n\t\t\t\t\thighlightMaterial: materials.highlightGreen,\n\t\t\t\t\trotation: [-90, 0, 0],\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzHoop: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\t// Blue hoop about Z-axis\n\t\t\t\t\tgeometry: shapes.hoop,\n\t\t\t\t\tmaterial: materials.blue,\n\t\t\t\t\thighlighted: true,\n\t\t\t\t\thighlightMaterial: materials.highlightBlue,\n\t\t\t\t\tmatrix: _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(180 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4()),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tbackfaces: true,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\txAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadBig,\n\t\t\t\t\tmaterial: materials.red,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0, 0, 1], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tyAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadBig,\n\t\t\t\t\tmaterial: materials.green,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(180 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [1, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t),\n\n\t\t\tzAxisArrow: rootNode.addChild(\n\t\t\t\tnew _viewer_scene_mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_7__.Mesh(rootNode, {\n\t\t\t\t\tgeometry: shapes.arrowHeadBig,\n\t\t\t\t\tmaterial: materials.blue,\n\t\t\t\t\tmatrix: (function () {\n\t\t\t\t\t\tconst translate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.translateMat4c(0, radius + 0.1, 0, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\tconst rotate = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4v(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, [0.8, 0, 0], _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t\treturn _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(rotate, translate, _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.identityMat4());\n\t\t\t\t\t})(),\n\t\t\t\t\tpickable: false,\n\t\t\t\t\tcollidable: false,\n\t\t\t\t\tclippable: false,\n\t\t\t\t\tvisible: false,\n\t\t\t\t\tisObject: false\n\t\t\t\t}),\n\t\t\t\tNO_STATE_INHERIT\n\t\t\t)\n\t\t};\n\t}\n\n\t_bindEvents() {\n\t\tconst self = this;\n\n\t\tvar grabbed = false;\n\n\t\tconst DRAG_ACTIONS = {\n\t\t\tnone: -1,\n\t\t\txTranslate: 0,\n\t\t\tyTranslate: 1,\n\t\t\tzTranslate: 2,\n\t\t\txRotate: 3,\n\t\t\tyRotate: 4,\n\t\t\tzRotate: 5\n\t\t};\n\n\t\tconst rootNode = this._rootNode;\n\n\t\tvar nextDragAction = null; // As we hover grabbed an arrow or hoop, self is the action we would do if we then dragged it.\n\t\tvar dragAction = null; // Action we're doing while we drag an arrow or hoop.\n\t\tconst lastCanvasPos = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec2();\n\n\t\tconst xBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([1, 0, 0]);\n\t\tconst yBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 1, 0]);\n\t\tconst zBaseAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 1]);\n\n\t\tconst canvas = this._viewer.scene.canvas.canvas;\n\t\tconst camera = this._viewer.camera;\n\t\tconst scene = this._viewer.scene;\n\n\t\t{\n\t\t\t// Keep gizmo screen size constant\n\n\t\t\tconst tempVec3a = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3([0, 0, 0]);\n\n\t\t\tlet distDirty = true;\n\t\t\tlet lastDist = -1;\n\n\t\t\tthis._onCameraViewMatrix = scene.camera.on(\"viewMatrix\", () => {\n\t\t\t\tdistDirty = true;\n\t\t\t});\n\n\t\t\tthis._onCameraProjMatrix = scene.camera.on(\"projMatrix\", () => {\n\t\t\t\tdistDirty = true;\n\t\t\t});\n\n\t\t\tthis._onSceneTick = scene.on(\"tick\", () => {\n\t\t\t\tconst dist = Math.abs(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(scene.camera.eye, this._pos, tempVec3a)));\n\n\t\t\t\tif (dist !== lastDist) {\n\t\t\t\t\tif (camera.projection === \"perspective\") {\n\t\t\t\t\t\tconst worldSize = Math.tan(camera.perspective.fov * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD) * dist;\n\t\t\t\t\t\tconst size = 0.07 * worldSize;\n\t\t\t\t\t\trootNode.scale = [size, size, size];\n\t\t\t\t\t\tlastDist = dist;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (camera.projection === \"ortho\") {\n\t\t\t\t\tconst worldSize = camera.ortho.scale / 10;\n\t\t\t\t\tconst size = worldSize;\n\t\t\t\t\trootNode.scale = [size, size, size];\n\t\t\t\t\tlastDist = dist;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tconst getClickCoordsWithinElement = (function () {\n\t\t\tconst canvasPos = new Float64Array(2);\n\t\t\treturn function (event) {\n\t\t\t\tif (!event) {\n\t\t\t\t\tevent = window.event;\n\t\t\t\t\tcanvasPos[0] = event.x;\n\t\t\t\t\tcanvasPos[1] = event.y;\n\t\t\t\t} else {\n\t\t\t\t\tvar element = event.target;\n\t\t\t\t\tvar totalOffsetLeft = 0;\n\t\t\t\t\tvar totalOffsetTop = 0;\n\n\t\t\t\t\twhile (element.offsetParent) {\n\t\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\n\t\t\t\t\t\ttotalOffsetTop += element.offsetTop;\n\t\t\t\t\t\telement = element.offsetParent;\n\t\t\t\t\t}\n\t\t\t\t\tcanvasPos[0] = event.pageX - totalOffsetLeft;\n\t\t\t\t\tcanvasPos[1] = event.pageY - totalOffsetTop;\n\t\t\t\t}\n\t\t\t\treturn canvasPos;\n\t\t\t};\n\t\t})();\n\n\t\tconst getTouchCoordsWithinElement = (function () {\n\t\t\tconst canvasPos = new Float64Array(2);\n\t\t\treturn function (event) {\n\t\t\t\tif (!event) {\n\t\t\t\t\tevent = window.event;\n\t\t\t\t}\n\t\t\t\tif (event.touches && event.touches.length) {\n\t\t\t\t\t// 如果有触摸事件,使用第一个触摸点的坐标\n\t\t\t\t\tcanvasPos[0] = event.touches[0].pageX;\n\t\t\t\t\tcanvasPos[1] = event.touches[0].pageY;\n\t\t\t\t} else {\n\t\t\t\t\t// 否则,假设是鼠标事件\n\t\t\t\t\tvar element = event.target;\n\t\t\t\t\tvar totalOffsetLeft = 0;\n\t\t\t\t\tvar totalOffsetTop = 0;\n\n\t\t\t\t\twhile (element.offsetParent) {\n\t\t\t\t\t\ttotalOffsetLeft += element.offsetLeft;\n\t\t\t\t\t\ttotalOffsetTop += element.offsetTop;\n\t\t\t\t\t\telement = element.offsetParent;\n\t\t\t\t\t}\n\t\t\t\t\tcanvasPos[0] = event.pageX - totalOffsetLeft;\n\t\t\t\t\tcanvasPos[1] = event.pageY - totalOffsetTop;\n\t\t\t\t}\n\t\t\t\treturn canvasPos;\n\t\t\t};\n\t\t})();\n\n\t\tconst localToWorldVec = (function () {\n\t\t\tconst mat = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function (localVec, worldVec) {\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.quaternionToMat4(self._rootNode.quaternion, mat);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(mat, localVec, worldVec);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(worldVec);\n\t\t\t\treturn worldVec;\n\t\t\t};\n\t\t})();\n\n\t\tvar getTranslationPlane = (function () {\n\t\t\tconst planeNormal = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\treturn function (worldAxis) {\n\t\t\t\tconst absX = Math.abs(worldAxis[0]);\n\t\t\t\tif (absX > Math.abs(worldAxis[1]) && absX > Math.abs(worldAxis[2])) {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(worldAxis, [0, 1, 0], planeNormal);\n\t\t\t\t} else {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(worldAxis, [1, 0, 0], planeNormal);\n\t\t\t\t}\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(planeNormal, worldAxis, planeNormal);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(planeNormal);\n\t\t\t\treturn planeNormal;\n\t\t\t};\n\t\t})();\n\n\t\tconst dragTranslateSectionPlane = (function () {\n\t\t\tconst p1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst p2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst worldAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\treturn function (baseAxis, fromMouse, toMouse) {\n\t\t\t\tlocalToWorldVec(baseAxis, worldAxis);\n\t\t\t\tconst planeNormal = getTranslationPlane(worldAxis, fromMouse, toMouse);\n\t\t\t\tgetPointerPlaneIntersect(fromMouse, planeNormal, p1);\n\t\t\t\tgetPointerPlaneIntersect(toMouse, planeNormal, p2);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(p2, p1);\n\t\t\t\tconst dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p2, worldAxis);\n\t\t\t\tself._pos[0] += worldAxis[0] * dot;\n\t\t\t\tself._pos[1] += worldAxis[1] * dot;\n\t\t\t\tself._pos[2] += worldAxis[2] * dot;\n\t\t\t\tself._rootNode.position = self._pos;\n\t\t\t\tif (self._sectionPlane) {\n\t\t\t\t\tself._sectionPlane.pos = self._pos;\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\n\t\tvar dragRotateSectionPlane = (function () {\n\t\t\tconst p1 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\tconst p2 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\tconst c = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\tconst worldAxis = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\n\t\t\treturn function (baseAxis, fromMouse, toMouse) {\n\t\t\t\tlocalToWorldVec(baseAxis, worldAxis);\n\t\t\t\tconst hasData =\n\t\t\t\t\tgetPointerPlaneIntersect(fromMouse, worldAxis, p1) && getPointerPlaneIntersect(toMouse, worldAxis, p2);\n\t\t\t\tif (!hasData) {\n\t\t\t\t\t// Find intersections with view plane and project down to origin\n\t\t\t\t\tconst planeNormal = getTranslationPlane(worldAxis, fromMouse, toMouse);\n\t\t\t\t\tgetPointerPlaneIntersect(fromMouse, planeNormal, p1, 1); // Ensure plane moves closer to camera so angles become workable\n\t\t\t\t\tgetPointerPlaneIntersect(toMouse, planeNormal, p2, 1);\n\t\t\t\t\tvar dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p1, worldAxis);\n\t\t\t\t\tp1[0] -= dot * worldAxis[0];\n\t\t\t\t\tp1[1] -= dot * worldAxis[1];\n\t\t\t\t\tp1[2] -= dot * worldAxis[2];\n\t\t\t\t\tdot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p2, worldAxis);\n\t\t\t\t\tp2[0] -= dot * worldAxis[0];\n\t\t\t\t\tp2[1] -= dot * worldAxis[1];\n\t\t\t\t\tp2[2] -= dot * worldAxis[2];\n\t\t\t\t}\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(p1);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(p2);\n\t\t\t\tdot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(p1, p2);\n\t\t\t\tdot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.clamp(dot, -1.0, 1.0); // Rounding errors cause dot to exceed allowed range\n\t\t\t\tvar incDegrees = Math.acos(dot) * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.RADTODEG;\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(p1, p2, c);\n\t\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(c, worldAxis) < 0.0) {\n\t\t\t\t\tincDegrees = -incDegrees;\n\t\t\t\t}\n\t\t\t\tself._rootNode.rotate(baseAxis, incDegrees);\n\t\t\t\trotateSectionPlane();\n\t\t\t};\n\t\t})();\n\n\t\tvar getPointerPlaneIntersect = (function () {\n\t\t\tconst dir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4([0, 0, 0, 1]);\n\t\t\tconst matrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function (mouse, axis, dest, offset) {\n\t\t\t\toffset = offset || 0;\n\t\t\t\tdir[0] = (mouse[0] / canvas.width) * 2.0 - 1.0;\n\t\t\t\tdir[1] = -((mouse[1] / canvas.height) * 2.0 - 1.0);\n\t\t\t\tdir[2] = 0.0;\n\t\t\t\tdir[3] = 1.0;\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4(camera.projMatrix, camera.viewMatrix, matrix); // Unproject norm device coords to view coords\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(matrix);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec4(matrix, dir, dir);\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec4Scalar(dir, 1.0 / dir[3]); // This is now point A on the ray in world space\n\t\t\t\tvar rayO = camera.eye; // The direction\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec4(dir, rayO, dir);\n\t\t\t\tconst origin = self._sectionPlane.pos; // Plane origin:\n\t\t\t\tvar d = -_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(origin, axis) - offset;\n\t\t\t\tvar dot = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(axis, dir);\n\t\t\t\tif (Math.abs(dot) > 0.005) {\n\t\t\t\t\tvar t = -(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec3(axis, rayO) + d) / dot;\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(dir, t, dest);\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(dest, rayO);\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(dest, origin, dest);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t};\n\t\t})();\n\n\t\tconst rotateSectionPlane = (function () {\n\t\t\tconst dir = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\t\t\tconst mat = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4();\n\t\t\treturn function () {\n\t\t\t\tif (self.sectionPlane) {\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.quaternionToMat4(rootNode.quaternion, mat); // << ---\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(mat, [0, 0, 1], dir);\n\t\t\t\t\tself._setSectionPlaneDir(dir);\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\n\t\t{\n\t\t\tvar mouseDownLeft;\n\t\t\tvar mouseDownMiddle;\n\t\t\tvar mouseDownRight;\n\t\t\tvar down = false;\n\t\t\tvar lastAffordanceMesh;\n\n\t\t\tthis._onCameraControlHover = this._viewer.cameraControl.on(\"hoverEnter\", (hit) => {\n\t\t\t\tif (!this._visible) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (down) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tgrabbed = false;\n\t\t\t\tif (lastAffordanceMesh) {\n\t\t\t\t\tlastAffordanceMesh.visible = false;\n\t\t\t\t}\n\t\t\t\tvar affordanceMesh;\n\t\t\t\tconst meshId = hit.entity.id;\n\t\t\t\tswitch (meshId) {\n\t\t\t\t\tcase this._displayMeshes.xAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.xAxisHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yShaftHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.zAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.zAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.zAxisHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.zAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.xCurveHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xHoop;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xRotate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yCurveHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yHoop;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yRotate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t// case this._displayMeshes.zCurveHandle.id:\n\t\t\t\t\t// \taffordanceMesh = this._affordanceMeshes.zHoop;\n\t\t\t\t\t// \tnextDragAction = DRAG_ACTIONS.zRotate;\n\t\t\t\t\t// \tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\t\treturn; // Not clicked an arrow or hoop\n\t\t\t\t}\n\t\t\t\tif (affordanceMesh) {\n\t\t\t\t\taffordanceMesh.visible = true;\n\t\t\t\t}\n\t\t\t\tlastAffordanceMesh = affordanceMesh;\n\t\t\t\tgrabbed = true;\n\t\t\t});\n\n\t\t\tthis._onCameraControlHoverLeave = this._viewer.cameraControl.on(\"hoverOutEntity\", (hit) => {\n\t\t\t\tif (!this._visible) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (lastAffordanceMesh) {\n\t\t\t\t\tlastAffordanceMesh.visible = false;\n\t\t\t\t}\n\t\t\t\tlastAffordanceMesh = null;\n\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t});\n\n\t\t\t//mousedown\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mousedown\",\n\t\t\t\t(this._canvasMouseDownListener = (e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (!this._visible || !grabbed) return;\n\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = false;\n\t\t\t\t\tswitch (e.which) {\n\t\t\t\t\t\tcase 1: // Left button\n\t\t\t\t\t\t\tmouseDownLeft = true;\n\t\t\t\t\t\t\tdown = true;\n\t\t\t\t\t\t\tvar canvasPos = getClickCoordsWithinElement(e);\n\t\t\t\t\t\t\tdragAction = nextDragAction;\n\t\t\t\t\t\t\tlastCanvasPos[0] = canvasPos[0];\n\t\t\t\t\t\t\tlastCanvasPos[1] = canvasPos[1];\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t);\n\t\t\t//mousemove\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mousemove\",\n\t\t\t\t(this._canvasMouseMoveListener = (e) => {\n\t\t\t\t\tif (!this._visible) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!down) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar canvasPos = getClickCoordsWithinElement(e);\n\t\t\t\t\tconst x = canvasPos[0];\n\t\t\t\t\tconst y = canvasPos[1];\n\n\t\t\t\t\tswitch (dragAction) {\n\t\t\t\t\t\tcase DRAG_ACTIONS.xTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.xRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlastCanvasPos[0] = x;\n\t\t\t\t\tlastCanvasPos[1] = y;\n\t\t\t\t})\n\t\t\t);\n\t\t\t//mouseup\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"mouseup\",\n\t\t\t\t(this._canvasMouseUpListener = (e) => {\n\t\t\t\t\tif (!this._visible) return;\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = true;\n\t\t\t\t\tif (!down) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tswitch (e.which) {\n\t\t\t\t\t\tcase 1: // Left button\n\t\t\t\t\t\t\tmouseDownLeft = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 2: // Middle/both buttons\n\t\t\t\t\t\t\tmouseDownMiddle = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 3: // Right button\n\t\t\t\t\t\t\tmouseDownRight = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdown = false;\n\t\t\t\t\tgrabbed = false;\n\t\t\t\t})\n\t\t\t);\n\n\t\t\t//wheel\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"wheel\",\n\t\t\t\t(this._canvasWheelListener = (e) => {\n\t\t\t\t\tif (!this._visible) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar delta = Math.max(-1, Math.min(1, -e.deltaY * 40));\n\t\t\t\t\tif (delta === 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t);\n\n\t\t\tthis._onCameraControlHover = this._viewer.cameraControl.on(\"touchEntity\", (hit) => {\n\t\t\t\tif (!this._visible || down || grabbed) return;\n\t\t\t\tgrabbed = false;\n\t\t\t\tif (lastAffordanceMesh) {\n\t\t\t\t\tlastAffordanceMesh.visible = false;\n\t\t\t\t}\n\t\t\t\tvar affordanceMesh;\n\t\t\t\tconst meshId = hit.entity.id;\n\t\t\t\tswitch (meshId) {\n\t\t\t\t\tcase this._displayMeshes.xAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.xAxisHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yShaftHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.zAxisArrowHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.zAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.zAxisHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.zAxisArrow;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.zTranslate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.xCurveHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.xHoop;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.xRotate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase this._displayMeshes.yCurveHandle.id:\n\t\t\t\t\t\taffordanceMesh = this._affordanceMeshes.yHoop;\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.yRotate;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t// case this._displayMeshes.zCurveHandle.id:\n\t\t\t\t\t// \taffordanceMesh = this._affordanceMeshes.zHoop;\n\t\t\t\t\t// \tnextDragAction = DRAG_ACTIONS.zRotate;\n\t\t\t\t\t// \tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\t\treturn; // Not clicked an arrow or hoop\n\t\t\t\t}\n\t\t\t\tif (affordanceMesh) {\n\t\t\t\t\taffordanceMesh.visible = true;\n\t\t\t\t}\n\t\t\t\tlastAffordanceMesh = affordanceMesh;\n\t\t\t\tgrabbed = true;\n\t\t\t});\n\t\t\t//touchstart\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchstart\",\n\t\t\t\t(this._canvasMouseDownListener = (e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (!this._visible || !grabbed) return;\n\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = false;\n\t\t\t\t\tdown = true;\n\t\t\t\t\tvar canvasPos = getTouchCoordsWithinElement(e);\n\t\t\t\t\tdragAction = nextDragAction;\n\t\t\t\t\tlastCanvasPos[0] = canvasPos[0];\n\t\t\t\t\tlastCanvasPos[1] = canvasPos[1];\n\t\t\t\t})\n\t\t\t);\n\t\t\t//touchmove\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchmove\",\n\t\t\t\t(this._canvasMouseMoveListener = (e) => {\n\t\t\t\t\tif (!this._visible || !down) return;\n\n\t\t\t\t\tvar canvasPos = getTouchCoordsWithinElement(e);\n\t\t\t\t\tconst x = canvasPos[0];\n\t\t\t\t\tconst y = canvasPos[1];\n\n\t\t\t\t\tswitch (dragAction) {\n\t\t\t\t\t\tcase DRAG_ACTIONS.xTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zTranslate:\n\t\t\t\t\t\t\tdragTranslateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.xRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.yRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DRAG_ACTIONS.zRotate:\n\t\t\t\t\t\t\tdragRotateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlastCanvasPos[0] = x;\n\t\t\t\t\tlastCanvasPos[1] = y;\n\t\t\t\t})\n\t\t\t);\n\t\t\t//touchend\n\t\t\tcanvas.addEventListener(\n\t\t\t\t\"touchend\",\n\t\t\t\t(this._canvasTouchEndListener = (e) => {\n\t\t\t\t\tif (!this._visible) return;\n\t\t\t\t\tthis._viewer.cameraControl.pointerEnabled = true;\n\t\t\t\t\tif (lastAffordanceMesh) {\n\t\t\t\t\t\tlastAffordanceMesh.visible = false;\n\t\t\t\t\t}\n\t\t\t\t\tlastAffordanceMesh = null;\n\t\t\t\t\tnextDragAction = DRAG_ACTIONS.none;\n\t\t\t\t\tdown = false;\n\t\t\t\t\tgrabbed = false;\n\t\t\t\t})\n\t\t\t);\n\t\t\tcanvas.addEventListener(\"touchcancel\", this._canvasTouchEndListener);\n\t\t}\n\t}\n\n\t_destroy() {\n\t\tthis._unbindEvents();\n\t\tthis._destroyNodes();\n\t}\n\n\t_unbindEvents() {\n\t\tconst viewer = this._viewer;\n\t\tconst scene = viewer.scene;\n\t\tconst canvas = scene.canvas.canvas;\n\t\tconst camera = viewer.camera;\n\t\tconst cameraControl = viewer.cameraControl;\n\n\t\tscene.off(this._onSceneTick);\n\n\t\tcanvas.removeEventListener(\"mousedown\", this._canvasMouseDownListener);\n\t\tcanvas.removeEventListener(\"mousemove\", this._canvasMouseMoveListener);\n\t\tcanvas.removeEventListener(\"mouseup\", this._canvasMouseUpListener);\n\t\tcanvas.removeEventListener(\"wheel\", this._canvasWheelListener);\n\t\tcanvas.removeEventListener(\"touchend\", this._canvasTouchEndListener);\n\t\tcanvas.removeEventListener(\"touchcancel\", this._canvasTouchEndListener);\n\n\t\tcamera.off(this._onCameraViewMatrix);\n\t\tcamera.off(this._onCameraProjMatrix);\n\n\t\tcameraControl.off(this._onCameraControlHover);\n\t\tcameraControl.off(this._onCameraControlHoverLeave);\n\t}\n\n\t_destroyNodes() {\n\t\tthis._setSectionPlane(null);\n\t\tthis._rootNode.destroy();\n\t\tthis._displayMeshes = {};\n\t\tthis._affordanceMeshes = {};\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SectionPlanesPlugin/Control.js?");
1908
1918
 
1909
1919
  /***/ }),
1910
1920
 
@@ -1914,7 +1924,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1914
1924
  \*****************************************************/
1915
1925
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1916
1926
 
1917
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Overview: () => (/* binding */ Overview)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_scene_Scene_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/scene/Scene.js */ \"./src/viewer/scene/scene/Scene.js\");\n/* harmony import */ var _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./../../viewer/scene/lights/DirLight.js */ \"./src/viewer/scene/lights/DirLight.js\");\n/* harmony import */ var _Plane_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Plane.js */ \"./src/plugins/SectionPlanesPlugin/Plane.js\");\n\r\n\r\n\r\n\r\n\r\n/**\r\n * @desc An interactive 3D overview for navigating the {@link SectionPlane}s created by its {@link SectionPlanesPlugin}.\r\n *\r\n * * Located at {@link SectionPlanesPlugin#overview}.\r\n * * Renders the overview on a separate canvas at a corner of the {@link Viewer}'s {@link Scene} {@link Canvas}.\r\n * * The overview shows a 3D plane object for each {@link SectionPlane} in the {@link Scene}.\r\n * * Click a plane object in the overview to toggle the visibility of a 3D gizmo to edit the position and orientation of its {@link SectionPlane}.\r\n *\r\n * @private\r\n */\r\nclass Overview {\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tconstructor(plugin, cfg) {\r\n\t\tif (!cfg.onHoverEnterPlane || !cfg.onHoverLeavePlane || !cfg.onClickedNothing || !cfg.onClickedPlane) {\r\n\t\t\tthrow \"Missing config(s): onHoverEnterPlane, onHoverLeavePlane, onClickedNothing || onClickedPlane\";\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * The {@link SectionPlanesPlugin} that owns this SectionPlanesOverview.\r\n\t\t *\r\n\t\t * @type {SectionPlanesPlugin}\r\n\t\t */\r\n\t\tthis.plugin = plugin;\r\n\r\n\t\tthis._viewer = plugin.viewer;\r\n\r\n\t\tthis._onHoverEnterPlane = cfg.onHoverEnterPlane;\r\n\t\tthis._onHoverLeavePlane = cfg.onHoverLeavePlane;\r\n\t\tthis._onClickedNothing = cfg.onClickedNothing;\r\n\t\tthis._onClickedPlane = cfg.onClickedPlane;\r\n\t\tthis._visible = true;\r\n\r\n\t\tthis._planes = {};\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Init canvas\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\tthis._canvas = cfg.overviewCanvas;\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Init scene\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\tthis._scene = new _viewer_scene_scene_Scene_js__WEBPACK_IMPORTED_MODULE_1__.Scene(this._viewer, {\r\n\t\t\tcanvasId: this._canvas.id,\r\n\t\t\ttransparent: true,\r\n\t\t\tspinnerElementId: \"overviewer_spinner\"\r\n\t\t});\r\n\t\tthis._scene.clearLights();\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_2__.DirLight(this._scene, {\r\n\t\t\tdir: [0.4, -0.4, 0.8],\r\n\t\t\tcolor: [0.8, 1.0, 1.0],\r\n\t\t\tintensity: 1.0,\r\n\t\t\tspace: \"view\"\r\n\t\t});\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_2__.DirLight(this._scene, {\r\n\t\t\tdir: [-0.8, -0.3, -0.4],\r\n\t\t\tcolor: [0.8, 0.8, 0.8],\r\n\t\t\tintensity: 1.0,\r\n\t\t\tspace: \"view\"\r\n\t\t});\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_2__.DirLight(this._scene, {\r\n\t\t\tdir: [0.8, -0.6, -0.8],\r\n\t\t\tcolor: [1.0, 1.0, 1.0],\r\n\t\t\tintensity: 1.0,\r\n\t\t\tspace: \"view\"\r\n\t\t});\r\n\r\n\t\tthis._scene.camera;\r\n\t\tthis._scene.camera.perspective.fov = 70;\r\n\r\n\t\tthis._zUp = false;\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Synchronize overview scene camera with viewer camera\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\t{\r\n\t\t\tconst camera = this._scene.camera;\r\n\t\t\tconst matrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4c(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, 1, 0, 0);\r\n\t\t\tconst eyeLookVec = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\t\tconst eyeLookVecOverview = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\t\tconst upOverview = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n\t\t\tthis._synchCamera = () => {\r\n\t\t\t\tconst eye = this._viewer.camera.eye;\r\n\t\t\t\tconst look = this._viewer.camera.look;\r\n\t\t\t\tconst up = this._viewer.camera.up;\r\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(eye, look, eyeLookVec)), 7);\r\n\t\t\t\tif (this._zUp) {\r\n\t\t\t\t\t// +Z up\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(matrix, eyeLookVec, eyeLookVecOverview);\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(matrix, up, upOverview);\r\n\t\t\t\t\tcamera.look = [0, 0, 0];\r\n\t\t\t\t\tcamera.eye = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(matrix, eyeLookVec, eyeLookVecOverview);\r\n\t\t\t\t\tcamera.up = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint3(matrix, up, upOverview);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// +Y up\r\n\t\t\t\t\tcamera.look = [0, 0, 0];\r\n\t\t\t\t\tcamera.eye = eyeLookVec;\r\n\t\t\t\t\tcamera.up = up;\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tthis._onViewerCameraMatrix = this._viewer.camera.on(\"matrix\", this._synchCamera);\r\n\r\n\t\tthis._onViewerCameraWorldAxis = this._viewer.camera.on(\"worldAxis\", this._synchCamera);\r\n\r\n\t\tthis._onViewerCameraFOV = this._viewer.camera.perspective.on(\"fov\", (fov) => {\r\n\t\t\tthis._scene.camera.perspective.fov = fov;\r\n\t\t});\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Bind overview canvas events\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\t{\r\n\t\t\tvar hoveredEntity = null;\r\n\r\n\t\t\tthis._onInputMouseMove = this._scene.input.on(\"mousemove\", (coords) => {\r\n\t\t\t\tconst hit = this._scene.pick({\r\n\t\t\t\t\tcanvasPos: coords\r\n\t\t\t\t});\r\n\t\t\t\tif (hit) {\r\n\t\t\t\t\tif (!hoveredEntity || hit.entity.id !== hoveredEntity.id) {\r\n\t\t\t\t\t\tif (hoveredEntity) {\r\n\t\t\t\t\t\t\tconst plane = this._planes[hoveredEntity.id];\r\n\t\t\t\t\t\t\tif (plane) {\r\n\t\t\t\t\t\t\t\tthis._onHoverLeavePlane(hoveredEntity.id);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\thoveredEntity = hit.entity;\r\n\t\t\t\t\t\tconst plane = this._planes[hoveredEntity.id];\r\n\t\t\t\t\t\tif (plane) {\r\n\t\t\t\t\t\t\tthis._onHoverEnterPlane(hoveredEntity.id);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (hoveredEntity) {\r\n\t\t\t\t\t\tthis._onHoverLeavePlane(hoveredEntity.id);\r\n\t\t\t\t\t\thoveredEntity = null;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tthis._scene.canvas.canvas.addEventListener(\r\n\t\t\t\t\"mouseup\",\r\n\t\t\t\t(this._onCanvasMouseUp = () => {\r\n\t\t\t\t\tif (hoveredEntity) {\r\n\t\t\t\t\t\tconst plane = this._planes[hoveredEntity.id];\r\n\t\t\t\t\t\tif (plane) {\r\n\t\t\t\t\t\t\tthis._onClickedPlane(hoveredEntity.id);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis._onClickedNothing();\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tthis._scene.canvas.canvas.addEventListener(\r\n\t\t\t\t\"mouseout\",\r\n\t\t\t\t(this._onCanvasMouseOut = () => {\r\n\t\t\t\t\tif (hoveredEntity) {\r\n\t\t\t\t\t\tthis._onHoverLeavePlane(hoveredEntity.id);\r\n\t\t\t\t\t\thoveredEntity = null;\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Configure overview\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\tthis.setVisible(cfg.overviewVisible);\r\n\t}\r\n\r\n\t/** Called by SectionPlanesPlugin#createSectionPlane()\r\n\t * @private\r\n\t */\r\n\taddSectionPlane(sectionPlane) {\r\n\t\tthis._planes[sectionPlane.id] = new _Plane_js__WEBPACK_IMPORTED_MODULE_3__.Plane(this, this._scene, sectionPlane);\r\n\t}\r\n\r\n\t/** @private\r\n\t */\r\n\tsetPlaneHighlighted(id, highlighted) {\r\n\t\tconst plane = this._planes[id];\r\n\t\tif (plane) {\r\n\t\t\tplane.setHighlighted(highlighted);\r\n\t\t}\r\n\t}\r\n\r\n\t/** @private\r\n\t */\r\n\tsetPlaneSelected(id, selected) {\r\n\t\tconst plane = this._planes[id];\r\n\t\tif (plane) {\r\n\t\t\tplane.setSelected(selected);\r\n\t\t}\r\n\t}\r\n\r\n\t/** @private\r\n\t */\r\n\tremoveSectionPlane(sectionPlane) {\r\n\t\tconst plane = this._planes[sectionPlane.id];\r\n\t\tif (plane) {\r\n\t\t\tplane.destroy();\r\n\t\t\tdelete this._planes[sectionPlane.id];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if this SectionPlanesOverview is visible.\r\n\t *\r\n\t * @param {Boolean} visible Whether or not this SectionPlanesOverview is visible.\r\n\t */\r\n\tsetVisible(visible = true) {\r\n\t\tthis._visible = visible;\r\n\t\tthis._canvas.style.visibility = visible ? \"visible\" : \"hidden\";\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if this SectionPlanesOverview is visible.\r\n\t *\r\n\t * @return {Boolean} True when this SectionPlanesOverview is visible.\r\n\t */\r\n\tgetVisible() {\r\n\t\treturn this._visible;\r\n\t}\r\n\r\n\t/** @private\r\n\t */\r\n\tdestroy() {\r\n\t\tthis._viewer.camera.off(this._onViewerCameraMatrix);\r\n\t\tthis._viewer.camera.off(this._onViewerCameraWorldAxis);\r\n\t\tthis._viewer.camera.perspective.off(this._onViewerCameraFOV);\r\n\r\n\t\tthis._scene.input.off(this._onInputMouseMove);\r\n\t\tthis._scene.canvas.canvas.removeEventListener(\"mouseup\", this._onCanvasMouseUp);\r\n\t\tthis._scene.canvas.canvas.removeEventListener(\"mouseout\", this._onCanvasMouseOut);\r\n\t\tthis._scene.destroy();\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SectionPlanesPlugin/Overview.js?");
1927
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Overview: () => (/* binding */ Overview)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_scene_Scene_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/scene/Scene.js */ \"./src/viewer/scene/scene/Scene.js\");\n/* harmony import */ var _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./../../viewer/scene/lights/DirLight.js */ \"./src/viewer/scene/lights/DirLight.js\");\n/* harmony import */ var _Plane_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Plane.js */ \"./src/plugins/SectionPlanesPlugin/Plane.js\");\n/* harmony import */ var _Box_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Box.js */ \"./src/plugins/SectionPlanesPlugin/Box.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * @desc An interactive 3D overview for navigating the {@link SectionPlane}s created by its {@link SectionPlanesPlugin}.\r\n *\r\n * * Located at {@link SectionPlanesPlugin#overview}.\r\n * * Renders the overview on a separate canvas at a corner of the {@link Viewer}'s {@link Scene} {@link Canvas}.\r\n * * The overview shows a 3D plane object for each {@link SectionPlane} in the {@link Scene}.\r\n * * Click a plane object in the overview to toggle the visibility of a 3D gizmo to edit the position and orientation of its {@link SectionPlane}.\r\n *\r\n * @private\r\n */\r\nclass Overview {\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tconstructor(plugin, cfg) {\r\n\t\tif (!cfg.onHoverEnterPlane || !cfg.onHoverLeavePlane || !cfg.onClickedNothing || !cfg.onClickedPlane) {\r\n\t\t\tthrow \"Missing config(s): onHoverEnterPlane, onHoverLeavePlane, onClickedNothing || onClickedPlane\";\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * The {@link SectionPlanesPlugin} that owns this SectionPlanesOverview.\r\n\t\t *\r\n\t\t * @type {SectionPlanesPlugin}\r\n\t\t */\r\n\t\tthis.plugin = plugin;\r\n\r\n\t\tthis._viewer = plugin.viewer;\r\n\r\n\t\tthis._onHoverEnterPlane = cfg.onHoverEnterPlane;\r\n\t\tthis._onHoverLeavePlane = cfg.onHoverLeavePlane;\r\n\t\tthis._onClickedNothing = cfg.onClickedNothing;\r\n\t\tthis._onClickedPlane = cfg.onClickedPlane;\r\n\t\tthis._visible = true;\r\n\r\n\t\tthis._planes = {};\r\n\t\tthis._box = null;\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Init canvas\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\tthis._canvas = cfg.overviewCanvas;\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Init scene\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\tthis._scene = new _viewer_scene_scene_Scene_js__WEBPACK_IMPORTED_MODULE_1__.Scene(this._viewer, {\r\n\t\t\tcanvasId: this._canvas.id,\r\n\t\t\ttransparent: true,\r\n\t\t\tspinnerElementId: \"overviewer_spinner\"\r\n\t\t});\r\n\t\tthis._scene.clearLights();\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_2__.DirLight(this._scene, {\r\n\t\t\tdir: [0.4, -0.4, 0.8],\r\n\t\t\tcolor: [0.8, 1.0, 1.0],\r\n\t\t\tintensity: 1.0,\r\n\t\t\tspace: \"view\"\r\n\t\t});\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_2__.DirLight(this._scene, {\r\n\t\t\tdir: [-0.8, -0.3, -0.4],\r\n\t\t\tcolor: [0.8, 0.8, 0.8],\r\n\t\t\tintensity: 1.0,\r\n\t\t\tspace: \"view\"\r\n\t\t});\r\n\t\tnew _viewer_scene_lights_DirLight_js__WEBPACK_IMPORTED_MODULE_2__.DirLight(this._scene, {\r\n\t\t\tdir: [0.8, -0.6, -0.8],\r\n\t\t\tcolor: [1.0, 1.0, 1.0],\r\n\t\t\tintensity: 1.0,\r\n\t\t\tspace: \"view\"\r\n\t\t});\r\n\r\n\t\tthis._scene.camera;\r\n\t\tthis._scene.camera.perspective.fov = 70;\r\n\r\n\t\tthis._zUp = false;\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Synchronize overview scene camera with viewer camera\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\t{\r\n\t\t\tconst camera = this._scene.camera;\r\n\t\t\tconst matrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.rotationMat4c(-90 * _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD, 1, 0, 0);\r\n\t\t\tconst eyeLookVec = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\t\tconst eyeLookVecOverview = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\t\tconst upOverview = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n\t\t\tthis._synchCamera = () => {\r\n\t\t\t\tconst eye = this._viewer.camera.eye;\r\n\t\t\t\tconst look = this._viewer.camera.look;\r\n\t\t\t\tconst up = this._viewer.camera.up;\r\n\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(eye, look, eyeLookVec)), 7);\r\n\t\t\t\tif (this._zUp) {\r\n\t\t\t\t\t// +Z up\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(matrix, eyeLookVec, eyeLookVecOverview);\r\n\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(matrix, up, upOverview);\r\n\t\t\t\t\tcamera.look = [0, 0, 0];\r\n\t\t\t\t\tcamera.eye = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(matrix, eyeLookVec, eyeLookVecOverview);\r\n\t\t\t\t\tcamera.up = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint3(matrix, up, upOverview);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// +Y up\r\n\t\t\t\t\tcamera.look = [0, 0, 0];\r\n\t\t\t\t\tcamera.eye = eyeLookVec;\r\n\t\t\t\t\tcamera.up = up;\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tthis._onViewerCameraMatrix = this._viewer.camera.on(\"matrix\", this._synchCamera);\r\n\r\n\t\tthis._onViewerCameraWorldAxis = this._viewer.camera.on(\"worldAxis\", this._synchCamera);\r\n\r\n\t\tthis._onViewerCameraFOV = this._viewer.camera.perspective.on(\"fov\", (fov) => {\r\n\t\t\tthis._scene.camera.perspective.fov = fov;\r\n\t\t});\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Bind overview canvas events\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\t{\r\n\t\t\tvar hoveredEntity = null;\r\n\r\n\t\t\tthis._onInputMouseMove = this._scene.input.on(\"mousemove\", (coords) => {\r\n\t\t\t\tconst hit = this._scene.pick({\r\n\t\t\t\t\tcanvasPos: coords\r\n\t\t\t\t});\r\n\t\t\t\tif (hit) {\r\n\t\t\t\t\tif (!hoveredEntity || hit.entity.id !== hoveredEntity.id) {\r\n\t\t\t\t\t\tif (hoveredEntity) {\r\n\t\t\t\t\t\t\tconst plane = this._planes[hoveredEntity.id];\r\n\t\t\t\t\t\t\tif (plane) {\r\n\t\t\t\t\t\t\t\tthis._onHoverLeavePlane(hoveredEntity.id);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\thoveredEntity = hit.entity;\r\n\t\t\t\t\t\tconst plane = this._planes[hoveredEntity.id];\r\n\t\t\t\t\t\tif (plane) {\r\n\t\t\t\t\t\t\tthis._onHoverEnterPlane(hoveredEntity.id);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (hoveredEntity) {\r\n\t\t\t\t\t\tthis._onHoverLeavePlane(hoveredEntity.id);\r\n\t\t\t\t\t\thoveredEntity = null;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tthis._scene.canvas.canvas.addEventListener(\r\n\t\t\t\t\"mouseup\",\r\n\t\t\t\t(this._onCanvasMouseUp = () => {\r\n\t\t\t\t\tif (hoveredEntity) {\r\n\t\t\t\t\t\tconst plane = this._planes[hoveredEntity.id];\r\n\t\t\t\t\t\tif (plane) {\r\n\t\t\t\t\t\t\tthis._onClickedPlane(hoveredEntity.id);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis._onClickedNothing();\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t\tthis._scene.canvas.canvas.addEventListener(\r\n\t\t\t\t\"mouseout\",\r\n\t\t\t\t(this._onCanvasMouseOut = () => {\r\n\t\t\t\t\tif (hoveredEntity) {\r\n\t\t\t\t\t\tthis._onHoverLeavePlane(hoveredEntity.id);\r\n\t\t\t\t\t\thoveredEntity = null;\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\t\t// Configure overview\r\n\t\t//--------------------------------------------------------------------------------------------------------------\r\n\r\n\t\tthis.setVisible(cfg.overviewVisible);\r\n\t}\r\n\r\n\t/** Called by SectionPlanesPlugin#createSectionPlane()\r\n\t * @private\r\n\t */\r\n\taddSectionPlane(sectionPlane) {\r\n\t\tthis._planes[sectionPlane.id] = new _Plane_js__WEBPACK_IMPORTED_MODULE_3__.Plane(this, this._scene, sectionPlane);\r\n\t}\r\n\r\n\tsetSectionBox(sectionBox) {\r\n\t\tthis._box = new _Box_js__WEBPACK_IMPORTED_MODULE_4__.Box(this, this._scene, sectionBox);\r\n\t}\r\n\r\n\t/** @private\r\n\t */\r\n\tsetPlaneHighlighted(id, highlighted) {\r\n\t\tconst plane = this._planes[id];\r\n\t\tif (plane) {\r\n\t\t\tplane.setHighlighted(highlighted);\r\n\t\t}\r\n\t}\r\n\r\n\t/** @private\r\n\t */\r\n\tsetPlaneSelected(id, selected) {\r\n\t\tconst plane = this._planes[id];\r\n\t\tif (plane) {\r\n\t\t\tplane.setSelected(selected);\r\n\t\t}\r\n\t}\r\n\r\n\t/** @private\r\n\t */\r\n\tremoveSectionPlane(sectionPlane) {\r\n\t\tconst plane = this._planes[sectionPlane.id];\r\n\t\tif (plane) {\r\n\t\t\tplane.destroy();\r\n\t\t\tdelete this._planes[sectionPlane.id];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if this SectionPlanesOverview is visible.\r\n\t *\r\n\t * @param {Boolean} visible Whether or not this SectionPlanesOverview is visible.\r\n\t */\r\n\tsetVisible(visible = true) {\r\n\t\tthis._visible = visible;\r\n\t\tthis._canvas.style.visibility = visible ? \"visible\" : \"hidden\";\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if this SectionPlanesOverview is visible.\r\n\t *\r\n\t * @return {Boolean} True when this SectionPlanesOverview is visible.\r\n\t */\r\n\tgetVisible() {\r\n\t\treturn this._visible;\r\n\t}\r\n\r\n\t/** @private\r\n\t */\r\n\tdestroy() {\r\n\t\tthis._viewer.camera.off(this._onViewerCameraMatrix);\r\n\t\tthis._viewer.camera.off(this._onViewerCameraWorldAxis);\r\n\t\tthis._viewer.camera.perspective.off(this._onViewerCameraFOV);\r\n\r\n\t\tthis._scene.input.off(this._onInputMouseMove);\r\n\t\tthis._scene.canvas.canvas.removeEventListener(\"mouseup\", this._onCanvasMouseUp);\r\n\t\tthis._scene.canvas.canvas.removeEventListener(\"mouseout\", this._onCanvasMouseOut);\r\n\t\tthis._scene.destroy();\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SectionPlanesPlugin/Overview.js?");
1918
1928
 
1919
1929
  /***/ }),
1920
1930
 
@@ -1934,7 +1944,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1934
1944
  \****************************************************************/
1935
1945
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1936
1946
 
1937
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SectionPlanesPlugin: () => (/* binding */ SectionPlanesPlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_sectionPlane_SectionPlane_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/sectionPlane/SectionPlane.js */ \"./src/viewer/scene/sectionPlane/SectionPlane.js\");\n/* harmony import */ var _Control_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Control.js */ \"./src/plugins/SectionPlanesPlugin/Control.js\");\n/* harmony import */ var _ClippingBox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ClippingBox.js */ \"./src/plugins/SectionPlanesPlugin/ClippingBox.js\");\n/* harmony import */ var _ClippingPlane_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ClippingPlane.js */ \"./src/plugins/SectionPlanesPlugin/ClippingPlane.js\");\n/* harmony import */ var _Overview_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Overview.js */ \"./src/plugins/SectionPlanesPlugin/Overview.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst tempAABB = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.AABB3();\r\nconst tempVec3 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n/**\r\n * SectionPlanesPlugin is a {@link Viewer} plugin that manages {@link SectionPlane}s.\r\n *\r\n * [<img src=\"https://user-images.githubusercontent.com/83100/57724962-406e9a00-768c-11e9-9f1f-3d178a3ec11f.gif\">](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_SectionPlanesPlugin)\r\n *\r\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_SectionPlanesPlugin)]\r\n *\r\n * ## Overview\r\n *\r\n * * Use the SectionPlanesPlugin to\r\n * create and edit {@link SectionPlane}s to slice portions off your models and reveal internal structures.\r\n * * As shown in the screen capture above, SectionPlanesPlugin shows an overview of all your SectionPlanes (on the right, in\r\n * this example).\r\n * * Click a plane in the overview to activate a 3D control with which you can interactively\r\n * reposition its SectionPlane in the main canvas.\r\n * * Use {@lin BCFViewpointsPlugin} to save and load SectionPlanes in BCF viewpoints.\r\n *\r\n * ## Usage\r\n *\r\n * In the example below, we'll use a {@link GLTFLoaderPlugin} to load a model, and a SectionPlanesPlugin\r\n * to slice it open with two {@link SectionPlane}s. We'll show the overview in the bottom right of the Viewer\r\n * canvas. Finally, we'll programmatically activate the 3D editing control, so that we can use it to interactively\r\n * reposition our second SectionPlane.\r\n *\r\n * ````JavaScript\r\n * import {Viewer, GLTFLoaderPlugin, SectionPlanesPlugin} from \"xeokit-sdk.es.js\";\r\n *\r\n * // Create a Viewer and arrange its Camera\r\n *\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\"\r\n * });\r\n *\r\n * viewer.camera.eye = [-5.02, 2.22, 15.09];\r\n * viewer.camera.look = [4.97, 2.79, 9.89];\r\n * viewer.camera.up = [-0.05, 0.99, 0.02];\r\n *\r\n *\r\n * // Add a GLTFLoaderPlugin\r\n *\r\n * const gltfLoader = new GLTFLoaderPlugin(viewer);\r\n *\r\n * // Add a SectionPlanesPlugin, with overview visible\r\n *\r\n * const sectionPlanes = new SectionPlanesPlugin(viewer, {\r\n * overviewCanvasID: \"myOverviewCanvas\",\r\n * overviewVisible: true\r\n * });\r\n *\r\n * // Load a model\r\n *\r\n * const model = gltfLoader.load({\r\n * id: \"myModel\",\r\n * src: \"./models/gltf/schependomlaan/scene.gltf\"\r\n * });\r\n *\r\n * // Create a couple of section planes\r\n * // These will be shown in the overview\r\n *\r\n * sectionPlanes.createSectionPlane({\r\n * id: \"mySectionPlane\",\r\n * pos: [1.04, 1.95, 9.74],\r\n * dir: [1.0, 0.0, 0.0]\r\n * });\r\n *\r\n * sectionPlanes.createSectionPlane({\r\n * id: \"mySectionPlane2\",\r\n * pos: [2.30, 4.46, 14.93],\r\n * dir: [0.0, -0.09, -0.79]\r\n * });\r\n *\r\n * // Show the SectionPlanePlugin's 3D editing gizmo,\r\n * // to interactively reposition one of our SectionPlanes\r\n *\r\n * sectionPlanes.showControl(\"mySectionPlane2\");\r\n *\r\n * const mySectionPlane2 = sectionPlanes.sectionPlanes[\"mySectionPlane2\"];\r\n *\r\n * // Programmatically reposition one of our SectionPlanes\r\n * // This also updates its position as shown in the overview gizmo\r\n *\r\n * mySectionPlane2.pos = [11.0, 6.0, -12];\r\n * mySectionPlane2.dir = [0.4, 0.0, 0.5];\r\n * ````\r\n */\r\nclass SectionPlanesPlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_1__.Plugin {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Viewer} viewer The Viewer.\r\n\t * @param {Object} cfg Plugin configuration.\r\n\t * @param {String} [cfg.id=\"SectionPlanes\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\r\n\t * @param {String} [cfg.overviewCanvasId] ID of a canvas element to display the overview.\r\n\t * @param {String} [cfg.overviewVisible=true] Initial visibility of the overview canvas.\r\n\t */\r\n\tconstructor(viewer, cfg = {}) {\r\n\t\tsuper(\"SectionPlanes\", viewer);\r\n\r\n\t\tthis._freeControls = [];\r\n\t\tthis._sectionPlanes = viewer.scene.sectionPlanes;\r\n\t\tthis._controls = {};\r\n\t\tthis._currentControl = null;\r\n\t\tthis._shownControlId = null;\r\n\r\n\t\tif (cfg.overviewCanvasId !== null && cfg.overviewCanvasId !== undefined) {\r\n\t\t\tconst overviewCanvas = document.getElementById(cfg.overviewCanvasId);\r\n\r\n\t\t\tif (!overviewCanvas) {\r\n\t\t\t\tthis.warn(\"Can't find overview canvas: '\" + cfg.overviewCanvasId + \"' - will create plugin without overview\");\r\n\t\t\t} else {\r\n\t\t\t\tthis._overview = new _Overview_js__WEBPACK_IMPORTED_MODULE_6__.Overview(this, {\r\n\t\t\t\t\toverviewCanvas: overviewCanvas,\r\n\t\t\t\t\tvisible: cfg.overviewVisible,\r\n\r\n\t\t\t\t\tonHoverEnterPlane: (id) => {\r\n\t\t\t\t\t\tthis._overview.setPlaneHighlighted(id, true);\r\n\t\t\t\t\t},\r\n\r\n\t\t\t\t\tonHoverLeavePlane: (id) => {\r\n\t\t\t\t\t\tthis._overview.setPlaneHighlighted(id, false);\r\n\t\t\t\t\t},\r\n\r\n\t\t\t\t\tonClickedPlane: (id) => {\r\n\t\t\t\t\t\tif (this.getShownControl() === id) {\r\n\t\t\t\t\t\t\tthis.hideControl();\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tthis.showControl(id);\r\n\t\t\t\t\t\tconst sectionPlane = this.sectionPlanes[id];\r\n\t\t\t\t\t\tconst sectionPlanePos = sectionPlane.pos;\r\n\t\t\t\t\t\ttempAABB.set(this.viewer.scene.aabb);\r\n\t\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(tempAABB, tempVec3);\r\n\t\t\t\t\t\ttempAABB[0] += sectionPlanePos[0] - tempVec3[0];\r\n\t\t\t\t\t\ttempAABB[1] += sectionPlanePos[1] - tempVec3[1];\r\n\t\t\t\t\t\ttempAABB[2] += sectionPlanePos[2] - tempVec3[2];\r\n\t\t\t\t\t\ttempAABB[3] += sectionPlanePos[0] - tempVec3[0];\r\n\t\t\t\t\t\ttempAABB[4] += sectionPlanePos[1] - tempVec3[1];\r\n\t\t\t\t\t\ttempAABB[5] += sectionPlanePos[2] - tempVec3[2];\r\n\t\t\t\t\t\tthis.viewer.cameraFlight.flyTo({\r\n\t\t\t\t\t\t\taabb: tempAABB,\r\n\t\t\t\t\t\t\tfitFOV: 65\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t},\r\n\r\n\t\t\t\t\tonClickedNothing: () => {\r\n\t\t\t\t\t\tthis.hideControl();\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis._onSceneSectionPlaneCreated = viewer.scene.on(\"sectionPlaneCreated\", (sectionPlane) => {\r\n\t\t\t// SectionPlane created, either via SectionPlanesPlugin#createSectionPlane(), or by directly\r\n\t\t\t// instantiating a SectionPlane independently of SectionPlanesPlugin, which can be done\r\n\t\t\t// by BCFViewpointsPlugin#loadViewpoint().\r\n\r\n\t\t\tthis._sectionPlaneCreated(sectionPlane);\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if the overview canvas is visible.\r\n\t *\r\n\t * @param {Boolean} visible Whether or not the overview canvas is visible.\r\n\t */\r\n\tsetOverviewVisible(visible) {\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.setVisible(visible);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if the overview canvas is visible.\r\n\t *\r\n\t * @return {Boolean} True when the overview canvas is visible.\r\n\t */\r\n\tgetOverviewVisible() {\r\n\t\tif (this._overview) {\r\n\t\t\treturn this._overview.getVisible();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns a map of the {@link SectionPlane}s created by this SectionPlanesPlugin.\r\n\t *\r\n\t * @returns {{String:SectionPlane}} A map containing the {@link SectionPlane}s, each mapped to its {@link SectionPlane#id}.\r\n\t */\r\n\tget sectionPlanes() {\r\n\t\treturn this._sectionPlanes;\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a {@link SectionPlane}.\r\n\t *\r\n\t * The {@link SectionPlane} will be registered by {@link SectionPlane#id} in {@link SectionPlanesPlugin#sectionPlanes}.\r\n\t *\r\n\t * @param {Object} params {@link SectionPlane} configuration.\r\n\t * @param {String} [params.id] Unique ID to assign to the {@link SectionPlane}. Must be unique among all components in the {@link Viewer}'s {@link Scene}. Auto-generated when omitted.\r\n\t * @param {Number[]} [params.pos=[0,0,0]] World-space position of the {@link SectionPlane}.\r\n\t * @param {Number[]} [params.dir=[0,0,-1]] World-space vector indicating the orientation of the {@link SectionPlane}.\r\n\t * @param {Boolean} [params.active=true] Whether the {@link SectionPlane} is initially active. Only clips while this is true.\r\n\t * @returns {SectionPlane} The new {@link SectionPlane}.\r\n\t */\r\n\tcreateSectionPlane(params = {}) {\r\n\t\tif (params.id !== undefined && params.id !== null && this.viewer.scene.components[params.id]) {\r\n\t\t\tthis.error(\"Viewer component with this ID already exists: \" + params.id);\r\n\t\t\tdelete params.id;\r\n\t\t}\r\n\r\n\t\t// Note that SectionPlane constructor fires \"sectionPlaneCreated\" on the Scene,\r\n\t\t// which SectionPlanesPlugin handles and calls #_sectionPlaneCreated to create gizmo and add to overview canvas.\r\n\r\n\t\tconst sectionPlane = new _viewer_scene_sectionPlane_SectionPlane_js__WEBPACK_IMPORTED_MODULE_2__.SectionPlane(this.viewer.scene, {\r\n\t\t\tid: params.id,\r\n\t\t\tpos: params.pos,\r\n\t\t\tdir: params.dir,\r\n\t\t\tactive: true || 0\r\n\t\t});\r\n\t\treturn sectionPlane;\r\n\t}\r\n\r\n\t//剖切面创建后,创建一个控制器\r\n\t_sectionPlaneCreated(sectionPlane) {\r\n\t\tlet newControl;\r\n\t\tswitch (this._sectionWay) {\r\n\t\t\tcase \"plane\":\r\n\t\t\t\tnewControl = new _ClippingPlane_js__WEBPACK_IMPORTED_MODULE_5__.ClippingPlane(this, this._controlsConfig);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"box\":\r\n\t\t\t\tnewControl = new _ClippingBox_js__WEBPACK_IMPORTED_MODULE_4__.ClippingBox(this, this._controlsConfig);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tnewControl = new _Control_js__WEBPACK_IMPORTED_MODULE_3__.Control(this);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t\tconst control = this._freeControls.length > 0 ? this._freeControls.pop() : newControl;\r\n\t\tcontrol._setSectionPlane(sectionPlane);\r\n\t\tcontrol.setVisible(true);\r\n\t\tthis._currentControl = control;\r\n\t\tthis._controls[sectionPlane.id] = control;\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.addSectionPlane(sectionPlane);\r\n\t\t}\r\n\t\tsectionPlane.once(\"destroyed\", () => {\r\n\t\t\tthis._sectionPlaneDestroyed(sectionPlane);\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 设置是否是触屏模式\r\n\t * @param {boolean} touch\r\n\t */\r\n\tset isTouch(touch) {\r\n\t\tthis._isTouch = touch;\r\n\t\tif (touch === true) this.sectionWay = \"plane\";\r\n\t\telse this.sectionWay = \"control\";\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切对象样式\r\n\t * @param {any} cfg\r\n\t * @param {number} cfg.planeSize?\r\n\t * @param {number} cfg.controlSize?\r\n\t * @param {number} cfg.planeOpacity?\r\n\t * @param {number[]} cfg.controlFillColor?\r\n\t * @param {number[]} cfg.controlEdgeColor?\r\n\t */\r\n\tset sectionConfigs(cfg) {\r\n\t\tthis._controlsConfig = cfg;\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切方式\r\n\t * @param {string} way\r\n\t */\r\n\tset sectionWay(way) {\r\n\t\tthis._sectionWay = way;\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切面方向\r\n\t * @param {number} direction\r\n\t */\r\n\tset sectionDirection(direction) {\r\n\t\tthis.clear();\r\n\t\tlet dir;\r\n\t\tswitch (direction) {\r\n\t\t\tcase 0:\r\n\t\t\t\tdir = [0, 0, -1];\r\n\t\t\t\tbreak;\r\n\t\t\tcase 1:\r\n\t\t\t\tdir = [0, -1, 0];\r\n\t\t\t\tbreak;\r\n\t\t\tcase 2:\r\n\t\t\t\tdir = [-1, 0, 0];\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t\tthis.createSectionPlane({\r\n\t\t\tpos: this.viewer.camera.look,\r\n\t\t\tdir: dir\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切面位置\r\n\t * @param id\r\n\t * @param pos\r\n\t */\r\n\tsetControlPos(posRate) {\r\n\t\tif (this._currentControl == null) return;\r\n\t\t// if (this._currentControl.type != \"plane\") return;\r\n\t\tthis._currentControl.pos = posRate;\r\n\t}\r\n\r\n\t/**\r\n\t * Inverts the direction of {@link SectionPlane#dir} on every existing SectionPlane.\r\n\t *\r\n\t * Inverts all SectionPlanes, including those that were not created with SectionPlanesPlugin.\r\n\t */\r\n\tflipSectionPlanes() {\r\n\t\tconst sectionPlanes = this.viewer.scene.sectionPlanes;\r\n\t\tfor (let id in sectionPlanes) {\r\n\t\t\tconst sectionPlane = sectionPlanes[id];\r\n\t\t\tsectionPlane.flipDir();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Shows the 3D editing gizmo for a {@link SectionPlane}.\r\n\t *\r\n\t * @param {String} id ID of the {@link SectionPlane}.\r\n\t */\r\n\tshowControl(id) {\r\n\t\tconst control = this._controls[id];\r\n\t\tif (!control) {\r\n\t\t\tthis.error(\"Control not found: \" + id);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.hideControl();\r\n\t\tcontrol.setVisible(true);\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.setPlaneSelected(id, true);\r\n\t\t}\r\n\t\tthis._shownControlId = id;\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切对象的尺寸\r\n\t * @param {*} size\r\n\t */\r\n\tsetControlsSize(size) {\r\n\t\tfor (let id in this._controls) {\r\n\t\t\tthis._controls[id].controlSize = size;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 设置指定id剖切对象的尺寸\r\n\t * @param {*} id\r\n\t * @param {*} size\r\n\t * @returns\r\n\t */\r\n\tsetControlSizeByID(id, size) {\r\n\t\tconst control = this._controls[id];\r\n\t\tif (!control) {\r\n\t\t\tthis.error(\"Control not found: \" + id);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._controls[id].controlSize = size;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the ID of the {@link SectionPlane} that the 3D editing gizmo is shown for.\r\n\t *\r\n\t * Returns ````null```` when the editing gizmo is not shown.\r\n\t *\r\n\t * @returns {String} ID of the the {@link SectionPlane} that the 3D editing gizmo is shown for, if shown, else ````null````.\r\n\t */\r\n\tgetShownControl() {\r\n\t\treturn this._shownControlId;\r\n\t}\r\n\r\n\t/**\r\n\t * Hides the 3D {@link SectionPlane} editing gizmo if shown.\r\n\t */\r\n\thideControl() {\r\n\t\tfor (var id in this._controls) {\r\n\t\t\tif (this._controls.hasOwnProperty(id)) {\r\n\t\t\t\tthis._controls[id].setVisible(false);\r\n\t\t\t\tif (this._overview) {\r\n\t\t\t\t\tthis._overview.setPlaneSelected(id, false);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._shownControlId = null;\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys a {@link SectionPlane} created by this SectionPlanesPlugin.\r\n\t *\r\n\t * @param {String} id ID of the {@link SectionPlane}.\r\n\t */\r\n\tdestroySectionPlane(id) {\r\n\t\tvar sectionPlane = this.viewer.scene.sectionPlanes[id];\r\n\t\tif (!sectionPlane) {\r\n\t\t\tthis.error(\"SectionPlane not found: \" + id);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._sectionPlaneDestroyed(sectionPlane);\r\n\t\tsectionPlane.destroy();\r\n\r\n\t\tif (id === this._shownControlId) {\r\n\t\t\tthis._shownControlId = null;\r\n\t\t}\r\n\t}\r\n\r\n\t_sectionPlaneDestroyed(sectionPlane) {\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.removeSectionPlane(sectionPlane);\r\n\t\t}\r\n\t\tconst control = this._controls[sectionPlane.id];\r\n\t\tif (!control) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tcontrol.setVisible(false);\r\n\t\tcontrol._setSectionPlane(null);\r\n\t\tdelete this._controls[sectionPlane.id];\r\n\t\tthis._freeControls.push(control);\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys all {@link SectionPlane}s created by this SectionPlanesPlugin.\r\n\t */\r\n\tclear() {\r\n\t\tconst ids = Object.keys(this._sectionPlanes);\r\n\t\tfor (var i = 0, len = ids.length; i < len; i++) {\r\n\t\t\tthis.destroySectionPlane(ids[i]);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tsend(name, value) {\r\n\t\tswitch (name) {\r\n\t\t\tcase \"snapshotStarting\": // Viewer#getSnapshot() about to take snapshot - hide controls\r\n\t\t\t\tfor (let id in this._controls) {\r\n\t\t\t\t\tif (this._controls.hasOwnProperty(id)) {\r\n\t\t\t\t\t\tthis._controls[id].setCulled(true);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase \"snapshotFinished\": // Viewer#getSnapshot() finished taking snapshot - show controls again\r\n\t\t\t\tfor (let id in this._controls) {\r\n\t\t\t\t\tif (this._controls.hasOwnProperty(id)) {\r\n\t\t\t\t\t\tthis._controls[id].setCulled(false);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase \"clearSectionPlanes\":\r\n\t\t\t\tthis.clear();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys this SectionPlanesPlugin.\r\n\t *\r\n\t * Also destroys each {@link SectionPlane} created by this SectionPlanesPlugin.\r\n\t *\r\n\t * Does not destroy the canvas the SectionPlanesPlugin was configured with.\r\n\t */\r\n\tdestroy() {\r\n\t\tthis.clear();\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.destroy();\r\n\t\t}\r\n\t\tthis._destroyFreeControls();\r\n\t\tsuper.destroy();\r\n\t}\r\n\r\n\t_destroyFreeControls() {\r\n\t\tvar control = this._freeControls.pop();\r\n\t\twhile (control) {\r\n\t\t\tcontrol._destroy();\r\n\t\t\tcontrol = this._freeControls.pop();\r\n\t\t}\r\n\t\tthis.viewer.scene.off(this._onSceneSectionPlaneCreated);\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SectionPlanesPlugin/SectionPlanesPlugin.js?");
1947
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SectionPlanesPlugin: () => (/* binding */ SectionPlanesPlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_sectionPlane_SectionPlane_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/sectionPlane/SectionPlane.js */ \"./src/viewer/scene/sectionPlane/SectionPlane.js\");\n/* harmony import */ var _Control_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Control.js */ \"./src/plugins/SectionPlanesPlugin/Control.js\");\n/* harmony import */ var _ClippingBox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ClippingBox.js */ \"./src/plugins/SectionPlanesPlugin/ClippingBox.js\");\n/* harmony import */ var _ClippingPlane_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ClippingPlane.js */ \"./src/plugins/SectionPlanesPlugin/ClippingPlane.js\");\n/* harmony import */ var _Overview_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Overview.js */ \"./src/plugins/SectionPlanesPlugin/Overview.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst tempAABB = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.AABB3();\r\nconst tempVec3 = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n/**\r\n * SectionPlanesPlugin is a {@link Viewer} plugin that manages {@link SectionPlane}s.\r\n *\r\n * [<img src=\"https://user-images.githubusercontent.com/83100/57724962-406e9a00-768c-11e9-9f1f-3d178a3ec11f.gif\">](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_SectionPlanesPlugin)\r\n *\r\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_SectionPlanesPlugin)]\r\n *\r\n * ## Overview\r\n *\r\n * * Use the SectionPlanesPlugin to\r\n * create and edit {@link SectionPlane}s to slice portions off your models and reveal internal structures.\r\n * * As shown in the screen capture above, SectionPlanesPlugin shows an overview of all your SectionPlanes (on the right, in\r\n * this example).\r\n * * Click a plane in the overview to activate a 3D control with which you can interactively\r\n * reposition its SectionPlane in the main canvas.\r\n * * Use {@lin BCFViewpointsPlugin} to save and load SectionPlanes in BCF viewpoints.\r\n *\r\n * ## Usage\r\n *\r\n * In the example below, we'll use a {@link GLTFLoaderPlugin} to load a model, and a SectionPlanesPlugin\r\n * to slice it open with two {@link SectionPlane}s. We'll show the overview in the bottom right of the Viewer\r\n * canvas. Finally, we'll programmatically activate the 3D editing control, so that we can use it to interactively\r\n * reposition our second SectionPlane.\r\n *\r\n * ````JavaScript\r\n * import {Viewer, GLTFLoaderPlugin, SectionPlanesPlugin} from \"xeokit-sdk.es.js\";\r\n *\r\n * // Create a Viewer and arrange its Camera\r\n *\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\"\r\n * });\r\n *\r\n * viewer.camera.eye = [-5.02, 2.22, 15.09];\r\n * viewer.camera.look = [4.97, 2.79, 9.89];\r\n * viewer.camera.up = [-0.05, 0.99, 0.02];\r\n *\r\n *\r\n * // Add a GLTFLoaderPlugin\r\n *\r\n * const gltfLoader = new GLTFLoaderPlugin(viewer);\r\n *\r\n * // Add a SectionPlanesPlugin, with overview visible\r\n *\r\n * const sectionPlanes = new SectionPlanesPlugin(viewer, {\r\n * overviewCanvasID: \"myOverviewCanvas\",\r\n * overviewVisible: true\r\n * });\r\n *\r\n * // Load a model\r\n *\r\n * const model = gltfLoader.load({\r\n * id: \"myModel\",\r\n * src: \"./models/gltf/schependomlaan/scene.gltf\"\r\n * });\r\n *\r\n * // Create a couple of section planes\r\n * // These will be shown in the overview\r\n *\r\n * sectionPlanes.createSectionPlane({\r\n * id: \"mySectionPlane\",\r\n * pos: [1.04, 1.95, 9.74],\r\n * dir: [1.0, 0.0, 0.0]\r\n * });\r\n *\r\n * sectionPlanes.createSectionPlane({\r\n * id: \"mySectionPlane2\",\r\n * pos: [2.30, 4.46, 14.93],\r\n * dir: [0.0, -0.09, -0.79]\r\n * });\r\n *\r\n * // Show the SectionPlanePlugin's 3D editing gizmo,\r\n * // to interactively reposition one of our SectionPlanes\r\n *\r\n * sectionPlanes.showControl(\"mySectionPlane2\");\r\n *\r\n * const mySectionPlane2 = sectionPlanes.sectionPlanes[\"mySectionPlane2\"];\r\n *\r\n * // Programmatically reposition one of our SectionPlanes\r\n * // This also updates its position as shown in the overview gizmo\r\n *\r\n * mySectionPlane2.pos = [11.0, 6.0, -12];\r\n * mySectionPlane2.dir = [0.4, 0.0, 0.5];\r\n * ````\r\n */\r\nclass SectionPlanesPlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_1__.Plugin {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Viewer} viewer The Viewer.\r\n\t * @param {Object} cfg Plugin configuration.\r\n\t * @param {String} [cfg.id=\"SectionPlanes\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\r\n\t * @param {String} [cfg.overviewCanvasId] ID of a canvas element to display the overview.\r\n\t * @param {String} [cfg.overviewVisible=true] Initial visibility of the overview canvas.\r\n\t */\r\n\tconstructor(viewer, cfg = {}) {\r\n\t\tsuper(\"SectionPlanes\", viewer);\r\n\r\n\t\tthis._freeControls = [];\r\n\t\tthis._sectionPlanes = viewer.scene.sectionPlanes;\r\n\t\tthis._controls = {};\r\n\t\tthis._currentControl = null;\r\n\t\tthis._shownControlId = null;\r\n\r\n\t\tif (cfg.overviewCanvasId !== null && cfg.overviewCanvasId !== undefined) {\r\n\t\t\tconst overviewCanvas = document.getElementById(cfg.overviewCanvasId);\r\n\r\n\t\t\tif (!overviewCanvas) {\r\n\t\t\t\tthis.warn(\"Can't find overview canvas: '\" + cfg.overviewCanvasId + \"' - will create plugin without overview\");\r\n\t\t\t} else {\r\n\t\t\t\tthis._overview = new _Overview_js__WEBPACK_IMPORTED_MODULE_6__.Overview(this, {\r\n\t\t\t\t\toverviewCanvas: overviewCanvas,\r\n\t\t\t\t\tvisible: cfg.overviewVisible,\r\n\r\n\t\t\t\t\tonHoverEnterPlane: (id) => {\r\n\t\t\t\t\t\tthis._overview.setPlaneHighlighted(id, true);\r\n\t\t\t\t\t},\r\n\r\n\t\t\t\t\tonHoverLeavePlane: (id) => {\r\n\t\t\t\t\t\tthis._overview.setPlaneHighlighted(id, false);\r\n\t\t\t\t\t},\r\n\r\n\t\t\t\t\tonClickedPlane: (id) => {\r\n\t\t\t\t\t\tif (this.getShownControl() === id) {\r\n\t\t\t\t\t\t\tthis.hideControl();\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tthis.showControl(id);\r\n\t\t\t\t\t\tconst sectionPlane = this.sectionPlanes[id];\r\n\t\t\t\t\t\tconst sectionPlanePos = sectionPlane.pos;\r\n\t\t\t\t\t\ttempAABB.set(this.viewer.scene.aabb);\r\n\t\t\t\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(tempAABB, tempVec3);\r\n\t\t\t\t\t\ttempAABB[0] += sectionPlanePos[0] - tempVec3[0];\r\n\t\t\t\t\t\ttempAABB[1] += sectionPlanePos[1] - tempVec3[1];\r\n\t\t\t\t\t\ttempAABB[2] += sectionPlanePos[2] - tempVec3[2];\r\n\t\t\t\t\t\ttempAABB[3] += sectionPlanePos[0] - tempVec3[0];\r\n\t\t\t\t\t\ttempAABB[4] += sectionPlanePos[1] - tempVec3[1];\r\n\t\t\t\t\t\ttempAABB[5] += sectionPlanePos[2] - tempVec3[2];\r\n\t\t\t\t\t\tthis.viewer.cameraFlight.flyTo({\r\n\t\t\t\t\t\t\taabb: tempAABB,\r\n\t\t\t\t\t\t\tfitFOV: 65\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t},\r\n\r\n\t\t\t\t\tonClickedNothing: () => {\r\n\t\t\t\t\t\tthis.hideControl();\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis._onSceneSectionPlaneCreated = viewer.scene.on(\"sectionPlaneCreated\", (sectionPlane) => {\r\n\t\t\t// SectionPlane created, either via SectionPlanesPlugin#createSectionPlane(), or by directly\r\n\t\t\t// instantiating a SectionPlane independently of SectionPlanesPlugin, which can be done\r\n\t\t\t// by BCFViewpointsPlugin#loadViewpoint().\r\n\t\t\tthis._sectionPlaneCreated(sectionPlane);\r\n\t\t});\r\n\r\n\t\tthis._onSceneSectionBoxCreated = viewer.scene.on(\"sectionBoxCreated\", (sectionBox) => {\r\n\t\t\tthis._sectionBoxCreated(sectionBox);\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if the overview canvas is visible.\r\n\t *\r\n\t * @param {Boolean} visible Whether or not the overview canvas is visible.\r\n\t */\r\n\tsetOverviewVisible(visible) {\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.setVisible(visible);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if the overview canvas is visible.\r\n\t *\r\n\t * @return {Boolean} True when the overview canvas is visible.\r\n\t */\r\n\tgetOverviewVisible() {\r\n\t\tif (this._overview) {\r\n\t\t\treturn this._overview.getVisible();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns a map of the {@link SectionPlane}s created by this SectionPlanesPlugin.\r\n\t *\r\n\t * @returns {{String:SectionPlane}} A map containing the {@link SectionPlane}s, each mapped to its {@link SectionPlane#id}.\r\n\t */\r\n\tget sectionPlanes() {\r\n\t\treturn this._sectionPlanes;\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a {@link SectionPlane}.\r\n\t *\r\n\t * The {@link SectionPlane} will be registered by {@link SectionPlane#id} in {@link SectionPlanesPlugin#sectionPlanes}.\r\n\t *\r\n\t * @param {Object} params {@link SectionPlane} configuration.\r\n\t * @param {String} [params.id] Unique ID to assign to the {@link SectionPlane}. Must be unique among all components in the {@link Viewer}'s {@link Scene}. Auto-generated when omitted.\r\n\t * @param {Number[]} [params.pos=[0,0,0]] World-space position of the {@link SectionPlane}.\r\n\t * @param {Number[]} [params.dir=[0,0,-1]] World-space vector indicating the orientation of the {@link SectionPlane}.\r\n\t * @param {Boolean} [params.active=true] Whether the {@link SectionPlane} is initially active. Only clips while this is true.\r\n\t * @returns {SectionPlane} The new {@link SectionPlane}.\r\n\t */\r\n\tcreateSectionPlane(params = {}) {\r\n\t\tif (params.id !== undefined && params.id !== null && this.viewer.scene.components[params.id]) {\r\n\t\t\tthis.error(\"Viewer component with this ID already exists: \" + params.id);\r\n\t\t\tdelete params.id;\r\n\t\t}\r\n\r\n\t\t// Note that SectionPlane constructor fires \"sectionPlaneCreated\" on the Scene,\r\n\t\t// which SectionPlanesPlugin handles and calls #_sectionPlaneCreated to create gizmo and add to overview canvas.\r\n\r\n\t\tconst sectionPlane = new _viewer_scene_sectionPlane_SectionPlane_js__WEBPACK_IMPORTED_MODULE_2__.SectionPlane(this.viewer.scene, {\r\n\t\t\tid: params.id,\r\n\t\t\tpos: params.pos,\r\n\t\t\tdir: params.dir,\r\n\t\t\tactive: true || 0\r\n\t\t});\r\n\t\treturn sectionPlane;\r\n\t}\r\n\r\n\t//剖切面创建后,创建一个控制器\r\n\t_sectionPlaneCreated(sectionPlane) {\r\n\t\tlet newControl;\r\n\t\tswitch (this._sectionWay) {\r\n\t\t\tcase \"plane\":\r\n\t\t\t\tnewControl = new _ClippingPlane_js__WEBPACK_IMPORTED_MODULE_5__.ClippingPlane(this, this._controlsConfig);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tnewControl = new _Control_js__WEBPACK_IMPORTED_MODULE_3__.Control(this);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t\tconst control = this._freeControls.length > 0 ? this._freeControls.pop() : newControl;\r\n\t\tcontrol._setSectionPlane(sectionPlane);\r\n\t\tcontrol.setVisible(true);\r\n\t\tthis._currentControl = control;\r\n\t\tthis._controls[sectionPlane.id] = control;\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.addSectionPlane(sectionPlane);\r\n\t\t}\r\n\t\tsectionPlane.once(\"destroyed\", () => {\r\n\t\t\tthis._sectionPlaneDestroyed(sectionPlane);\r\n\t\t});\r\n\t}\r\n\r\n\t//剖切盒创建后,创建一个控制器\r\n\t_sectionBoxCreated(sectionBox) {\r\n\t\tlet newControl;\r\n\t\tnewControl = new _ClippingBox_js__WEBPACK_IMPORTED_MODULE_4__.ClippingBox(this, this._controlsConfig);\r\n\t\tconst control = this._freeControls.length > 0 ? this._freeControls.pop() : newControl;\r\n\t\tcontrol._setSectionBox(sectionBox);\r\n\t\tcontrol.setVisible(true);\r\n\t\tthis._currentControl = control;\r\n\t\tthis._controls[sectionBox.id] = control;\r\n\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.setSectionBox(sectionBox);\r\n\t\t}\r\n\t\tsectionBox.once(\"destroyed\", () => {\r\n\t\t\tthis._sectionPlaneDestroyed(sectionBox);\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 设置是否是触屏模式\r\n\t * @param {boolean} touch\r\n\t */\r\n\tset isTouch(touch) {\r\n\t\tthis._isTouch = touch;\r\n\t\tif (touch === true) this.sectionWay = \"plane\";\r\n\t\telse this.sectionWay = \"control\";\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切对象样式\r\n\t * @param {any} cfg\r\n\t * @param {number} cfg.planeSize?\r\n\t * @param {number} cfg.controlSize?\r\n\t * @param {number} cfg.planeOpacity?\r\n\t * @param {number[]} cfg.controlFillColor?\r\n\t * @param {number[]} cfg.controlEdgeColor?\r\n\t */\r\n\tset sectionConfigs(cfg) {\r\n\t\tthis._controlsConfig = cfg;\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切方式\r\n\t * @param {string} way\r\n\t */\r\n\tset sectionWay(way) {\r\n\t\tthis._sectionWay = way;\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切面方向\r\n\t * @param {number} direction\r\n\t */\r\n\tset sectionDirection(direction) {\r\n\t\tthis.clear();\r\n\t\tlet dir;\r\n\t\tswitch (direction) {\r\n\t\t\tcase 0:\r\n\t\t\t\tdir = [0, 0, -1];\r\n\t\t\t\tbreak;\r\n\t\t\tcase 1:\r\n\t\t\t\tdir = [0, -1, 0];\r\n\t\t\t\tbreak;\r\n\t\t\tcase 2:\r\n\t\t\t\tdir = [-1, 0, 0];\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t\tconst { center } = this.viewer.scene;\r\n\t\tthis.createSectionPlane({\r\n\t\t\tpos: _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.AABB3([center[0], center[1], center[2]]),\r\n\t\t\tdir: dir\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切面位置\r\n\t * @param id\r\n\t * @param pos\r\n\t */\r\n\tsetControlPos(posRate) {\r\n\t\tif (this._currentControl == null) return;\r\n\t\t// if (this._currentControl.type != \"plane\") return;\r\n\t\tthis._currentControl.pos = posRate;\r\n\t}\r\n\r\n\t/**\r\n\t * Inverts the direction of {@link SectionPlane#dir} on every existing SectionPlane.\r\n\t *\r\n\t * Inverts all SectionPlanes, including those that were not created with SectionPlanesPlugin.\r\n\t */\r\n\tflipSectionPlanes() {\r\n\t\tconst sectionPlanes = this.viewer.scene.sectionPlanes;\r\n\t\tfor (let id in sectionPlanes) {\r\n\t\t\tconst sectionPlane = sectionPlanes[id];\r\n\t\t\tsectionPlane.flipDir();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Shows the 3D editing gizmo for a {@link SectionPlane}.\r\n\t *\r\n\t * @param {String} id ID of the {@link SectionPlane}.\r\n\t */\r\n\tshowControl(id) {\r\n\t\tconst control = this._controls[id];\r\n\t\tif (!control) {\r\n\t\t\tthis.error(\"Control not found: \" + id);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.hideControl();\r\n\t\tcontrol.setVisible(true);\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.setPlaneSelected(id, true);\r\n\t\t}\r\n\t\tthis._shownControlId = id;\r\n\t}\r\n\r\n\t/**\r\n\t * 设置剖切对象的尺寸\r\n\t * @param {*} size\r\n\t */\r\n\tsetControlsSize(size) {\r\n\t\tfor (let id in this._controls) {\r\n\t\t\tthis._controls[id].controlSize = size;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 设置指定id剖切对象的尺寸\r\n\t * @param {*} id\r\n\t * @param {*} size\r\n\t * @returns\r\n\t */\r\n\tsetControlSizeByID(id, size) {\r\n\t\tconst control = this._controls[id];\r\n\t\tif (!control) {\r\n\t\t\tthis.error(\"Control not found: \" + id);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._controls[id].controlSize = size;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the ID of the {@link SectionPlane} that the 3D editing gizmo is shown for.\r\n\t *\r\n\t * Returns ````null```` when the editing gizmo is not shown.\r\n\t *\r\n\t * @returns {String} ID of the the {@link SectionPlane} that the 3D editing gizmo is shown for, if shown, else ````null````.\r\n\t */\r\n\tgetShownControl() {\r\n\t\treturn this._shownControlId;\r\n\t}\r\n\r\n\t/**\r\n\t * Hides the 3D {@link SectionPlane} editing gizmo if shown.\r\n\t */\r\n\thideControl() {\r\n\t\tfor (var id in this._controls) {\r\n\t\t\tif (this._controls.hasOwnProperty(id)) {\r\n\t\t\t\tthis._controls[id].setVisible(false);\r\n\t\t\t\tif (this._overview) {\r\n\t\t\t\t\tthis._overview.setPlaneSelected(id, false);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._shownControlId = null;\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys a {@link SectionPlane} created by this SectionPlanesPlugin.\r\n\t *\r\n\t * @param {String} id ID of the {@link SectionPlane}.\r\n\t */\r\n\tdestroySectionPlane(id) {\r\n\t\tvar sectionPlane = this.viewer.scene.sectionPlanes[id];\r\n\t\tif (!sectionPlane) {\r\n\t\t\tthis.error(\"SectionPlane not found: \" + id);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._sectionPlaneDestroyed(sectionPlane);\r\n\t\tsectionPlane.destroy();\r\n\r\n\t\tif (id === this._shownControlId) {\r\n\t\t\tthis._shownControlId = null;\r\n\t\t}\r\n\t}\r\n\r\n\t_sectionPlaneDestroyed(sectionPlane) {\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.removeSectionPlane(sectionPlane);\r\n\t\t}\r\n\t\tconst control = this._controls[sectionPlane.id];\r\n\t\tif (!control) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tcontrol.setVisible(false);\r\n\t\tcontrol._setSectionPlane(null);\r\n\t\tdelete this._controls[sectionPlane.id];\r\n\t\tthis._freeControls.push(control);\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys all {@link SectionPlane}s created by this SectionPlanesPlugin.\r\n\t */\r\n\tclear() {\r\n\t\tconst ids = Object.keys(this._sectionPlanes);\r\n\t\tfor (var i = 0, len = ids.length; i < len; i++) {\r\n\t\t\tthis.destroySectionPlane(ids[i]);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tsend(name, value) {\r\n\t\tswitch (name) {\r\n\t\t\tcase \"snapshotStarting\": // Viewer#getSnapshot() about to take snapshot - hide controls\r\n\t\t\t\tfor (let id in this._controls) {\r\n\t\t\t\t\tif (this._controls.hasOwnProperty(id)) {\r\n\t\t\t\t\t\tthis._controls[id].setCulled(true);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase \"snapshotFinished\": // Viewer#getSnapshot() finished taking snapshot - show controls again\r\n\t\t\t\tfor (let id in this._controls) {\r\n\t\t\t\t\tif (this._controls.hasOwnProperty(id)) {\r\n\t\t\t\t\t\tthis._controls[id].setCulled(false);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase \"clearSectionPlanes\":\r\n\t\t\t\tthis.clear();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys this SectionPlanesPlugin.\r\n\t *\r\n\t * Also destroys each {@link SectionPlane} created by this SectionPlanesPlugin.\r\n\t *\r\n\t * Does not destroy the canvas the SectionPlanesPlugin was configured with.\r\n\t */\r\n\tdestroy() {\r\n\t\tthis.clear();\r\n\t\tif (this._overview) {\r\n\t\t\tthis._overview.destroy();\r\n\t\t}\r\n\t\tthis._destroyFreeControls();\r\n\t\tsuper.destroy();\r\n\t}\r\n\r\n\t_destroyFreeControls() {\r\n\t\tvar control = this._freeControls.pop();\r\n\t\twhile (control) {\r\n\t\t\tcontrol._destroy();\r\n\t\t\tcontrol = this._freeControls.pop();\r\n\t\t}\r\n\t\tthis.viewer.scene.off(this._onSceneSectionPlaneCreated);\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SectionPlanesPlugin/SectionPlanesPlugin.js?");
1938
1948
 
1939
1949
  /***/ }),
1940
1950
 
@@ -1954,7 +1964,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1954
1964
  \******************************************************/
1955
1965
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1956
1966
 
1957
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SkyboxesPlugin: () => (/* binding */ SkyboxesPlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_skybox_Skybox_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/skybox/Skybox.js */ \"./src/viewer/scene/skybox/Skybox.js\");\n\r\n\r\n\r\n/**\r\n * {@link Viewer} plugin that manages skyboxes\r\n *\r\n * @example\r\n *\r\n * // Create a Viewer\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\"\r\n * });\r\n *\r\n * // Add a GLTFModelsPlugin\r\n * var gltfLoaderPlugin = new GLTFModelsPlugin(viewer, {\r\n * id: \"GLTFModels\" // Default value\r\n * });\r\n *\r\n * // Add a SkyboxesPlugin\r\n * var skyboxesPlugin = new SkyboxesPlugin(viewer, {\r\n * id: \"Skyboxes\" // Default value\r\n * });\r\n *\r\n * // Load a glTF model\r\n * const model = gltfLoaderPlugin.load({\r\n * id: \"myModel\",\r\n * src: \"./models/gltf/mygltfmodel.gltf\"\r\n * });\r\n *\r\n * // Create three directional World-space lights. \"World\" means that they will appear as if part\r\n * // of the world, instead of \"View\", where they move with the user's head.\r\n *\r\n * skyboxesPlugin.createLight({\r\n * id: \"keyLight\",\r\n * dir: [0.8, -0.6, -0.8],\r\n * color: [1.0, 0.3, 0.3],\r\n * intensity: 1.0,\r\n * space: \"world\"\r\n * });\r\n *\r\n * skyboxesPlugin.createLight({\r\n * id: \"fillLight\",\r\n * dir: [-0.8, -0.4, -0.4],\r\n * color: [0.3, 1.0, 0.3],\r\n * intensity: 1.0,\r\n * space: \"world\"\r\n * });\r\n *\r\n * skyboxesPlugin.createDirLight({\r\n * id: \"rimLight\",\r\n * dir: [0.2, -0.8, 0.8],\r\n * color: [0.6, 0.6, 0.6],\r\n * intensity: 1.0,\r\n * space: \"world\"\r\n * });\r\n *\r\n * @class SkyboxesPlugin\r\n */\r\nclass SkyboxesPlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__.Plugin {\r\n\r\n constructor(viewer) {\r\n super(\"skyboxes\", viewer);\r\n this.skyboxes = {};\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n send(name, value) {\r\n switch (name) {\r\n case \"clear\":\r\n this.clear();\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n Creates a skybox.\r\n\r\n @param {String} id Unique ID to assign to the skybox.\r\n @param {Object} params Skybox configuration.\r\n @param {Boolean} [params.active=true] Whether the skybox plane is initially active. Only skyboxes while this is true.\r\n @returns {Skybox} The new skybox.\r\n */\r\n createSkybox(id, params) {\r\n if (this.viewer.scene.components[id]) {\r\n this.error(\"Component with this ID already exists: \" + id);\r\n return this;\r\n }\r\n var skybox = new _viewer_scene_skybox_Skybox_js__WEBPACK_IMPORTED_MODULE_1__.Skybox(this.viewer.scene, {\r\n id: id,\r\n pos: params.pos,\r\n dir: params.dir,\r\n active: true || 0\r\n });\r\n this.skyboxes[id] = skybox;\r\n return skybox;\r\n }\r\n\r\n /**\r\n Destroys a skybox.\r\n @param id\r\n */\r\n destroySkybox(id) {\r\n var skybox = this.skyboxes[id];\r\n if (!skybox) {\r\n this.error(\"Skybox not found: \" + id);\r\n return;\r\n }\r\n skybox.destroy();\r\n }\r\n\r\n /**\r\n Destroys all skyboxes.\r\n */\r\n clear() {\r\n var ids = Object.keys(this.viewer.scene.skyboxes);\r\n for (var i = 0, len = ids.length; i < len; i++) {\r\n this.destroySkybox(ids[i]);\r\n }\r\n }\r\n\r\n /**\r\n * Destroys this plugin.\r\n *\r\n * Clears skyboxes from the Viewer first.\r\n */\r\n destroy() {\r\n this.clear();\r\n super.clear();\r\n }\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SkyboxesPlugin/SkyboxesPlugin.js?");
1967
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SkyboxesPlugin: () => (/* binding */ SkyboxesPlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_skybox_Skybox_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/skybox/Skybox.js */ \"./src/viewer/scene/skybox/Skybox.js\");\n\n\n\n/**\n * {@link Viewer} plugin that manages skyboxes\n *\n * @example\n *\n * // Create a Viewer\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\"\n * });\n *\n * // Add a GLTFModelsPlugin\n * var gltfLoaderPlugin = new GLTFModelsPlugin(viewer, {\n * id: \"GLTFModels\" // Default value\n * });\n *\n * // Add a SkyboxesPlugin\n * var skyboxesPlugin = new SkyboxesPlugin(viewer, {\n * id: \"Skyboxes\" // Default value\n * });\n *\n * // Load a glTF model\n * const model = gltfLoaderPlugin.load({\n * id: \"myModel\",\n * src: \"./models/gltf/mygltfmodel.gltf\"\n * });\n *\n * // Create three directional World-space lights. \"World\" means that they will appear as if part\n * // of the world, instead of \"View\", where they move with the user's head.\n *\n * skyboxesPlugin.createLight({\n * id: \"keyLight\",\n * dir: [0.8, -0.6, -0.8],\n * color: [1.0, 0.3, 0.3],\n * intensity: 1.0,\n * space: \"world\"\n * });\n *\n * skyboxesPlugin.createLight({\n * id: \"fillLight\",\n * dir: [-0.8, -0.4, -0.4],\n * color: [0.3, 1.0, 0.3],\n * intensity: 1.0,\n * space: \"world\"\n * });\n *\n * skyboxesPlugin.createDirLight({\n * id: \"rimLight\",\n * dir: [0.2, -0.8, 0.8],\n * color: [0.6, 0.6, 0.6],\n * intensity: 1.0,\n * space: \"world\"\n * });\n *\n * @class SkyboxesPlugin\n */\nclass SkyboxesPlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__.Plugin {\n\tconstructor(viewer) {\n\t\tsuper(\"skyboxes\", viewer);\n\t\tthis.skyboxes = {};\n\t\tthis._active = true;\n\t}\n\n\t/**\n\t * @private\n\t */\n\tsend(name, value) {\n\t\tswitch (name) {\n\t\t\tcase \"clear\":\n\t\t\t\tthis.clear();\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n Creates a skybox.\n\n @param {String} id Unique ID to assign to the skybox.\n @param {Object} params Skybox configuration.\n @param {Boolean} [params.active=true] Whether the skybox plane is initially active. Only skyboxes while this is true.\n @returns {Skybox} The new skybox.\n */\n\tcreateSkybox(id, params) {\n\t\tif (this.viewer.scene.components[id]) {\n\t\t\tthis.error(\"Component with this ID already exists: \" + id);\n\t\t\treturn this;\n\t\t}\n\t\tvar skybox = new _viewer_scene_skybox_Skybox_js__WEBPACK_IMPORTED_MODULE_1__.Skybox(this.viewer.scene, {\n\t\t\tid: id,\n\t\t\tsize: params.size,\n\t\t\tscale: params.scale,\n\t\t\tsrc: params.src,\n\t\t\tpos: params.pos,\n\t\t\tdir: params.dir,\n\t\t\tactive: params.active,\n\t\t\tencoding: 3000\n\t\t});\n\t\tthis.skyboxes[id] = skybox;\n\t\treturn skybox;\n\t}\n\n\tset active(active) {\n\t\tthis._active = active;\n\t\tfor (let i = 0; i < this.skyboxes.length; i++) this.skyboxes[i].active = active;\n\t}\n\tget active() {\n\t\treturn this._active;\n\t}\n\n\t/**\n Destroys a skybox.\n @param id\n */\n\tdestroySkybox(id) {\n\t\tvar skybox = this.skyboxes[id];\n\t\tif (!skybox) {\n\t\t\tthis.error(\"Skybox not found: \" + id);\n\t\t\treturn;\n\t\t}\n\t\tskybox.destroy();\n\t}\n\n\t/**\n Destroys all skyboxes.\n */\n\tclear() {\n\t\tvar ids = Object.keys(this.viewer.scene.skyboxes);\n\t\tfor (var i = 0, len = ids.length; i < len; i++) {\n\t\t\tthis.destroySkybox(ids[i]);\n\t\t}\n\t}\n\n\t/**\n\t * Destroys this plugin.\n\t *\n\t * Clears skyboxes from the Viewer first.\n\t */\n\tdestroy() {\n\t\tthis.clear();\n\t\tsuper.clear();\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/SkyboxesPlugin/SkyboxesPlugin.js?");
1958
1968
 
1959
1969
  /***/ }),
1960
1970
 
@@ -2044,7 +2054,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2044
2054
  \******************************************************/
2045
2055
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2046
2056
 
2047
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ViewCullPlugin: () => (/* binding */ ViewCullPlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/math/Frustum.js */ \"./src/viewer/scene/math/Frustum.js\");\n/* harmony import */ var _lib_culling_ObjectCullStates_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../lib/culling/ObjectCullStates.js */ \"./src/plugins/lib/culling/ObjectCullStates.js\");\n\r\n\r\n\r\n\r\n\r\nconst MAX_KD_TREE_DEPTH = 8; // Increase if greater precision needed\r\n\r\nconst kdTreeDimLength = new Float32Array(3);\r\n\r\n/**\r\n * {@link Viewer} plugin that performs view frustum culling to accelerate rendering performance.\r\n *\r\n * For each {@link Entity} that represents an object, ````ViewCullPlugin```` will automatically\r\n * set {@link Entity#culled}````false```` whenever it falls outside our field of view.\r\n *\r\n * When culled, an ````Entity```` is not processed by xeokit's renderer.\r\n *\r\n * Internally, ````ViewCullPlugin```` organizes {@link Entity}s in\r\n * a [bounding volume hierarchy](https://en.wikipedia.org/wiki/Bounding_volume_hierarchy), implemented as\r\n * a [kd-tree](https://en.wikipedia.org/wiki/K-d_tree).\r\n *\r\n * On each {@link Scene} \"tick\" event, ````ViewCullPlugin```` searches the kd-tree using a frustum generated from\r\n * the {@link Camera}, marking each ````Entity```` **culled** if it falls outside the frustum.\r\n *\r\n * Use ````ViewCullPlugin```` by simply adding it to your ````Viewer````:\r\n *\r\n * ````javascript\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\",\r\n * transparent: true\r\n * });\r\n *\r\n * const viewCullPlugin = new ViewCullPlugin(viewer, {\r\n * maxTreeDepth: 20\r\n * });\r\n *\r\n * const xtcLoader = new XTCLoaderPlugin(viewer);\r\n *\r\n * const model = xtcLoader.load({\r\n * id: \"myModel\",\r\n * src: \"./models/xtc/OTCConferenceCenter.xtc\"\r\n * });\r\n * ````\r\n */\r\nclass ViewCullPlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__.Plugin {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Viewer} viewer The Viewer.\r\n\t * @param {Object} cfg Plugin configuration.\r\n\t * @param {String} [cfg.id=\"ViewCull\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\r\n\t * @param {Number} [cfg.maxTreeDepth=8] Maximum depth of the kd-tree.\r\n\t */\r\n\tconstructor(viewer, cfg = {}) {\r\n\t\tsuper(\"ViewCull\", viewer);\r\n\r\n\t\tthis._objectCullStates = (0,_lib_culling_ObjectCullStates_js__WEBPACK_IMPORTED_MODULE_3__.getObjectCullStates)(viewer.scene); // Combines updates from multiple culling systems for its Scene's Entities\r\n\r\n\t\tthis._maxTreeDepth = cfg.maxTreeDepth || MAX_KD_TREE_DEPTH;\r\n\t\tthis._modelInfos = {};\r\n\t\tthis._frustum = new _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum();\r\n\t\tthis._kdRoot = null;\r\n\r\n\t\tthis._frustumDirty = false;\r\n\t\tthis._kdTreeDirty = false;\r\n\r\n\t\tthis._onViewMatrix = viewer.scene.camera.on(\"viewMatrix\", () => {\r\n\t\t\tthis._frustumDirty = true;\r\n\t\t});\r\n\r\n\t\tthis._onProjMatrix = viewer.scene.camera.on(\"projMatMatrix\", () => {\r\n\t\t\tthis._frustumDirty = true;\r\n\t\t});\r\n\r\n\t\tthis._onModelLoaded = viewer.scene.on(\"modelLoaded\", (modelId) => {\r\n\t\t\tconst model = this.viewer.scene.models[modelId];\r\n\t\t\tif (model) {\r\n\t\t\t\tthis._addModel(model);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis._onSceneTick = viewer.scene.on(\"tick\", () => {\r\n\t\t\tthis._doCull();\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether view culling is enabled.\r\n\t *\r\n\t * @param {Boolean} enabled Whether to enable view culling.\r\n\t */\r\n\tset enabled(enabled) {\r\n\t\tthis._enabled = enabled;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether view culling is enabled.\r\n\t *\r\n\t * @retutns {Boolean} Whether view culling is enabled.\r\n\t */\r\n\tget enabled() {\r\n\t\treturn this._enabled;\r\n\t}\r\n\r\n\t_addModel(model) {\r\n\t\tconst modelInfo = {\r\n\t\t\tmodel: model,\r\n\t\t\tonDestroyed: model.on(\"destroyed\", () => {\r\n\t\t\t\tthis._removeModel(model);\r\n\t\t\t})\r\n\t\t};\r\n\t\tthis._modelInfos[model.id] = modelInfo;\r\n\t\tthis._kdTreeDirty = true;\r\n\t}\r\n\r\n\t_removeModel(model) {\r\n\t\tconst modelInfo = this._modelInfos[model.id];\r\n\t\tif (modelInfo) {\r\n\t\t\tmodelInfo.model.off(modelInfo.onDestroyed);\r\n\t\t\tdelete this._modelInfos[model.id];\r\n\t\t\tthis._kdTreeDirty = true;\r\n\t\t}\r\n\t}\r\n\r\n\t_doCull() {\r\n\t\tconst cullDirty = this._frustumDirty || this._kdTreeDirty;\r\n\t\tif (this._frustumDirty) {\r\n\t\t\tthis._buildFrustum();\r\n\t\t}\r\n\t\tif (this._kdTreeDirty) {\r\n\t\t\tthis._buildKDTree();\r\n\t\t}\r\n\t\tif (cullDirty) {\r\n\t\t\tconst kdNode = this._kdRoot;\r\n\t\t\tif (kdNode) {\r\n\t\t\t\tthis._visitKDNode(kdNode);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t_buildFrustum() {\r\n\t\tconst camera = this.viewer.scene.camera;\r\n\t\t(0,_viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.setFrustum)(this._frustum, camera.viewMatrix, camera.projMatrix);\r\n\t\tthis._frustumDirty = false;\r\n\t}\r\n\r\n\t_buildKDTree() {\r\n\t\tconst viewer = this.viewer;\r\n\t\tconst scene = viewer.scene;\r\n\t\tconst depth = 0;\r\n\t\tif (this._kdRoot) {\r\n\t\t\t// TODO: uncull all objects with respect to this frustum culling plugin?\r\n\t\t}\r\n\t\tthis._kdRoot = {\r\n\t\t\taabb: scene.getAABB(),\r\n\t\t\tintersection: _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT\r\n\t\t};\r\n\t\tfor (let objectIdx = 0, len = this._objectCullStates.numObjects; objectIdx < len; objectIdx++) {\r\n\t\t\tconst entity = this._objectCullStates.objects[objectIdx];\r\n\t\t\tthis._insertEntityIntoKDTree(this._kdRoot, entity, objectIdx, depth + 1);\r\n\t\t}\r\n\t\tthis._kdTreeDirty = false;\r\n\t}\r\n\r\n\t_insertEntityIntoKDTree(kdNode, entity, objectIdx, depth) {\r\n\t\tconst entityAABB = entity.aabb;\r\n\r\n\t\tif (depth >= this._maxTreeDepth) {\r\n\t\t\tkdNode.objects = kdNode.objects || [];\r\n\t\t\tkdNode.objects.push(objectIdx);\r\n\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3(kdNode.aabb, entityAABB);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (kdNode.left) {\r\n\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.containsAABB3(kdNode.left.aabb, entityAABB)) {\r\n\t\t\t\tthis._insertEntityIntoKDTree(kdNode.left, entity, objectIdx, depth + 1);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (kdNode.right) {\r\n\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.containsAABB3(kdNode.right.aabb, entityAABB)) {\r\n\t\t\t\tthis._insertEntityIntoKDTree(kdNode.right, entity, objectIdx, depth + 1);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst nodeAABB = kdNode.aabb;\r\n\r\n\t\tkdTreeDimLength[0] = nodeAABB[3] - nodeAABB[0];\r\n\t\tkdTreeDimLength[1] = nodeAABB[4] - nodeAABB[1];\r\n\t\tkdTreeDimLength[2] = nodeAABB[5] - nodeAABB[2];\r\n\r\n\t\tlet dim = 0;\r\n\r\n\t\tif (kdTreeDimLength[1] > kdTreeDimLength[dim]) {\r\n\t\t\tdim = 1;\r\n\t\t}\r\n\r\n\t\tif (kdTreeDimLength[2] > kdTreeDimLength[dim]) {\r\n\t\t\tdim = 2;\r\n\t\t}\r\n\r\n\t\tif (!kdNode.left) {\r\n\t\t\tconst aabbLeft = nodeAABB.slice();\r\n\t\t\taabbLeft[dim + 3] = (nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0;\r\n\t\t\tkdNode.left = {\r\n\t\t\t\taabb: aabbLeft,\r\n\t\t\t\tintersection: _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT\r\n\t\t\t};\r\n\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.containsAABB3(aabbLeft, entityAABB)) {\r\n\t\t\t\tthis._insertEntityIntoKDTree(kdNode.left, entity, objectIdx, depth + 1);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!kdNode.right) {\r\n\t\t\tconst aabbRight = nodeAABB.slice();\r\n\t\t\taabbRight[dim] = (nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0;\r\n\t\t\tkdNode.right = {\r\n\t\t\t\taabb: aabbRight,\r\n\t\t\t\tintersection: _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT\r\n\t\t\t};\r\n\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.containsAABB3(aabbRight, entityAABB)) {\r\n\t\t\t\tthis._insertEntityIntoKDTree(kdNode.right, entity, objectIdx, depth + 1);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tkdNode.objects = kdNode.objects || [];\r\n\t\tkdNode.objects.push(objectIdx);\r\n\r\n\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3(kdNode.aabb, entityAABB);\r\n\t}\r\n\r\n\t_visitKDNode(kdNode, intersects = _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT) {\r\n\t\tif (intersects !== _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT && kdNode.intersects === intersects) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (intersects === _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT) {\r\n\t\t\tintersects = (0,_viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.frustumIntersectsAABB3)(this._frustum, kdNode.aabb);\r\n\t\t\tkdNode.intersects = intersects;\r\n\t\t}\r\n\t\tconst culled = intersects === _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.OUTSIDE;\r\n\t\tconst objects = kdNode.objects;\r\n\t\tif (objects && objects.length > 0) {\r\n\t\t\tfor (let i = 0, len = objects.length; i < len; i++) {\r\n\t\t\t\tconst objectIdx = objects[i];\r\n\t\t\t\tthis._objectCullStates.setObjectViewCulled(objectIdx, culled);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (kdNode.left) {\r\n\t\t\tthis._visitKDNode(kdNode.left, intersects);\r\n\t\t}\r\n\t\tif (kdNode.right) {\r\n\t\t\tthis._visitKDNode(kdNode.right, intersects);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tsend(name, value) {}\r\n\r\n\t/**\r\n\t * Destroys this ViewCullPlugin.\r\n\t */\r\n\tdestroy() {\r\n\t\tsuper.destroy();\r\n\t\tthis._clear();\r\n\t\tconst scene = this.viewer.scene;\r\n\t\tconst camera = scene.camera;\r\n\t\tscene.off(this._onModelLoaded);\r\n\t\tscene.off(this._onSceneTick);\r\n\t\tcamera.off(this._onViewMatrix);\r\n\t\tcamera.off(this._onProjMatrix);\r\n\t}\r\n\r\n\t_clear() {\r\n\t\tfor (let modelId in this._modelInfos) {\r\n\t\t\tconst modelInfo = this._modelInfos[modelId];\r\n\t\t\tmodelInfo.model.off(modelInfo.onDestroyed);\r\n\t\t}\r\n\t\tthis._modelInfos = {};\r\n\t\tthis._kdRoot = null;\r\n\t\tthis._kdTreeDirty = true;\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/ViewCullPlugin/ViewCullPlugin.js?");
2057
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ViewCullPlugin: () => (/* binding */ ViewCullPlugin)\n/* harmony export */ });\n/* harmony import */ var _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../viewer/Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../viewer/scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../viewer/scene/math/Frustum.js */ \"./src/viewer/scene/math/Frustum.js\");\n/* harmony import */ var _lib_culling_ObjectCullStates_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../lib/culling/ObjectCullStates.js */ \"./src/plugins/lib/culling/ObjectCullStates.js\");\n\r\n\r\n\r\n\r\n\r\nconst MAX_KD_TREE_DEPTH = 8; // Increase if greater precision needed\r\n\r\nconst kdTreeDimLength = new Float32Array(3);\r\n\r\n/**\r\n * {@link Viewer} plugin that performs view frustum culling to accelerate rendering performance.\r\n *\r\n * For each {@link Entity} that represents an object, ````ViewCullPlugin```` will automatically\r\n * set {@link Entity#culled}````false```` whenever it falls outside our field of view.\r\n *\r\n * When culled, an ````Entity```` is not processed by xeokit's renderer.\r\n *\r\n * Internally, ````ViewCullPlugin```` organizes {@link Entity}s in\r\n * a [bounding volume hierarchy](https://en.wikipedia.org/wiki/Bounding_volume_hierarchy), implemented as\r\n * a [kd-tree](https://en.wikipedia.org/wiki/K-d_tree).\r\n *\r\n * On each {@link Scene} \"tick\" event, ````ViewCullPlugin```` searches the kd-tree using a frustum generated from\r\n * the {@link Camera}, marking each ````Entity```` **culled** if it falls outside the frustum.\r\n *\r\n * Use ````ViewCullPlugin```` by simply adding it to your ````Viewer````:\r\n *\r\n * ````javascript\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\",\r\n * transparent: true\r\n * });\r\n *\r\n * const viewCullPlugin = new ViewCullPlugin(viewer, {\r\n * maxTreeDepth: 20\r\n * });\r\n *\r\n * const xtcLoader = new XTCLoaderPlugin(viewer);\r\n *\r\n * const model = xtcLoader.load({\r\n * id: \"myModel\",\r\n * src: \"./models/xtc/OTCConferenceCenter.xtc\"\r\n * });\r\n * ````\r\n */\r\nclass ViewCullPlugin extends _viewer_Plugin_js__WEBPACK_IMPORTED_MODULE_0__.Plugin {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Viewer} viewer The Viewer.\r\n\t * @param {Object} cfg Plugin configuration.\r\n\t * @param {String} [cfg.id=\"ViewCull\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\r\n\t * @param {Number} [cfg.maxTreeDepth=8] Maximum depth of the kd-tree.\r\n\t */\r\n\tconstructor(viewer, cfg = {}) {\r\n\t\tsuper(\"ViewCull\", viewer);\r\n\r\n\t\tthis._objectCullStates = (0,_lib_culling_ObjectCullStates_js__WEBPACK_IMPORTED_MODULE_3__.getObjectCullStates)(viewer.scene); // Combines updates from multiple culling systems for its Scene's Entities\r\n\r\n\t\tthis._maxTreeDepth = cfg.maxTreeDepth || MAX_KD_TREE_DEPTH;\r\n\t\tthis._modelInfos = {};\r\n\t\tthis._frustum = new _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum();\r\n\t\tthis._kdRoot = null;\r\n\r\n\t\tthis._frustumDirty = false;\r\n\t\tthis._kdTreeDirty = false;\r\n\r\n\t\tthis._insideView = false;\r\n\t\tthis.enabled = cfg.enabled;\r\n\r\n\t\tconst camera = viewer.scene.camera;\r\n\r\n\t\tthis._onViewMatrix = viewer.scene.camera.on(\"viewMatrix\", () => {\r\n\t\t\tthis._frustumDirty = true;\r\n\t\t});\r\n\r\n\t\tthis._onProjMatrix = viewer.scene.camera.on(\"projMatMatrix\", () => {\r\n\t\t\tthis._frustumDirty = true;\r\n\t\t});\r\n\r\n\t\tthis._onModelLoaded = viewer.scene.on(\"modelLoaded\", (modelId) => {\r\n\t\t\tconst model = this.viewer.scene.models[modelId];\r\n\t\t\tif (model) {\r\n\t\t\t\tthis._addModel(model);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis._onSceneTick = viewer.scene.on(\"tick\", () => {\r\n\t\t\tif (this._enabled) this._doCull();\r\n\t\t\tthis.insideView = this.isBoxInFrustum(\r\n\t\t\t\tthis.extractFrustumPlanes(camera.projMatrix, camera.viewMatrix),\r\n\t\t\t\tviewer.scene.aabb\r\n\t\t\t);\r\n\t\t});\r\n\t}\r\n\r\n\t//包围盒和视锥相交测试\r\n\tisBoxInFrustum(frustumPlanes, aabb) {\r\n\t\tfor (let i = 0; i < 6; i++) {\r\n\t\t\tconst plane = frustumPlanes[i];\r\n\r\n\t\t\tconst p = [plane[0] > 0 ? aabb[3] : aabb[0], plane[1] > 0 ? aabb[4] : aabb[1], plane[2] > 0 ? aabb[5] : aabb[2]];\r\n\r\n\t\t\tif (plane[0] * p[0] + plane[1] * p[1] + plane[2] * p[2] + plane[3] < 0) {\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n\t//视锥计算\r\n\textractFrustumPlanes(projectionMatrix, viewMatrix) {\r\n\t\tconst combinedMatrix = _viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.identityMat4();\r\n\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulMat4(projectionMatrix, viewMatrix, combinedMatrix);\r\n\r\n\t\tconst planes = [];\r\n\r\n\t\tfor (let i = 0; i < 6; i++) {\r\n\t\t\tplanes.push(_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.identityMat4());\r\n\t\t}\r\n\r\n\t\t// Left plane\r\n\t\tplanes[0][0] = combinedMatrix[3] + combinedMatrix[0];\r\n\t\tplanes[0][1] = combinedMatrix[7] + combinedMatrix[4];\r\n\t\tplanes[0][2] = combinedMatrix[11] + combinedMatrix[8];\r\n\t\tplanes[0][3] = combinedMatrix[15] + combinedMatrix[12];\r\n\r\n\t\t// Right plane\r\n\t\tplanes[1][0] = combinedMatrix[3] - combinedMatrix[0];\r\n\t\tplanes[1][1] = combinedMatrix[7] - combinedMatrix[4];\r\n\t\tplanes[1][2] = combinedMatrix[11] - combinedMatrix[8];\r\n\t\tplanes[1][3] = combinedMatrix[15] - combinedMatrix[12];\r\n\r\n\t\t// Bottom plane\r\n\t\tplanes[2][0] = combinedMatrix[3] + combinedMatrix[1];\r\n\t\tplanes[2][1] = combinedMatrix[7] + combinedMatrix[5];\r\n\t\tplanes[2][2] = combinedMatrix[11] + combinedMatrix[9];\r\n\t\tplanes[2][3] = combinedMatrix[15] + combinedMatrix[13];\r\n\r\n\t\t// Top plane\r\n\t\tplanes[3][0] = combinedMatrix[3] - combinedMatrix[1];\r\n\t\tplanes[3][1] = combinedMatrix[7] - combinedMatrix[5];\r\n\t\tplanes[3][2] = combinedMatrix[11] - combinedMatrix[9];\r\n\t\tplanes[3][3] = combinedMatrix[15] - combinedMatrix[13];\r\n\r\n\t\t// Near plane\r\n\t\tplanes[4][0] = combinedMatrix[3] + combinedMatrix[2];\r\n\t\tplanes[4][1] = combinedMatrix[7] + combinedMatrix[6];\r\n\t\tplanes[4][2] = combinedMatrix[11] + combinedMatrix[10];\r\n\t\tplanes[4][3] = combinedMatrix[15] + combinedMatrix[14];\r\n\r\n\t\t// Far plane\r\n\t\tplanes[5][0] = combinedMatrix[3] - combinedMatrix[2];\r\n\t\tplanes[5][1] = combinedMatrix[7] - combinedMatrix[6];\r\n\t\tplanes[5][2] = combinedMatrix[11] - combinedMatrix[10];\r\n\t\tplanes[5][3] = combinedMatrix[15] - combinedMatrix[14];\r\n\r\n\t\tfor (let i = 0; i < 6; i++) {\r\n\t\t\tconst length = Math.sqrt(planes[i][0] * planes[i][0] + planes[i][1] * planes[i][1] + planes[i][2] * planes[i][2]);\r\n\r\n\t\t\tplanes[i][0] /= length;\r\n\t\t\tplanes[i][1] /= length;\r\n\t\t\tplanes[i][2] /= length;\r\n\t\t\tplanes[i][3] /= length;\r\n\t\t}\r\n\r\n\t\treturn planes;\r\n\t}\r\n\r\n\tget insideView() {\r\n\t\treturn this._insideView;\r\n\t}\r\n\r\n\tset insideView(insideView) {\r\n\t\tthis._insideView = insideView;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether view culling is enabled.\r\n\t *\r\n\t * @param {Boolean} enabled Whether to enable view culling.\r\n\t */\r\n\tset enabled(enabled) {\r\n\t\tthis._enabled = enabled;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether view culling is enabled.\r\n\t *\r\n\t * @retutns {Boolean} Whether view culling is enabled.\r\n\t */\r\n\tget enabled() {\r\n\t\treturn this._enabled;\r\n\t}\r\n\r\n\t_addModel(model) {\r\n\t\tconst modelInfo = {\r\n\t\t\tmodel: model,\r\n\t\t\tonDestroyed: model.on(\"destroyed\", () => {\r\n\t\t\t\tthis._removeModel(model);\r\n\t\t\t})\r\n\t\t};\r\n\t\tthis._modelInfos[model.id] = modelInfo;\r\n\t\tthis._kdTreeDirty = true;\r\n\t}\r\n\r\n\t_removeModel(model) {\r\n\t\tconst modelInfo = this._modelInfos[model.id];\r\n\t\tif (modelInfo) {\r\n\t\t\tmodelInfo.model.off(modelInfo.onDestroyed);\r\n\t\t\tdelete this._modelInfos[model.id];\r\n\t\t\tthis._kdTreeDirty = true;\r\n\t\t}\r\n\t}\r\n\r\n\t_doCull() {\r\n\t\tconst cullDirty = this._frustumDirty || this._kdTreeDirty;\r\n\t\tif (this._frustumDirty) {\r\n\t\t\tthis._buildFrustum();\r\n\t\t}\r\n\t\tif (this._kdTreeDirty) {\r\n\t\t\tthis._buildKDTree();\r\n\t\t}\r\n\t\tif (cullDirty) {\r\n\t\t\tconst kdNode = this._kdRoot;\r\n\t\t\tif (kdNode) {\r\n\t\t\t\tthis._visitKDNode(kdNode);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t_buildFrustum() {\r\n\t\tconst camera = this.viewer.scene.camera;\r\n\t\t(0,_viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.setFrustum)(this._frustum, camera.viewMatrix, camera.projMatrix);\r\n\t\tthis._frustumDirty = false;\r\n\t}\r\n\r\n\t_buildKDTree() {\r\n\t\tconst viewer = this.viewer;\r\n\t\tconst scene = viewer.scene;\r\n\t\tconst depth = 0;\r\n\t\tif (this._kdRoot) {\r\n\t\t\t// TODO: uncull all objects with respect to this frustum culling plugin?\r\n\t\t}\r\n\t\tthis._kdRoot = {\r\n\t\t\taabb: scene.getAABB(),\r\n\t\t\tintersection: _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT\r\n\t\t};\r\n\t\tfor (let objectIdx = 0, len = this._objectCullStates.numObjects; objectIdx < len; objectIdx++) {\r\n\t\t\tconst entity = this._objectCullStates.objects[objectIdx];\r\n\t\t\tthis._insertEntityIntoKDTree(this._kdRoot, entity, objectIdx, depth + 1);\r\n\t\t}\r\n\t\tthis._kdTreeDirty = false;\r\n\t}\r\n\r\n\t_insertEntityIntoKDTree(kdNode, entity, objectIdx, depth) {\r\n\t\tconst entityAABB = entity.aabb;\r\n\r\n\t\tif (depth >= this._maxTreeDepth) {\r\n\t\t\tkdNode.objects = kdNode.objects || [];\r\n\t\t\tkdNode.objects.push(objectIdx);\r\n\t\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3(kdNode.aabb, entityAABB);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (kdNode.left) {\r\n\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.containsAABB3(kdNode.left.aabb, entityAABB)) {\r\n\t\t\t\tthis._insertEntityIntoKDTree(kdNode.left, entity, objectIdx, depth + 1);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (kdNode.right) {\r\n\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.containsAABB3(kdNode.right.aabb, entityAABB)) {\r\n\t\t\t\tthis._insertEntityIntoKDTree(kdNode.right, entity, objectIdx, depth + 1);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst nodeAABB = kdNode.aabb;\r\n\r\n\t\tkdTreeDimLength[0] = nodeAABB[3] - nodeAABB[0];\r\n\t\tkdTreeDimLength[1] = nodeAABB[4] - nodeAABB[1];\r\n\t\tkdTreeDimLength[2] = nodeAABB[5] - nodeAABB[2];\r\n\r\n\t\tlet dim = 0;\r\n\r\n\t\tif (kdTreeDimLength[1] > kdTreeDimLength[dim]) {\r\n\t\t\tdim = 1;\r\n\t\t}\r\n\r\n\t\tif (kdTreeDimLength[2] > kdTreeDimLength[dim]) {\r\n\t\t\tdim = 2;\r\n\t\t}\r\n\r\n\t\tif (!kdNode.left) {\r\n\t\t\tconst aabbLeft = nodeAABB.slice();\r\n\t\t\taabbLeft[dim + 3] = (nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0;\r\n\t\t\tkdNode.left = {\r\n\t\t\t\taabb: aabbLeft,\r\n\t\t\t\tintersection: _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT\r\n\t\t\t};\r\n\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.containsAABB3(aabbLeft, entityAABB)) {\r\n\t\t\t\tthis._insertEntityIntoKDTree(kdNode.left, entity, objectIdx, depth + 1);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!kdNode.right) {\r\n\t\t\tconst aabbRight = nodeAABB.slice();\r\n\t\t\taabbRight[dim] = (nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0;\r\n\t\t\tkdNode.right = {\r\n\t\t\t\taabb: aabbRight,\r\n\t\t\t\tintersection: _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT\r\n\t\t\t};\r\n\t\t\tif (_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.containsAABB3(aabbRight, entityAABB)) {\r\n\t\t\t\tthis._insertEntityIntoKDTree(kdNode.right, entity, objectIdx, depth + 1);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tkdNode.objects = kdNode.objects || [];\r\n\t\tkdNode.objects.push(objectIdx);\r\n\r\n\t\t_viewer_scene_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3(kdNode.aabb, entityAABB);\r\n\t}\r\n\r\n\t_visitKDNode(kdNode, intersects = _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT) {\r\n\t\tif (intersects !== _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT && kdNode.intersects === intersects) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (intersects === _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.INTERSECT) {\r\n\t\t\tintersects = (0,_viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.frustumIntersectsAABB3)(this._frustum, kdNode.aabb);\r\n\t\t\t// this.insideView = intersects == 0 || intersects == 1;\r\n\t\t\tkdNode.intersects = intersects;\r\n\t\t}\r\n\t\tconst culled = intersects === _viewer_scene_math_Frustum_js__WEBPACK_IMPORTED_MODULE_2__.Frustum.OUTSIDE;\r\n\t\tconst objects = kdNode.objects;\r\n\t\tif (objects && objects.length > 0) {\r\n\t\t\tfor (let i = 0, len = objects.length; i < len; i++) {\r\n\t\t\t\tconst objectIdx = objects[i];\r\n\t\t\t\tthis._objectCullStates.setObjectViewCulled(objectIdx, culled);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (kdNode.left) {\r\n\t\t\tthis._visitKDNode(kdNode.left, intersects);\r\n\t\t}\r\n\t\tif (kdNode.right) {\r\n\t\t\tthis._visitKDNode(kdNode.right, intersects);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tsend(name, value) {}\r\n\r\n\t/**\r\n\t * Destroys this ViewCullPlugin.\r\n\t */\r\n\tdestroy() {\r\n\t\tsuper.destroy();\r\n\t\tthis._clear();\r\n\t\tconst scene = this.viewer.scene;\r\n\t\tconst camera = scene.camera;\r\n\t\tscene.off(this._onModelLoaded);\r\n\t\tscene.off(this._onSceneTick);\r\n\t\tcamera.off(this._onViewMatrix);\r\n\t\tcamera.off(this._onProjMatrix);\r\n\t}\r\n\r\n\t_clear() {\r\n\t\tfor (let modelId in this._modelInfos) {\r\n\t\t\tconst modelInfo = this._modelInfos[modelId];\r\n\t\t\tmodelInfo.model.off(modelInfo.onDestroyed);\r\n\t\t}\r\n\t\tthis._modelInfos = {};\r\n\t\tthis._kdRoot = null;\r\n\t\tthis._kdTreeDirty = true;\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/plugins/ViewCullPlugin/ViewCullPlugin.js?");
2048
2058
 
2049
2059
  /***/ }),
2050
2060
 
@@ -2374,7 +2384,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2374
2384
  \*****************************/
2375
2385
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2376
2386
 
2377
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AlphaFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.AlphaFormat),\n/* harmony export */ AmbientLight: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.AmbientLight),\n/* harmony export */ Bitmap: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Bitmap),\n/* harmony export */ ByteType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ByteType),\n/* harmony export */ CameraMemento: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CameraMemento),\n/* harmony export */ CameraPath: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CameraPath),\n/* harmony export */ CameraPathAnimation: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CameraPathAnimation),\n/* harmony export */ ClampToEdgeWrapping: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ClampToEdgeWrapping),\n/* harmony export */ Component: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Component),\n/* harmony export */ CompressedMediaType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CompressedMediaType),\n/* harmony export */ Configs: () => (/* reexport safe */ _Configs_js__WEBPACK_IMPORTED_MODULE_4__.Configs),\n/* harmony export */ CubicBezierCurve: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CubicBezierCurve),\n/* harmony export */ Curve: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Curve),\n/* harmony export */ DefaultLoadingManager: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.DefaultLoadingManager),\n/* harmony export */ DepthFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.DepthFormat),\n/* harmony export */ DepthStencilFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.DepthStencilFormat),\n/* harmony export */ DirLight: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.DirLight),\n/* harmony export */ EdgeMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.EdgeMaterial),\n/* harmony export */ EmphasisMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.EmphasisMaterial),\n/* harmony export */ FloatType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.FloatType),\n/* harmony export */ Fresnel: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Fresnel),\n/* harmony export */ Frustum: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Frustum),\n/* harmony export */ FrustumPlane: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.FrustumPlane),\n/* harmony export */ GIFMediaType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.GIFMediaType),\n/* harmony export */ HalfFloatType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.HalfFloatType),\n/* harmony export */ ImagePlane: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ImagePlane),\n/* harmony export */ IntType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.IntType),\n/* harmony export */ JPEGMediaType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.JPEGMediaType),\n/* harmony export */ KTX2TextureTranscoder: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.KTX2TextureTranscoder),\n/* harmony export */ LambertMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LambertMaterial),\n/* harmony export */ LightMap: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LightMap),\n/* harmony export */ LineSet: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LineSet),\n/* harmony export */ LinearEncoding: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearEncoding),\n/* harmony export */ LinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearFilter),\n/* harmony export */ LinearMipMapLinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearMipMapLinearFilter),\n/* harmony export */ LinearMipMapNearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearMipMapNearestFilter),\n/* harmony export */ LinearMipmapLinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearMipmapLinearFilter),\n/* harmony export */ LinearMipmapNearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearMipmapNearestFilter),\n/* harmony export */ Loader: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Loader),\n/* harmony export */ LoadingManager: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LoadingManager),\n/* harmony export */ LocaleService: () => (/* reexport safe */ _localization_LocaleService_js__WEBPACK_IMPORTED_MODULE_0__.LocaleService),\n/* harmony export */ LuminanceAlphaFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LuminanceAlphaFormat),\n/* harmony export */ LuminanceFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LuminanceFormat),\n/* harmony export */ Map: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Map),\n/* harmony export */ Marker: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Marker),\n/* harmony export */ Mesh: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Mesh),\n/* harmony export */ MetallicMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.MetallicMaterial),\n/* harmony export */ MirroredRepeatWrapping: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.MirroredRepeatWrapping),\n/* harmony export */ ModelMemento: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ModelMemento),\n/* harmony export */ NearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestFilter),\n/* harmony export */ NearestMipMapLinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestMipMapLinearFilter),\n/* harmony export */ NearestMipMapNearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestMipMapNearestFilter),\n/* harmony export */ NearestMipmapLinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestMipmapLinearFilter),\n/* harmony export */ NearestMipmapNearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestMipmapNearestFilter),\n/* harmony export */ Node: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Node),\n/* harmony export */ ObjectsMemento: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ObjectsMemento),\n/* harmony export */ PNGMediaType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.PNGMediaType),\n/* harmony export */ Path: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Path),\n/* harmony export */ PerformanceModel: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.PerformanceModel),\n/* harmony export */ PhongMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.PhongMaterial),\n/* harmony export */ Plugin: () => (/* reexport safe */ _Plugin_js__WEBPACK_IMPORTED_MODULE_2__.Plugin),\n/* harmony export */ PointLight: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.PointLight),\n/* harmony export */ QuadraticBezierCurve: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.QuadraticBezierCurve),\n/* harmony export */ Queue: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Queue),\n/* harmony export */ RGBAFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBAFormat),\n/* harmony export */ RGBAIntegerFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBAIntegerFormat),\n/* harmony export */ RGBA_ASTC_10x10_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_10x10_Format),\n/* harmony export */ RGBA_ASTC_10x5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_10x5_Format),\n/* harmony export */ RGBA_ASTC_10x6_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_10x6_Format),\n/* harmony export */ RGBA_ASTC_10x8_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_10x8_Format),\n/* harmony export */ RGBA_ASTC_12x10_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_12x10_Format),\n/* harmony export */ RGBA_ASTC_12x12_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_12x12_Format),\n/* harmony export */ RGBA_ASTC_4x4_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_4x4_Format),\n/* harmony export */ RGBA_ASTC_5x4_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_5x4_Format),\n/* harmony export */ RGBA_ASTC_5x5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_5x5_Format),\n/* harmony export */ RGBA_ASTC_6x5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_6x5_Format),\n/* harmony export */ RGBA_ASTC_6x6_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_6x6_Format),\n/* harmony export */ RGBA_ASTC_8x5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_8x5_Format),\n/* harmony export */ RGBA_ASTC_8x6_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_8x6_Format),\n/* harmony export */ RGBA_ASTC_8x8_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_8x8_Format),\n/* harmony export */ RGBA_BPTC_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_BPTC_Format),\n/* harmony export */ RGBA_ETC2_EAC_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ETC2_EAC_Format),\n/* harmony export */ RGBA_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_PVRTC_2BPPV1_Format),\n/* harmony export */ RGBA_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_PVRTC_4BPPV1_Format),\n/* harmony export */ RGBA_S3TC_DXT1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_S3TC_DXT1_Format),\n/* harmony export */ RGBA_S3TC_DXT3_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_S3TC_DXT3_Format),\n/* harmony export */ RGBA_S3TC_DXT5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_S3TC_DXT5_Format),\n/* harmony export */ RGBFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBFormat),\n/* harmony export */ RGB_ETC1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_ETC1_Format),\n/* harmony export */ RGB_ETC2_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_ETC2_Format),\n/* harmony export */ RGB_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_PVRTC_2BPPV1_Format),\n/* harmony export */ RGB_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_PVRTC_4BPPV1_Format),\n/* harmony export */ RGB_S3TC_DXT1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_S3TC_DXT1_Format),\n/* harmony export */ RGFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGFormat),\n/* harmony export */ RGIntegerFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGIntegerFormat),\n/* harmony export */ ReadableGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ReadableGeometry),\n/* harmony export */ RedFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RedFormat),\n/* harmony export */ RedIntegerFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RedIntegerFormat),\n/* harmony export */ ReflectionMap: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ReflectionMap),\n/* harmony export */ RepeatWrapping: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RepeatWrapping),\n/* harmony export */ SceneModel: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SceneModel),\n/* harmony export */ SceneModelMesh: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SceneModelMesh),\n/* harmony export */ SceneModelTransform: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SceneModelTransform),\n/* harmony export */ SectionBox: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SectionBox),\n/* harmony export */ SectionPlane: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SectionPlane),\n/* harmony export */ ShortType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ShortType),\n/* harmony export */ Skybox: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Skybox),\n/* harmony export */ SpecularMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SpecularMaterial),\n/* harmony export */ SplineCurve: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SplineCurve),\n/* harmony export */ SpriteMarker: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SpriteMarker),\n/* harmony export */ Texture: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Texture),\n/* harmony export */ TextureTranscoder: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.TextureTranscoder),\n/* harmony export */ UnsignedByteType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedByteType),\n/* harmony export */ UnsignedInt248Type: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedInt248Type),\n/* harmony export */ UnsignedIntType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedIntType),\n/* harmony export */ UnsignedShort4444Type: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedShort4444Type),\n/* harmony export */ UnsignedShort5551Type: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedShort5551Type),\n/* harmony export */ UnsignedShortType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedShortType),\n/* harmony export */ VBOGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.VBOGeometry),\n/* harmony export */ Viewer: () => (/* reexport safe */ _Viewer_js__WEBPACK_IMPORTED_MODULE_3__.Viewer),\n/* harmony export */ WorkerPool: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.WorkerPool),\n/* harmony export */ buildBoxGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildBoxGeometry),\n/* harmony export */ buildBoxLinesGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildBoxLinesGeometry),\n/* harmony export */ buildCylinderGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry),\n/* harmony export */ buildGridGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildGridGeometry),\n/* harmony export */ buildPlaneGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildPlaneGeometry),\n/* harmony export */ buildSphereGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildSphereGeometry),\n/* harmony export */ buildTorusGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildTorusGeometry),\n/* harmony export */ buildVectorTextGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildVectorTextGeometry),\n/* harmony export */ createRTCViewMat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.createRTCViewMat),\n/* harmony export */ frustumIntersectsAABB3: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.frustumIntersectsAABB3),\n/* harmony export */ getKTX2TextureTranscoder: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.getKTX2TextureTranscoder),\n/* harmony export */ getPlaneRTCPos: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.getPlaneRTCPos),\n/* harmony export */ load3DSGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.load3DSGeometry),\n/* harmony export */ loadOBJGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.loadOBJGeometry),\n/* harmony export */ math: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.math),\n/* harmony export */ rtcToWorldPos: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.rtcToWorldPos),\n/* harmony export */ sRGBEncoding: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.sRGBEncoding),\n/* harmony export */ setFrustum: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.setFrustum),\n/* harmony export */ stats: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.stats),\n/* harmony export */ utils: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.utils),\n/* harmony export */ worldToRTCPos: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.worldToRTCPos),\n/* harmony export */ worldToRTCPositions: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.worldToRTCPositions)\n/* harmony export */ });\n/* harmony import */ var _localization_LocaleService_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./localization/LocaleService.js */ \"./src/viewer/localization/LocaleService.js\");\n/* harmony import */ var _scene_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./scene/index.js */ \"./src/viewer/scene/index.js\");\n/* harmony import */ var _Plugin_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _Viewer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Viewer.js */ \"./src/viewer/Viewer.js\");\n/* harmony import */ var _Configs_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Configs.js */ \"./src/viewer/Configs.js\");\n\r\n\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/index.js?");
2387
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AlphaFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.AlphaFormat),\n/* harmony export */ AmbientLight: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.AmbientLight),\n/* harmony export */ Bitmap: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Bitmap),\n/* harmony export */ ByteType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ByteType),\n/* harmony export */ CameraMemento: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CameraMemento),\n/* harmony export */ CameraPath: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CameraPath),\n/* harmony export */ CameraPathAnimation: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CameraPathAnimation),\n/* harmony export */ Canvas: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Canvas),\n/* harmony export */ ClampToEdgeWrapping: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ClampToEdgeWrapping),\n/* harmony export */ Component: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Component),\n/* harmony export */ CompressedMediaType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CompressedMediaType),\n/* harmony export */ Configs: () => (/* reexport safe */ _Configs_js__WEBPACK_IMPORTED_MODULE_4__.Configs),\n/* harmony export */ CubicBezierCurve: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.CubicBezierCurve),\n/* harmony export */ Curve: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Curve),\n/* harmony export */ DefaultLoadingManager: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.DefaultLoadingManager),\n/* harmony export */ DepthFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.DepthFormat),\n/* harmony export */ DepthStencilFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.DepthStencilFormat),\n/* harmony export */ DirLight: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.DirLight),\n/* harmony export */ EdgeMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.EdgeMaterial),\n/* harmony export */ EmphasisMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.EmphasisMaterial),\n/* harmony export */ FloatType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.FloatType),\n/* harmony export */ Fresnel: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Fresnel),\n/* harmony export */ Frustum: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Frustum),\n/* harmony export */ FrustumPlane: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.FrustumPlane),\n/* harmony export */ GIFMediaType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.GIFMediaType),\n/* harmony export */ HalfFloatType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.HalfFloatType),\n/* harmony export */ ImagePlane: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ImagePlane),\n/* harmony export */ IntType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.IntType),\n/* harmony export */ JPEGMediaType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.JPEGMediaType),\n/* harmony export */ KTX2TextureTranscoder: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.KTX2TextureTranscoder),\n/* harmony export */ LambertMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LambertMaterial),\n/* harmony export */ LightMap: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LightMap),\n/* harmony export */ LineSet: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LineSet),\n/* harmony export */ LinearEncoding: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearEncoding),\n/* harmony export */ LinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearFilter),\n/* harmony export */ LinearMipMapLinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearMipMapLinearFilter),\n/* harmony export */ LinearMipMapNearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearMipMapNearestFilter),\n/* harmony export */ LinearMipmapLinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearMipmapLinearFilter),\n/* harmony export */ LinearMipmapNearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LinearMipmapNearestFilter),\n/* harmony export */ Loader: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Loader),\n/* harmony export */ LoadingManager: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LoadingManager),\n/* harmony export */ LocaleService: () => (/* reexport safe */ _localization_LocaleService_js__WEBPACK_IMPORTED_MODULE_0__.LocaleService),\n/* harmony export */ LuminanceAlphaFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LuminanceAlphaFormat),\n/* harmony export */ LuminanceFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.LuminanceFormat),\n/* harmony export */ Map: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Map),\n/* harmony export */ Marker: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Marker),\n/* harmony export */ Mesh: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Mesh),\n/* harmony export */ MetallicMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.MetallicMaterial),\n/* harmony export */ MirroredRepeatWrapping: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.MirroredRepeatWrapping),\n/* harmony export */ ModelMemento: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ModelMemento),\n/* harmony export */ NearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestFilter),\n/* harmony export */ NearestMipMapLinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestMipMapLinearFilter),\n/* harmony export */ NearestMipMapNearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestMipMapNearestFilter),\n/* harmony export */ NearestMipmapLinearFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestMipmapLinearFilter),\n/* harmony export */ NearestMipmapNearestFilter: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.NearestMipmapNearestFilter),\n/* harmony export */ Node: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Node),\n/* harmony export */ ObjectsMemento: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ObjectsMemento),\n/* harmony export */ PNGMediaType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.PNGMediaType),\n/* harmony export */ Path: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Path),\n/* harmony export */ PerformanceModel: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.PerformanceModel),\n/* harmony export */ PhongMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.PhongMaterial),\n/* harmony export */ Plugin: () => (/* reexport safe */ _Plugin_js__WEBPACK_IMPORTED_MODULE_2__.Plugin),\n/* harmony export */ PointLight: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.PointLight),\n/* harmony export */ QuadraticBezierCurve: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.QuadraticBezierCurve),\n/* harmony export */ Queue: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Queue),\n/* harmony export */ RGBAFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBAFormat),\n/* harmony export */ RGBAIntegerFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBAIntegerFormat),\n/* harmony export */ RGBA_ASTC_10x10_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_10x10_Format),\n/* harmony export */ RGBA_ASTC_10x5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_10x5_Format),\n/* harmony export */ RGBA_ASTC_10x6_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_10x6_Format),\n/* harmony export */ RGBA_ASTC_10x8_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_10x8_Format),\n/* harmony export */ RGBA_ASTC_12x10_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_12x10_Format),\n/* harmony export */ RGBA_ASTC_12x12_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_12x12_Format),\n/* harmony export */ RGBA_ASTC_4x4_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_4x4_Format),\n/* harmony export */ RGBA_ASTC_5x4_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_5x4_Format),\n/* harmony export */ RGBA_ASTC_5x5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_5x5_Format),\n/* harmony export */ RGBA_ASTC_6x5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_6x5_Format),\n/* harmony export */ RGBA_ASTC_6x6_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_6x6_Format),\n/* harmony export */ RGBA_ASTC_8x5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_8x5_Format),\n/* harmony export */ RGBA_ASTC_8x6_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_8x6_Format),\n/* harmony export */ RGBA_ASTC_8x8_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ASTC_8x8_Format),\n/* harmony export */ RGBA_BPTC_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_BPTC_Format),\n/* harmony export */ RGBA_ETC2_EAC_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_ETC2_EAC_Format),\n/* harmony export */ RGBA_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_PVRTC_2BPPV1_Format),\n/* harmony export */ RGBA_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_PVRTC_4BPPV1_Format),\n/* harmony export */ RGBA_S3TC_DXT1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_S3TC_DXT1_Format),\n/* harmony export */ RGBA_S3TC_DXT3_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_S3TC_DXT3_Format),\n/* harmony export */ RGBA_S3TC_DXT5_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBA_S3TC_DXT5_Format),\n/* harmony export */ RGBFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGBFormat),\n/* harmony export */ RGB_ETC1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_ETC1_Format),\n/* harmony export */ RGB_ETC2_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_ETC2_Format),\n/* harmony export */ RGB_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_PVRTC_2BPPV1_Format),\n/* harmony export */ RGB_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_PVRTC_4BPPV1_Format),\n/* harmony export */ RGB_S3TC_DXT1_Format: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGB_S3TC_DXT1_Format),\n/* harmony export */ RGFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGFormat),\n/* harmony export */ RGIntegerFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RGIntegerFormat),\n/* harmony export */ ReadableGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ReadableGeometry),\n/* harmony export */ RedFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RedFormat),\n/* harmony export */ RedIntegerFormat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RedIntegerFormat),\n/* harmony export */ ReflectionMap: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ReflectionMap),\n/* harmony export */ Renderer: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Renderer),\n/* harmony export */ RepeatWrapping: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.RepeatWrapping),\n/* harmony export */ Scene: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Scene),\n/* harmony export */ SceneModel: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SceneModel),\n/* harmony export */ SceneModelMesh: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SceneModelMesh),\n/* harmony export */ SceneModelTransform: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SceneModelTransform),\n/* harmony export */ SectionBox: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SectionBox),\n/* harmony export */ SectionPlane: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SectionPlane),\n/* harmony export */ ShortType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.ShortType),\n/* harmony export */ Skybox: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Skybox),\n/* harmony export */ SpecularMaterial: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SpecularMaterial),\n/* harmony export */ SplineCurve: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SplineCurve),\n/* harmony export */ SpriteMarker: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.SpriteMarker),\n/* harmony export */ Texture: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.Texture),\n/* harmony export */ TextureTranscoder: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.TextureTranscoder),\n/* harmony export */ UnsignedByteType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedByteType),\n/* harmony export */ UnsignedInt248Type: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedInt248Type),\n/* harmony export */ UnsignedIntType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedIntType),\n/* harmony export */ UnsignedShort4444Type: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedShort4444Type),\n/* harmony export */ UnsignedShort5551Type: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedShort5551Type),\n/* harmony export */ UnsignedShortType: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.UnsignedShortType),\n/* harmony export */ VBOGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.VBOGeometry),\n/* harmony export */ Viewer: () => (/* reexport safe */ _Viewer_js__WEBPACK_IMPORTED_MODULE_3__.Viewer),\n/* harmony export */ WorkerPool: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.WorkerPool),\n/* harmony export */ buildBoxGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildBoxGeometry),\n/* harmony export */ buildBoxLinesGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildBoxLinesGeometry),\n/* harmony export */ buildCylinderGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry),\n/* harmony export */ buildGridGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildGridGeometry),\n/* harmony export */ buildPlaneGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildPlaneGeometry),\n/* harmony export */ buildSphereGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildSphereGeometry),\n/* harmony export */ buildTorusGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildTorusGeometry),\n/* harmony export */ buildVectorTextGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.buildVectorTextGeometry),\n/* harmony export */ createRTCViewMat: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.createRTCViewMat),\n/* harmony export */ frustumIntersectsAABB3: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.frustumIntersectsAABB3),\n/* harmony export */ getKTX2TextureTranscoder: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.getKTX2TextureTranscoder),\n/* harmony export */ getPlaneRTCPos: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.getPlaneRTCPos),\n/* harmony export */ load3DSGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.load3DSGeometry),\n/* harmony export */ loadOBJGeometry: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.loadOBJGeometry),\n/* harmony export */ math: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.math),\n/* harmony export */ rtcToWorldPos: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.rtcToWorldPos),\n/* harmony export */ sRGBEncoding: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.sRGBEncoding),\n/* harmony export */ setFrustum: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.setFrustum),\n/* harmony export */ stats: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.stats),\n/* harmony export */ utils: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.utils),\n/* harmony export */ worldToRTCPos: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.worldToRTCPos),\n/* harmony export */ worldToRTCPositions: () => (/* reexport safe */ _scene_index_js__WEBPACK_IMPORTED_MODULE_1__.worldToRTCPositions)\n/* harmony export */ });\n/* harmony import */ var _localization_LocaleService_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./localization/LocaleService.js */ \"./src/viewer/localization/LocaleService.js\");\n/* harmony import */ var _scene_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./scene/index.js */ \"./src/viewer/scene/index.js\");\n/* harmony import */ var _Plugin_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Plugin.js */ \"./src/viewer/Plugin.js\");\n/* harmony import */ var _Viewer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Viewer.js */ \"./src/viewer/Viewer.js\");\n/* harmony import */ var _Configs_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Configs.js */ \"./src/viewer/Configs.js\");\n\r\n\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/index.js?");
2378
2388
 
2379
2389
  /***/ }),
2380
2390
 
@@ -2424,7 +2434,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2424
2434
  \******************************************/
2425
2435
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2426
2436
 
2427
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ MetaScene: () => (/* binding */ MetaScene)\n/* harmony export */ });\n/* harmony import */ var _MetaModel_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./MetaModel.js */ \"./src/viewer/metadata/MetaModel.js\");\n/* harmony import */ var _MetaObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./MetaObject.js */ \"./src/viewer/metadata/MetaObject.js\");\n/* harmony import */ var _PropertySet_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./PropertySet.js */ \"./src/viewer/metadata/PropertySet.js\");\n/* harmony import */ var _scene_math_math_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n\r\n\r\n\r\n\r\n\r\n/**\r\n * @desc Metadata corresponding to a {@link Scene}.\r\n *\r\n * * Located in {@link Viewer#metaScene}.\r\n * * Contains {@link MetaModel}s and {@link MetaObject}s.\r\n * * [Scene graph example with metadata](http://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneGraph_metadata)\r\n */\r\nclass MetaScene {\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tconstructor(viewer, scene) {\r\n\t\t/**\r\n\t\t * The {@link Viewer}.\r\n\t\t * @property viewer\r\n\t\t * @type {Viewer}\r\n\t\t */\r\n\t\tthis.viewer = viewer;\r\n\r\n\t\t/**\r\n\t\t * The {@link Scene}.\r\n\t\t * @property scene\r\n\t\t * @type {Scene}\r\n\t\t */\r\n\t\tthis.scene = scene;\r\n\r\n\t\t/**\r\n\t\t * The {@link MetaModel}s belonging to this MetaScene, each mapped to its {@link MetaModel#modelId}.\r\n\t\t *\r\n\t\t * @type {{String:MetaModel}}\r\n\t\t */\r\n\t\tthis.metaModels = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link PropertySet}s belonging to this MetaScene, each mapped to its {@link PropertySet#id}.\r\n\t\t *\r\n\t\t * @type {{String:PropertySet}}\r\n\t\t */\r\n\t\tthis.propertySets = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link MetaObject}s belonging to this MetaScene, each mapped to its {@link MetaObject#id}.\r\n\t\t *\r\n\t\t * @type {{String:MetaObject}}\r\n\t\t */\r\n\t\tthis.metaObjects = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link MetaObject}s belonging to this MetaScene, each mapped to its {@link MetaObject#type}.\r\n\t\t *\r\n\t\t * @type {{String:MetaObject}}\r\n\t\t */\r\n\t\tthis.metaObjectsByType = {};\r\n\r\n\t\t/**\r\n\t\t * The root {@link MetaObject}s belonging to this MetaScene, each mapped to its {@link MetaObject#id}.\r\n\t\t *\r\n\t\t * @type {{String:MetaObject}}\r\n\t\t */\r\n\t\tthis.rootMetaObjects = {};\r\n\r\n\t\t/**\r\n\t\t * Subscriptions to events sent with {@link fire}.\r\n\t\t * @private\r\n\t\t */\r\n\t\tthis._eventSubs = {};\r\n\t}\r\n\r\n\t/**\r\n\t * Subscribes to an event fired at this Viewer.\r\n\t *\r\n\t * @param {String} event The event\r\n\t * @param {Function} callback Callback fired on the event\r\n\t */\r\n\ton(event, callback) {\r\n\t\tlet subs = this._eventSubs[event];\r\n\t\tif (!subs) {\r\n\t\t\tsubs = [];\r\n\t\t\tthis._eventSubs[event] = subs;\r\n\t\t}\r\n\t\tsubs.push(callback);\r\n\t}\r\n\r\n\t/**\r\n\t * Fires an event at this Viewer.\r\n\t *\r\n\t * @param {String} event Event name\r\n\t * @param {Object} value Event parameters\r\n\t */\r\n\tfire(event, value) {\r\n\t\tconst subs = this._eventSubs[event];\r\n\t\tif (subs) {\r\n\t\t\tfor (let i = 0, len = subs.length; i < len; i++) {\r\n\t\t\t\tsubs[i](value);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Unsubscribes from an event fired at this Viewer.\r\n\t * @param event\r\n\t */\r\n\toff(event) {\r\n\t\t// TODO\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a {@link MetaModel} in this MetaScene.\r\n\t *\r\n\t * The MetaModel will contain a hierarchy of {@link MetaObject}s, created from the\r\n\t * meta objects in ````metaModelData````.\r\n\t *\r\n\t * The meta object hierarchy in ````metaModelData```` is expected to be non-cyclic, with a single root. If the meta\r\n\t * objects are cyclic, then this method will log an error and attempt to recover by creating a dummy root MetaObject\r\n\t * of type \"Model\" and connecting all other MetaObjects as its direct children. If the meta objects contain multiple\r\n\t * roots, then this method similarly attempts to recover by creating a dummy root MetaObject of type \"Model\" and\r\n\t * connecting all the root MetaObjects as its children.\r\n\t *\r\n\t * @param {String} modelId ID for the new {@link MetaModel}, which will have {@link MetaModel#id} set to this value.\r\n\t * @param {Object} metaModelData Data for the {@link MetaModel}.\r\n\t * @param {Object} [options] Options for creating the {@link MetaModel}.\r\n\t * @param {Object} [options.includeTypes] When provided, only create {@link MetaObject}s with types in this list.\r\n\t * @param {Object} [options.excludeTypes] When provided, never create {@link MetaObject}s with types in this list.\r\n\t * @param {Boolean} [options.globalizeObjectIds=false] Whether to globalize each {@link MetaObject#id}. Set this ````true```` when you need to load multiple instances of the same meta model, to avoid ID clashes between the meta objects in the different instances.\r\n\t * @returns {MetaModel} The new MetaModel.\r\n\t */\r\n\tcreateMetaModel(modelId, metaModelData, options = {}) {\r\n\t\tconst metaModel = new _MetaModel_js__WEBPACK_IMPORTED_MODULE_0__.MetaModel({\r\n\t\t\t// Registers MetaModel in #metaModels\r\n\t\t\tmetaScene: this,\r\n\t\t\tid: modelId,\r\n\t\t\tprojectId: metaModelData.projectId || \"none\",\r\n\t\t\trevisionId: metaModelData.revisionId || \"none\",\r\n\t\t\tauthor: metaModelData.author || \"none\",\r\n\t\t\tcreatedAt: metaModelData.createdAt || \"none\",\r\n\t\t\tcreatingApplication: metaModelData.creatingApplication || \"none\",\r\n\t\t\tschema: metaModelData.schema || \"none\",\r\n\t\t\tpropertySets: []\r\n\t\t});\r\n\r\n\t\tmetaModel.loadData(metaModelData);\r\n\t\tmetaModel.finalize();\r\n\r\n\t\treturn metaModel;\r\n\t}\r\n\r\n\t/**\r\n\t * Removes a {@link MetaModel} from this MetaScene.\r\n\t *\r\n\t * Fires a \"metaModelDestroyed\" event with the value of the {@link MetaModel#id}.\r\n\t *\r\n\t * @param {String} metaModelId ID of the target {@link MetaModel}.\r\n\t */\r\n\tdestroyMetaModel(metaModelId) {\r\n\t\tconst metaModel = this.metaModels[metaModelId];\r\n\t\tif (!metaModel) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Remove global PropertySets\r\n\r\n\t\tif (metaModel.propertySets) {\r\n\t\t\tfor (let i = 0, len = metaModel.propertySets.length; i < len; i++) {\r\n\t\t\t\tconst propertySet = metaModel.propertySets[i];\r\n\t\t\t\tif (propertySet.metaModels.length === 1 && propertySet.metaModels[0].id === metaModelId) {\r\n\t\t\t\t\t// Property set owned only by this model, delete\r\n\t\t\t\t\tdelete this.propertySets[propertySet.id];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconst newMetaModels = [];\r\n\t\t\t\t\tfor (let j = 0, lenj = propertySet.metaModels.length; j < lenj; j++) {\r\n\t\t\t\t\t\tif (propertySet.metaModels[j].id !== metaModelId) {\r\n\t\t\t\t\t\t\tnewMetaModels.push(propertySet.metaModels[j]);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tpropertySet.metaModels = newMetaModels;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Remove MetaObjects\r\n\r\n\t\tif (metaModel.metaObjects) {\r\n\t\t\tfor (let i = 0, len = metaModel.metaObjects.length; i < len; i++) {\r\n\t\t\t\tconst metaObject = metaModel.metaObjects[i];\r\n\t\t\t\tconst type = metaObject.type;\r\n\t\t\t\tconst id = metaObject.id;\r\n\t\t\t\tif (metaObject.metaModels.length === 1 && metaObject.metaModels[0].id === metaModelId) {\r\n\t\t\t\t\t// MetaObject owned only by this model, delete\r\n\t\t\t\t\tdelete this.metaObjects[id];\r\n\t\t\t\t\tif (!metaObject.parent) {\r\n\t\t\t\t\t\tdelete this.rootMetaObjects[id];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Re-link entire MetaObject parent/child hierarchy\r\n\r\n\t\tfor (let objectId in this.metaObjects) {\r\n\t\t\tconst metaObject = this.metaObjects[objectId];\r\n\t\t\tif (metaObject.children) {\r\n\t\t\t\tmetaObject.children = [];\r\n\t\t\t}\r\n\r\n\t\t\t// Re-link each MetaObject's property sets\r\n\r\n\t\t\tif (metaObject.propertySets) {\r\n\t\t\t\tmetaObject.propertySets = [];\r\n\t\t\t}\r\n\t\t\tif (metaObject.propertySetIds) {\r\n\t\t\t\tfor (let i = 0, len = metaObject.propertySetIds.length; i < len; i++) {\r\n\t\t\t\t\tconst propertySetId = metaObject.propertySetIds[i];\r\n\t\t\t\t\tconst propertySet = this.propertySets[propertySetId];\r\n\t\t\t\t\tmetaObject.propertySets.push(propertySet);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.metaObjectsByType = {};\r\n\r\n\t\tfor (let objectId in this.metaObjects) {\r\n\t\t\tconst metaObject = this.metaObjects[objectId];\r\n\t\t\tconst type = metaObject.type;\r\n\t\t\tif (metaObject.children) {\r\n\t\t\t\tmetaObject.children = null;\r\n\t\t\t}\r\n\t\t\t(this.metaObjectsByType[type] || (this.metaObjectsByType[type] = {}))[objectId] = metaObject;\r\n\t\t}\r\n\r\n\t\tfor (let objectId in this.metaObjects) {\r\n\t\t\tconst metaObject = this.metaObjects[objectId];\r\n\t\t\tif (metaObject.parentId) {\r\n\t\t\t\tconst parentMetaObject = this.metaObjects[metaObject.parentId];\r\n\t\t\t\tif (parentMetaObject) {\r\n\t\t\t\t\tmetaObject.parent = parentMetaObject;\r\n\t\t\t\t\t(parentMetaObject.children || (parentMetaObject.children = [])).push(metaObject);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tdelete this.metaModels[metaModelId];\r\n\r\n\t\t// Relink MetaObjects to their MetaModels\r\n\r\n\t\t// for (let objectId in this.metaObjects) {\r\n\t\t// \tconst metaObject = this.metaObjects[objectId];\r\n\t\t// \tmetaObject.metaModels = [];\r\n\t\t// }\r\n\r\n\t\t// for (let modelId in this.metaModels) {\r\n\t\t// \tconst metaModel = this.metaModels[modelId];\r\n\t\t// \tfor (let i = 0, len = metaModel.metaObjects.length; i < len; i++) {\r\n\t\t// \t\tconst metaObject = metaModel.metaObjects[i];\r\n\t\t// \t\tmetaObject.metaModels.push(metaModel);\r\n\t\t// \t}\r\n\t\t// }\r\n\r\n\t\tthis.fire(\"metaModelDestroyed\", metaModelId);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the {@link MetaObject#id}s of the {@link MetaObject}s that have the given {@link MetaObject#type}.\r\n\t *\r\n\t * @param {String} type The type.\r\n\t * @returns {String[]} Array of {@link MetaObject#id}s.\r\n\t */\r\n\tgetObjectIDsByType(type) {\r\n\t\tconst metaObjects = this.metaObjectsByType[type];\r\n\t\treturn metaObjects ? Object.keys(metaObjects) : [];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the {@link MetaObject#id}s of the {@link MetaObject}s within the given subtree.\r\n\t *\r\n\t * @param {String} id ID of the root {@link MetaObject} of the given subtree.\r\n\t * @param {String[]} [includeTypes] Optional list of types to include.\r\n\t * @param {String[]} [excludeTypes] Optional list of types to exclude.\r\n\t * @returns {String[]} Array of {@link MetaObject#id}s.\r\n\t */\r\n\tgetObjectIDsInSubtree(id, includeTypes, excludeTypes) {\r\n\t\tconst list = [];\r\n\t\tconst metaObject = this.metaObjects[id];\r\n\t\tconst includeMask = includeTypes && includeTypes.length > 0 ? arrayToMap(includeTypes) : null;\r\n\t\tconst excludeMask = excludeTypes && excludeTypes.length > 0 ? arrayToMap(excludeTypes) : null;\r\n\r\n\t\tconst visit = (metaObject) => {\r\n\t\t\tif (!metaObject) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tvar include = true;\r\n\t\t\tif (excludeMask && excludeMask[metaObject.type]) {\r\n\t\t\t\tinclude = false;\r\n\t\t\t} else if (includeMask && !includeMask[metaObject.type]) {\r\n\t\t\t\tinclude = false;\r\n\t\t\t}\r\n\t\t\tif (include) {\r\n\t\t\t\tlist.push(metaObject.id);\r\n\t\t\t}\r\n\t\t\tconst children = metaObject.children;\r\n\t\t\tif (children) {\r\n\t\t\t\tfor (var i = 0, len = children.length; i < len; i++) {\r\n\t\t\t\t\tvisit(children[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tvisit(metaObject);\r\n\t\treturn list;\r\n\t}\r\n\r\n\t/**\r\n\t * Iterates over the {@link MetaObject}s within the subtree.\r\n\t *\r\n\t * @param {String} id ID of root {@link MetaObject}.\r\n\t * @param {Function} callback Callback fired at each {@link MetaObject}.\r\n\t */\r\n\twithMetaObjectsInSubtree(id, callback) {\r\n\t\tconst metaObject = this.metaObjects[id];\r\n\t\tif (!metaObject) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tmetaObject.withMetaObjectsInSubtree(callback);\r\n\t}\r\n}\r\n\r\nfunction arrayToMap(array) {\r\n\tconst map = {};\r\n\tfor (var i = 0, len = array.length; i < len; i++) {\r\n\t\tmap[array[i]] = true;\r\n\t}\r\n\treturn map;\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/metadata/MetaScene.js?");
2437
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ MetaScene: () => (/* binding */ MetaScene)\n/* harmony export */ });\n/* harmony import */ var _MetaModel_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./MetaModel.js */ \"./src/viewer/metadata/MetaModel.js\");\n/* harmony import */ var _MetaObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./MetaObject.js */ \"./src/viewer/metadata/MetaObject.js\");\n/* harmony import */ var _PropertySet_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./PropertySet.js */ \"./src/viewer/metadata/PropertySet.js\");\n/* harmony import */ var _scene_math_math_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../scene/math/math.js */ \"./src/viewer/scene/math/math.js\");\n\r\n\r\n\r\n\r\n\r\n/**\r\n * @desc Metadata corresponding to a {@link Scene}.\r\n *\r\n * * Located in {@link Viewer#metaScene}.\r\n * * Contains {@link MetaModel}s and {@link MetaObject}s.\r\n * * [Scene graph example with metadata](http://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneGraph_metadata)\r\n */\r\nclass MetaScene {\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tconstructor(viewer, scene) {\r\n\t\t/**\r\n\t\t * The {@link Viewer}.\r\n\t\t * @property viewer\r\n\t\t * @type {Viewer}\r\n\t\t */\r\n\t\tthis.viewer = viewer;\r\n\r\n\t\t/**\r\n\t\t * The {@link Scene}.\r\n\t\t * @property scene\r\n\t\t * @type {Scene}\r\n\t\t */\r\n\t\tthis.scene = scene;\r\n\r\n\t\t/**\r\n\t\t * The {@link MetaModel}s belonging to this MetaScene, each mapped to its {@link MetaModel#modelId}.\r\n\t\t *\r\n\t\t * @type {{String:MetaModel}}\r\n\t\t */\r\n\t\tthis.metaModels = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link PropertySet}s belonging to this MetaScene, each mapped to its {@link PropertySet#id}.\r\n\t\t *\r\n\t\t * @type {{String:PropertySet}}\r\n\t\t */\r\n\t\tthis.propertySets = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link MetaObject}s belonging to this MetaScene, each mapped to its {@link MetaObject#id}.\r\n\t\t *\r\n\t\t * @type {{String:MetaObject}}\r\n\t\t */\r\n\t\tthis.metaObjects = {};\r\n\r\n\t\t/**\r\n\t\t * The {@link MetaObject}s belonging to this MetaScene, each mapped to its {@link MetaObject#type}.\r\n\t\t *\r\n\t\t * @type {{String:MetaObject}}\r\n\t\t */\r\n\t\tthis.metaObjectsByType = {};\r\n\r\n\t\t/**\r\n\t\t * The root {@link MetaObject}s belonging to this MetaScene, each mapped to its {@link MetaObject#id}.\r\n\t\t *\r\n\t\t * @type {{String:MetaObject}}\r\n\t\t */\r\n\t\tthis.rootMetaObjects = {};\r\n\r\n\t\t/**\r\n\t\t * Subscriptions to events sent with {@link fire}.\r\n\t\t * @private\r\n\t\t */\r\n\t\tthis._eventSubs = {};\r\n\t}\r\n\r\n\t/**\r\n\t * Subscribes to an event fired at this Viewer.\r\n\t *\r\n\t * @param {String} event The event\r\n\t * @param {Function} callback Callback fired on the event\r\n\t */\r\n\ton(event, callback) {\r\n\t\tlet subs = this._eventSubs[event];\r\n\t\tif (!subs) {\r\n\t\t\tsubs = [];\r\n\t\t\tthis._eventSubs[event] = subs;\r\n\t\t}\r\n\t\tsubs.push(callback);\r\n\t}\r\n\r\n\t/**\r\n\t * Fires an event at this Viewer.\r\n\t *\r\n\t * @param {String} event Event name\r\n\t * @param {Object} value Event parameters\r\n\t */\r\n\tfire(event, value) {\r\n\t\tconst subs = this._eventSubs[event];\r\n\t\tif (subs) {\r\n\t\t\tfor (let i = 0, len = subs.length; i < len; i++) {\r\n\t\t\t\tsubs[i](value);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Unsubscribes from an event fired at this Viewer.\r\n\t * @param event\r\n\t */\r\n\toff(event) {\r\n\t\t// TODO\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a {@link MetaModel} in this MetaScene.\r\n\t *\r\n\t * The MetaModel will contain a hierarchy of {@link MetaObject}s, created from the\r\n\t * meta objects in ````metaModelData````.\r\n\t *\r\n\t * The meta object hierarchy in ````metaModelData```` is expected to be non-cyclic, with a single root. If the meta\r\n\t * objects are cyclic, then this method will log an error and attempt to recover by creating a dummy root MetaObject\r\n\t * of type \"Model\" and connecting all other MetaObjects as its direct children. If the meta objects contain multiple\r\n\t * roots, then this method similarly attempts to recover by creating a dummy root MetaObject of type \"Model\" and\r\n\t * connecting all the root MetaObjects as its children.\r\n\t *\r\n\t * @param {String} modelId ID for the new {@link MetaModel}, which will have {@link MetaModel#id} set to this value.\r\n\t * @param {Object} metaModelData Data for the {@link MetaModel}.\r\n\t * @param {Object} [options] Options for creating the {@link MetaModel}.\r\n\t * @param {Object} [options.includeTypes] When provided, only create {@link MetaObject}s with types in this list.\r\n\t * @param {Object} [options.excludeTypes] When provided, never create {@link MetaObject}s with types in this list.\r\n\t * @param {Boolean} [options.globalizeObjectIds=false] Whether to globalize each {@link MetaObject#id}. Set this ````true```` when you need to load multiple instances of the same meta model, to avoid ID clashes between the meta objects in the different instances.\r\n\t * @returns {MetaModel} The new MetaModel.\r\n\t */\r\n\tcreateMetaModel(modelId, metaModelData, options = {}) {\r\n\t\tconst metaModel = new _MetaModel_js__WEBPACK_IMPORTED_MODULE_0__.MetaModel({\r\n\t\t\t// Registers MetaModel in #metaModels\r\n\t\t\tmetaScene: this,\r\n\t\t\tid: modelId,\r\n\t\t\tprojectId: metaModelData.projectId || \"none\",\r\n\t\t\trevisionId: metaModelData.revisionId || \"none\",\r\n\t\t\tauthor: metaModelData.author || \"none\",\r\n\t\t\tcreatedAt: metaModelData.createdAt || \"none\",\r\n\t\t\tcreatingApplication: metaModelData.creatingApplication || \"none\",\r\n\t\t\tschema: metaModelData.schema || \"none\",\r\n\t\t\tpropertySets: []\r\n\t\t});\r\n\r\n\t\tmetaModel.loadData(metaModelData);\r\n\t\tmetaModel.finalize();\r\n\r\n\t\treturn metaModel;\r\n\t}\r\n\r\n\t/**\r\n\t * Removes a {@link MetaModel} from this MetaScene.\r\n\t *\r\n\t * Fires a \"metaModelDestroyed\" event with the value of the {@link MetaModel#id}.\r\n\t *\r\n\t * @param {String} metaModelId ID of the target {@link MetaModel}.\r\n\t */\r\n\tdestroyMetaModel(metaModelId) {\r\n\t\tconst metaModel = this.metaModels[metaModelId];\r\n\t\tif (!metaModel) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Remove global PropertySets\r\n\r\n\t\tif (metaModel.propertySets) {\r\n\t\t\tfor (let i = 0, len = metaModel.propertySets.length; i < len; i++) {\r\n\t\t\t\tconst propertySet = metaModel.propertySets[i];\r\n\t\t\t\tif (propertySet.metaModels.length === 1 && propertySet.metaModels[0].id === metaModelId) {\r\n\t\t\t\t\t// Property set owned only by this model, delete\r\n\t\t\t\t\tdelete this.propertySets[propertySet.id];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconst newMetaModels = [];\r\n\t\t\t\t\tfor (let j = 0, lenj = propertySet.metaModels.length; j < lenj; j++) {\r\n\t\t\t\t\t\tif (propertySet.metaModels[j].id !== metaModelId) {\r\n\t\t\t\t\t\t\tnewMetaModels.push(propertySet.metaModels[j]);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tpropertySet.metaModels = newMetaModels;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Remove MetaObjects\r\n\r\n\t\tif (metaModel.metaObjects) {\r\n\t\t\tfor (let i = 0, len = metaModel.metaObjects.length; i < len; i++) {\r\n\t\t\t\tconst metaObject = metaModel.metaObjects[i];\r\n\t\t\t\tconst type = metaObject.type;\r\n\t\t\t\tconst id = metaObject.id;\r\n\t\t\t\tif (metaObject.metaModels.length === 1 && metaObject.metaModels[0].id === metaModelId) {\r\n\t\t\t\t\t// MetaObject owned only by this model, delete\r\n\t\t\t\t\tdelete this.metaObjects[id];\r\n\t\t\t\t\tif (!metaObject.parent) {\r\n\t\t\t\t\t\tdelete this.rootMetaObjects[id];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Re-link entire MetaObject parent/child hierarchy\r\n\r\n\t\tfor (let objectId in this.metaObjects) {\r\n\t\t\tconst metaObject = this.metaObjects[objectId];\r\n\t\t\tif (metaObject.children) {\r\n\t\t\t\tmetaObject.children = [];\r\n\t\t\t}\r\n\r\n\t\t\t// Re-link each MetaObject's property sets\r\n\r\n\t\t\tif (metaObject.propertySets) {\r\n\t\t\t\tmetaObject.propertySets = [];\r\n\t\t\t}\r\n\t\t\tif (metaObject.propertySetIds) {\r\n\t\t\t\tfor (let i = 0, len = metaObject.propertySetIds.length; i < len; i++) {\r\n\t\t\t\t\tconst propertySetId = metaObject.propertySetIds[i];\r\n\t\t\t\t\tconst propertySet = this.propertySets[propertySetId];\r\n\t\t\t\t\tmetaObject.propertySets.push(propertySet);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.metaObjectsByType = {};\r\n\r\n\t\tfor (let objectId in this.metaObjects) {\r\n\t\t\tconst metaObject = this.metaObjects[objectId];\r\n\t\t\tconst type = metaObject.type;\r\n\t\t\tif (metaObject.children) {\r\n\t\t\t\tmetaObject.children = null;\r\n\t\t\t}\r\n\t\t\t(this.metaObjectsByType[type] || (this.metaObjectsByType[type] = {}))[objectId] = metaObject;\r\n\t\t}\r\n\r\n\t\tfor (let objectId in this.metaObjects) {\r\n\t\t\tconst metaObject = this.metaObjects[objectId];\r\n\t\t\tif (metaObject.parentId) {\r\n\t\t\t\tconst parentMetaObject = this.metaObjects[metaObject.parentId];\r\n\t\t\t\tif (parentMetaObject) {\r\n\t\t\t\t\tmetaObject.parent = parentMetaObject;\r\n\t\t\t\t\t(parentMetaObject.children || (parentMetaObject.children = [])).push(metaObject);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tdelete this.metaModels[metaModelId];\r\n\r\n\t\t// Relink MetaObjects to their MetaModels\r\n\r\n\t\t// for (let objectId in this.metaObjects) {\r\n\t\t// \tconst metaObject = this.metaObjects[objectId];\r\n\t\t// \tmetaObject.metaModels = [];\r\n\t\t// }\r\n\r\n\t\t// for (let modelId in this.metaModels) {\r\n\t\t// \tconst metaModel = this.metaModels[modelId];\r\n\t\t// \tfor (let i = 0, len = metaModel.metaObjects.length; i < len; i++) {\r\n\t\t// \t\tconst metaObject = metaModel.metaObjects[i];\r\n\t\t// \t\tmetaObject.metaModels.push(metaModel);\r\n\t\t// \t}\r\n\t\t// }\r\n\r\n\t\tthis.fire(\"metaModelDestroyed\", metaModelId);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the {@link MetaObject#id}s of the {@link MetaObject}s that have the given {@link MetaObject#type}.\r\n\t *\r\n\t * @param {String} type The type.\r\n\t * @returns {String[]} Array of {@link MetaObject#id}s.\r\n\t */\r\n\tgetObjectIDsByType(type) {\r\n\t\tconst metaObjects = this.metaObjectsByType[type];\r\n\t\treturn metaObjects ? Object.keys(metaObjects) : [];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the {@link MetaObject#id}s of the {@link MetaObject}s that have the given {@link MetaObject#types}.\r\n\t *\r\n\t * @param {String[]} types The array of type name.\r\n\t * @returns {String[]} Array of {@link MetaObject#id}s.\r\n\t */\r\n\tgetObjectIDsByTypes(types) {\r\n\t\tlet metaObjects = [];\r\n\t\tfor (let i = 0; i < types.length; i++) {\r\n\t\t\tlet type = types[i];\r\n\t\t\tmetaObjects = metaObjects.concat(this.getObjectIDsByType(type));\r\n\t\t}\r\n\t\treturn metaObjects;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the {@link MetaObject#id}s of the {@link MetaObject}s within the given subtree.\r\n\t *\r\n\t * @param {String} id ID of the root {@link MetaObject} of the given subtree.\r\n\t * @param {String[]} [includeTypes] Optional list of types to include.\r\n\t * @param {String[]} [excludeTypes] Optional list of types to exclude.\r\n\t * @returns {String[]} Array of {@link MetaObject#id}s.\r\n\t */\r\n\tgetObjectIDsInSubtree(id, includeTypes, excludeTypes) {\r\n\t\tconst list = [];\r\n\t\tconst metaObject = this.metaObjects[id];\r\n\t\tconst includeMask = includeTypes && includeTypes.length > 0 ? arrayToMap(includeTypes) : null;\r\n\t\tconst excludeMask = excludeTypes && excludeTypes.length > 0 ? arrayToMap(excludeTypes) : null;\r\n\r\n\t\tconst visit = (metaObject) => {\r\n\t\t\tif (!metaObject) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tvar include = true;\r\n\t\t\tif (excludeMask && excludeMask[metaObject.type]) {\r\n\t\t\t\tinclude = false;\r\n\t\t\t} else if (includeMask && !includeMask[metaObject.type]) {\r\n\t\t\t\tinclude = false;\r\n\t\t\t}\r\n\t\t\tif (include) {\r\n\t\t\t\tlist.push(metaObject.id);\r\n\t\t\t}\r\n\t\t\tconst children = metaObject.children;\r\n\t\t\tif (children) {\r\n\t\t\t\tfor (var i = 0, len = children.length; i < len; i++) {\r\n\t\t\t\t\tvisit(children[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tvisit(metaObject);\r\n\t\treturn list;\r\n\t}\r\n\r\n\t/**\r\n\t * Iterates over the {@link MetaObject}s within the subtree.\r\n\t *\r\n\t * @param {String} id ID of root {@link MetaObject}.\r\n\t * @param {Function} callback Callback fired at each {@link MetaObject}.\r\n\t */\r\n\twithMetaObjectsInSubtree(id, callback) {\r\n\t\tconst metaObject = this.metaObjects[id];\r\n\t\tif (!metaObject) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tmetaObject.withMetaObjectsInSubtree(callback);\r\n\t}\r\n}\r\n\r\nfunction arrayToMap(array) {\r\n\tconst map = {};\r\n\tfor (var i = 0, len = array.length; i < len; i++) {\r\n\t\tmap[array[i]] = true;\r\n\t}\r\n\treturn map;\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/metadata/MetaScene.js?");
2428
2438
 
2429
2439
  /***/ }),
2430
2440
 
@@ -2474,7 +2484,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2474
2484
  \*********************************************************/
2475
2485
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2476
2486
 
2477
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CameraControl: () => (/* binding */ CameraControl)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _camera_CameraFlightAnimation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./../camera/CameraFlightAnimation.js */ \"./src/viewer/scene/camera/CameraFlightAnimation.js\");\n/* harmony import */ var _lib_controllers_PanController_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lib/controllers/PanController.js */ \"./src/viewer/scene/CameraControl/lib/controllers/PanController.js\");\n/* harmony import */ var _lib_controllers_PivotController_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lib/controllers/PivotController.js */ \"./src/viewer/scene/CameraControl/lib/controllers/PivotController.js\");\n/* harmony import */ var _lib_controllers_PickController_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./lib/controllers/PickController.js */ \"./src/viewer/scene/CameraControl/lib/controllers/PickController.js\");\n/* harmony import */ var _lib_handlers_MousePanRotateDollyHandler_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./lib/handlers/MousePanRotateDollyHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/MousePanRotateDollyHandler.js\");\n/* harmony import */ var _lib_handlers_KeyboardAxisViewHandler_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./lib/handlers/KeyboardAxisViewHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/KeyboardAxisViewHandler.js\");\n/* harmony import */ var _lib_handlers_MousePickHandler_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./lib/handlers/MousePickHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/MousePickHandler.js\");\n/* harmony import */ var _lib_handlers_KeyboardPanRotateDollyHandler_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./lib/handlers/KeyboardPanRotateDollyHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/KeyboardPanRotateDollyHandler.js\");\n/* harmony import */ var _lib_CameraUpdater_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./lib/CameraUpdater.js */ \"./src/viewer/scene/CameraControl/lib/CameraUpdater.js\");\n/* harmony import */ var _lib_handlers_MouseMiscHandler_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./lib/handlers/MouseMiscHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/MouseMiscHandler.js\");\n/* harmony import */ var _lib_handlers_TouchPanRotateAndDollyHandler_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./lib/handlers/TouchPanRotateAndDollyHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _lib_handlers_TouchPickHandler_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./lib/handlers/TouchPickHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/TouchPickHandler.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst DEFAULT_SNAP_PICK_RADIUS = 20;\r\nconst DEFAULT_SNAP_VERTEX = true;\r\nconst DEFAULT_SNAP_EDGE = true;\r\n\r\n/**\r\n * @desc Controls the {@link Camera} with user input, and fires events when the user interacts with pickable {@link Entity}s.\r\n *\r\n * # Contents\r\n *\r\n * * [Overview](#overview)\r\n * * [Examples](#examples)\r\n * * [Orbit Mode](#orbit-mode)\r\n * + [Following the Pointer in Orbit Mode](#--following-the-pointer-in-orbit-mode--)\r\n * + [Showing the Pivot Position](#--showing-the-pivot-position--)\r\n * + [Axis-Aligned Views in Orbit Mode](#--axis-aligned-views-in-orbit-mode--)\r\n * + [View-Fitting Entitys in Orbit Mode](#--view-fitting-entitys-in-orbit-mode--)\r\n * * [First-Person Mode](#first-person-mode)\r\n * + [Following the Pointer in First-Person Mode](#--following-the-pointer-in-first-person-mode--)\r\n * + [Constraining Vertical Position in First-Person Mode](#--constraining-vertical-position-in-first-person-mode--)\r\n * + [Axis-Aligned Views in First-Person Mode](#--axis-aligned-views-in-first-person-mode--)\r\n * + [View-Fitting Entitys in First-Person Mode](#--view-fitting-entitys-in-first-person-mode--)\r\n * * [Plan-View Mode](#plan-view-mode)\r\n * + [Following the Pointer in Plan-View Mode](#--following-the-pointer-in-plan-view-mode--)\r\n * + [Axis-Aligned Views in Plan-View Mode](#--axis-aligned-views-in-plan-view-mode--)\r\n * * [CameraControl Events](#cameracontrol-events)\r\n * + [\"hover\"](#---hover---)\r\n * + [\"hoverOff\"](#---hoveroff---)\r\n * + [\"hoverEnter\"](#---hoverenter---)\r\n * + [\"hoverOut\"](#---hoverout---)\r\n * + [\"picked\"](#---picked---)\r\n * + [\"pickedSurface\"](#---pickedsurface---)\r\n * + [\"pickedNothing\"](#---pickednothing---)\r\n * + [\"doublePicked\"](#---doublepicked---)\r\n * + [\"doublePickedSurface\"](#---doublepickedsurface---)\r\n * + [\"doublePickedNothing\"](#---doublepickednothing---)\r\n * + [\"rightClick\"](#---rightclick---)\r\n * * [Custom Keyboard Mappings](#custom-keyboard-mappings)\r\n *\r\n * <br><br>\r\n *\r\n * # Overview\r\n *\r\n * * Each {@link Viewer} has a ````CameraControl````, located at {@link Viewer#cameraControl}.\r\n * * {@link CameraControl#navMode} selects the navigation mode:\r\n * * ````\"orbit\"```` rotates the {@link Camera} position about the target.\r\n * * ````\"firstPerson\"```` rotates the World about the Camera position.\r\n * * ````\"planView\"```` never rotates, but still allows to pan and dolly, typically for an axis-aligned view.\r\n * * {@link CameraControl#followPointer} makes the Camera follow the mouse or touch pointer.\r\n * * {@link CameraControl#constrainVertical} locks the Camera to its current height when in first-person mode.\r\n * * ````CameraControl```` fires pick events when we hover, click or tap on an {@link Entity}.\r\n * <br><br>\r\n *\r\n * # Examples\r\n *\r\n * * [Orbit Navigation - Duplex Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_orbit_Duplex)\r\n * * [Orbit Navigation - Holter Tower Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_orbit_HolterTower)\r\n * * [First-Person Navigation - Duplex Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_firstPerson_Duplex)\r\n * * [First-Person Navigation - Holter Tower Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_firstPerson_HolterTower)\r\n * * [Plan-view Navigation - Schependomlaan Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_planView_Schependomlaan)\r\n * * [Custom Keyboard Mapping](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_keyMap)\r\n * <br><br>\r\n *\r\n * # Orbit Mode\r\n *\r\n * In orbit mode, ````CameraControl```` orbits the {@link Camera} about the target.\r\n *\r\n * To enable orbit mode:\r\n *\r\n * ````javascript\r\n * const cameraControl = myViewer.cameraControl;\r\n * cameraControl.navMode = \"orbit\";\r\n * ````\r\n *\r\n * Then orbit by:\r\n *\r\n * * left-dragging the mouse,\r\n * * tap-dragging the touch pad, and\r\n * * pressing arrow keys, or ````Q```` and ````E```` on a QWERTY keyboard, or ````A```` and ````E```` on an AZERTY keyboard.\r\n * <br><br>\r\n *\r\n * Dolly forwards and backwards by:\r\n *\r\n * * spinning the mouse wheel,\r\n * * pinching on the touch pad, and\r\n * * pressing the ````+```` and ````-```` keys, or ````W```` and ````S```` on a QWERTY keyboard, or ````Z```` and ````S```` for AZERTY.\r\n * <br><br>\r\n *\r\n * Pan horizontally and vertically by:\r\n *\r\n * * right-dragging the mouse,\r\n * * left-dragging the mouse with the SHIFT key down,\r\n * * tap-dragging the touch pad with SHIFT down,\r\n * * pressing the ````A````, ````D````, ````Z```` and ````X```` keys on a QWERTY keyboard, and\r\n * * pressing the ````Q````, ````D````, ````W```` and ````X```` keys on an AZERTY keyboard,\r\n * <br><br>\r\n *\r\n * ## Following the Pointer in Orbit Mode\r\n *\r\n * When {@link CameraControl#followPointer} is ````true````in orbiting mode, the mouse or touch pointer will dynamically\r\n * indicate the target that the {@link Camera} will orbit, as well as dolly to and from.\r\n *\r\n * Lets ensure that we're in orbit mode, then enable the {@link Camera} to follow the pointer:\r\n *\r\n * ````javascript\r\n * cameraControl.navMode = \"orbit\";\r\n * cameraControl.followPointer = true;\r\n * ````\r\n *\r\n * ## Smart Pivoting\r\n *\r\n * TODO\r\n *\r\n * ## Showing the Pivot Position\r\n *\r\n * We can configure {@link CameraControl#pivotElement} with an HTML element to indicate the current\r\n * pivot position. The indicator will appear momentarily each time we move the {@link Camera} while in orbit mode with\r\n * {@link CameraControl#followPointer} set ````true````.\r\n *\r\n * First we'll define some CSS to style our pivot indicator as a black dot with a white border:\r\n *\r\n * ````css\r\n * .camera-pivot-marker {\r\n * color: #ffffff;\r\n * position: absolute;\r\n * width: 25px;\r\n * height: 25px;\r\n * border-radius: 15px;\r\n * border: 2px solid #ebebeb;\r\n * background: black;\r\n * visibility: hidden;\r\n * box-shadow: 5px 5px 15px 1px #000000;\r\n * z-index: 10000;\r\n * pointer-events: none;\r\n * }\r\n * ````\r\n *\r\n * Then we'll attach our pivot indicator's HTML element to the ````CameraControl````:\r\n *\r\n * ````javascript\r\n * const pivotElement = document.createRange().createContextualFragment(\"<div class='camera-pivot-marker'></div>\").firstChild;\r\n *\r\n * document.body.appendChild(pivotElement);\r\n *\r\n * cameraControl.pivotElement = pivotElement;\r\n * ````\r\n *\r\n * ## Axis-Aligned Views in Orbit Mode\r\n *\r\n * In orbit mode, we can use keys 1-6 to position the {@link Camera} to look at the center of the {@link Scene} from along each of the\r\n * six World-space axis. Pressing one of these keys will fly the {@link Camera} to the corresponding axis-aligned view.\r\n *\r\n * ## View-Fitting Entitys in Orbit Mode\r\n *\r\n * When {@link CameraControl#doublePickFlyTo} is ````true````, we can left-double-click or\r\n * double-tap (ie. \"double-pick\") an {@link Entity} to fit it to view. This will cause the {@link Camera}\r\n * to fly to that Entity. Our target then becomes the center of that Entity. If we are currently pivoting,\r\n * then our pivot position is then also set to the Entity center.\r\n *\r\n * Disable that behaviour by setting {@link CameraControl#doublePickFlyTo} ````false````.\r\n *\r\n * # First-Person Mode\r\n *\r\n * In first-person mode, ````CameraControl```` rotates the World about the {@link Camera} position.\r\n *\r\n * To enable first-person mode:\r\n *\r\n * ````javascript\r\n * cameraControl.navMode = \"firstPerson\";\r\n * ````\r\n *\r\n * Then rotate by:\r\n *\r\n * * left-dragging the mouse,\r\n * * tap-dragging the touch pad,\r\n * * pressing arrow keys, or ````Q```` and ````E```` on a QWERTY keyboard, or ````A```` and ````E```` on an AZERTY keyboard.\r\n * <br><br>\r\n *\r\n * Dolly forwards and backwards by:\r\n *\r\n * * spinning the mouse wheel,\r\n * * pinching on the touch pad, and\r\n * * pressing the ````+```` and ````-```` keys, or ````W```` and ````S```` on a QWERTY keyboard, or ````Z```` and ````S```` for AZERTY.\r\n * <br><br>\r\n *\r\n * Pan left, right, up and down by:\r\n *\r\n * * left-dragging or right-dragging the mouse, and\r\n * * tap-dragging the touch pad with SHIFT down.\r\n *\r\n * Pan forwards, backwards, left, right, up and down by pressing the ````WSADZX```` keys on a QWERTY keyboard,\r\n * or ````WSQDWX```` keys on an AZERTY keyboard.\r\n * <br><br>\r\n *\r\n * ## Following the Pointer in First-Person Mode\r\n *\r\n * When {@link CameraControl#followPointer} is ````true```` in first-person mode, the mouse or touch pointer will dynamically\r\n * indicate the target to which the {@link Camera} will dolly to and from. In first-person mode, however, the World will always rotate\r\n * about the {@link Camera} position.\r\n *\r\n * Lets ensure that we're in first-person mode, then enable the {@link Camera} to follow the pointer:\r\n *\r\n * ````javascript\r\n * cameraControl.navMode = \"firstPerson\";\r\n * cameraControl.followPointer = true;\r\n * ````\r\n *\r\n * When the pointer is over empty space, the target will remain the last object that the pointer was over.\r\n *\r\n * ## Constraining Vertical Position in First-Person Mode\r\n *\r\n * In first-person mode, we can lock the {@link Camera} to its current position on the vertical World axis, which is useful for walk-through navigation:\r\n *\r\n * ````javascript\r\n * cameraControl.constrainVertical = true;\r\n * ````\r\n *\r\n * ## Axis-Aligned Views in First-Person Mode\r\n *\r\n * In first-person mode we can use keys 1-6 to position the {@link Camera} to look at the center of\r\n * the {@link Scene} from along each of the six World-space axis. Pressing one of these keys will fly the {@link Camera} to the\r\n * corresponding axis-aligned view.\r\n *\r\n * ## View-Fitting Entitys in First-Person Mode\r\n *\r\n * As in orbit mode, when in first-person mode and {@link CameraControl#doublePickFlyTo} is ````true````, we can double-click\r\n * or double-tap an {@link Entity} (ie. \"double-picking\") to fit it in view. This will cause the {@link Camera} to fly to\r\n * that Entity. Our target then becomes the center of that Entity.\r\n *\r\n * Disable that behaviour by setting {@link CameraControl#doublePickFlyTo} ````false````.\r\n *\r\n * # Plan-View Mode\r\n *\r\n * In plan-view mode, ````CameraControl```` pans and rotates the {@link Camera}, without rotating it.\r\n *\r\n * To enable plan-view mode:\r\n *\r\n * ````javascript\r\n * cameraControl.navMode = \"planView\";\r\n * ````\r\n *\r\n * Dolly forwards and backwards by:\r\n *\r\n * * spinning the mouse wheel,\r\n * * pinching on the touch pad, and\r\n * * pressing the ````+```` and ````-```` keys.\r\n *\r\n * <br>\r\n * Pan left, right, up and down by:\r\n *\r\n * * left-dragging or right-dragging the mouse, and\r\n * * tap-dragging the touch pad with SHIFT down.\r\n *\r\n * Pan forwards, backwards, left, right, up and down by pressing the ````WSADZX```` keys on a QWERTY keyboard,\r\n * or ````WSQDWX```` keys on an AZERTY keyboard.\r\n * <br><br>\r\n *\r\n * ## Following the Pointer in Plan-View Mode\r\n *\r\n * When {@link CameraControl#followPointer} is ````true```` in plan-view mode, the mouse or touch pointer will dynamically\r\n * indicate the target to which the {@link Camera} will dolly to and from. In plan-view mode, however, the {@link Camera} cannot rotate.\r\n *\r\n * Lets ensure that we're in plan-view mode, then enable the {@link Camera} to follow the pointer:\r\n *\r\n * ````javascript\r\n * cameraControl.navMode = \"planView\";\r\n * cameraControl.followPointer = true; // Default\r\n * ````\r\n *\r\n * When the pointer is over empty space, the target will remain the last object that the pointer was over.\r\n *\r\n * ## Axis-Aligned Views in Plan-View Mode\r\n *\r\n * As in orbit and first-person modes, in plan-view mode we can use keys 1-6 to position the {@link Camera} to look at the center of\r\n * the {@link Scene} from along each of the six World-space axis. Pressing one of these keys will fly the {@link Camera} to the\r\n * corresponding axis-aligned view.\r\n *\r\n * # CameraControl Events\r\n *\r\n * ````CameraControl```` fires events as we interact with {@link Entity}s using mouse or touch input.\r\n *\r\n * The following examples demonstrate how to subscribe to those events.\r\n *\r\n * The first example shows how to save a handle to a subscription, which we can later use to unsubscribe.\r\n *\r\n * ## \"hover\"\r\n *\r\n * Event fired when the pointer moves while hovering over an Entity.\r\n *\r\n * ````javascript\r\n * const onHover = cameraControl.on(\"hover\", (e) => {\r\n * const entity = e.entity; // Entity\r\n * const canvasPos = e.canvasPos; // 2D canvas position\r\n * });\r\n * ````\r\n *\r\n * To unsubscribe from the event:\r\n *\r\n * ````javascript\r\n * cameraControl.off(onHover);\r\n * ````\r\n *\r\n * ## \"hoverOff\"\r\n *\r\n * Event fired when the pointer moves while hovering over empty space.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"hoverOff\", (e) => {\r\n * const canvasPos = e.canvasPos;\r\n * });\r\n * ````\r\n *\r\n * ## \"hoverEnter\"\r\n *\r\n * Event fired when the pointer moves onto an Entity.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"hoverEnter\", (e) => {\r\n * const entity = e.entity;\r\n * const canvasPos = e.canvasPos;\r\n * });\r\n * ````\r\n *\r\n * ## \"hoverOut\"\r\n *\r\n * Event fired when the pointer moves off an Entity.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"hoverOut\", (e) => {\r\n * const entity = e.entity;\r\n * const canvasPos = e.canvasPos;\r\n * });\r\n * ````\r\n *\r\n * ## \"picked\"\r\n *\r\n * Event fired when we left-click or tap on an Entity.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"picked\", (e) => {\r\n * const entity = e.entity;\r\n * const canvasPos = e.canvasPos;\r\n * });\r\n * ````\r\n *\r\n * ## \"pickedSurface\"\r\n *\r\n * Event fired when we left-click or tap on the surface of an Entity.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"picked\", (e) => {\r\n * const entity = e.entity;\r\n * const canvasPos = e.canvasPos;\r\n * const worldPos = e.worldPos; // 3D World-space position\r\n * const viewPos = e.viewPos; // 3D View-space position\r\n * const worldNormal = e.worldNormal; // 3D World-space normal vector\r\n * });\r\n * ````\r\n *\r\n * ## \"pickedNothing\"\r\n *\r\n * Event fired when we left-click or tap on empty space.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"pickedNothing\", (e) => {\r\n * const canvasPos = e.canvasPos;\r\n * });\r\n * ````\r\n *\r\n * ## \"doublePicked\"\r\n *\r\n * Event fired wwhen we left-double-click or double-tap on an Entity.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"doublePicked\", (e) => {\r\n * const entity = e.entity;\r\n * const canvasPos = e.canvasPos;\r\n * });\r\n * ````\r\n *\r\n * ## \"doublePickedSurface\"\r\n *\r\n * Event fired when we left-double-click or double-tap on the surface of an Entity.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"doublePickedSurface\", (e) => {\r\n * const entity = e.entity;\r\n * const canvasPos = e.canvasPos;\r\n * const worldPos = e.worldPos;\r\n * const viewPos = e.viewPos;\r\n * const worldNormal = e.worldNormal;\r\n * });\r\n * ````\r\n *\r\n * ## \"doublePickedNothing\"\r\n *\r\n * Event fired when we left-double-click or double-tap on empty space.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"doublePickedNothing\", (e) => {\r\n * const canvasPos = e.canvasPos;\r\n * });\r\n * ````\r\n *\r\n * ## \"rightClick\"\r\n *\r\n * Event fired when we right-click on the canvas.\r\n *\r\n * ````javascript\r\n * cameraControl.on(\"rightClick\", (e) => {\r\n * const event = e.event; // Mouse event\r\n * const canvasPos = e.canvasPos;\r\n * });\r\n * ````\r\n *\r\n * ## Custom Keyboard Mappings\r\n *\r\n * We can customize````CameraControl```` key bindings as shown below.\r\n *\r\n * In this example, we'll just set the default bindings for a QWERTY keyboard.\r\n *\r\n * ````javascript\r\n * const input = myViewer.scene.input;\r\n *\r\n * cameraControl.navMode = \"orbit\";\r\n * cameraControl.followPointer = true;\r\n *\r\n * const keyMap = {};\r\n *\r\n * keyMap[cameraControl.PAN_LEFT] = [input.KEY_A];\r\n * keyMap[cameraControl.PAN_RIGHT] = [input.KEY_D];\r\n * keyMap[cameraControl.PAN_UP] = [input.KEY_Z];\r\n * keyMap[cameraControl.PAN_DOWN] = [input.KEY_X];\r\n * keyMap[cameraControl.DOLLY_FORWARDS] = [input.KEY_W, input.KEY_ADD];\r\n * keyMap[cameraControl.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\r\n * keyMap[cameraControl.ROTATE_X_POS] = [input.KEY_DOWN_ARROW];\r\n * keyMap[cameraControl.ROTATE_X_NEG] = [input.KEY_UP_ARROW];\r\n * keyMap[cameraControl.ROTATE_Y_POS] = [input.KEY_LEFT_ARROW];\r\n * keyMap[cameraControl.ROTATE_Y_NEG] = [input.KEY_RIGHT_ARROW];\r\n * keyMap[cameraControl.AXIS_VIEW_RIGHT] = [input.KEY_NUM_1];\r\n * keyMap[cameraControl.AXIS_VIEW_BACK] = [input.KEY_NUM_2];\r\n * keyMap[cameraControl.AXIS_VIEW_LEFT] = [input.KEY_NUM_3];\r\n * keyMap[cameraControl.AXIS_VIEW_FRONT] = [input.KEY_NUM_4];\r\n * keyMap[cameraControl.AXIS_VIEW_TOP] = [input.KEY_NUM_5];\r\n * keyMap[cameraControl.AXIS_VIEW_BOTTOM] = [input.KEY_NUM_6];\r\n *\r\n * cameraControl.keyMap = keyMap;\r\n * ````\r\n *\r\n * We can also just configure default bindings for a specified keyboard layout, like this:\r\n *\r\n * ````javascript\r\n * cameraControl.keyMap = \"qwerty\";\r\n * ````\r\n *\r\n * Then, ````CameraControl```` will internally set {@link CameraControl#keyMap} to the default key map for the QWERTY\r\n * layout (which is the same set of mappings we set in the previous example). In other words, if we subsequently\r\n * read {@link CameraControl#keyMap}, it will now be a key map, instead of the \"qwerty\" string value we set it to.\r\n *\r\n * Supported layouts are, so far:\r\n *\r\n * * ````\"qwerty\"````\r\n * * ````\"azerty\"````\r\n */\r\nclass CameraControl extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\r\n\t/**\r\n\t * @private\r\n\t * @constructor\r\n\t */\r\n\tconstructor(owner, cfg = {}) {\r\n\t\tsuper(owner, cfg);\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.PAN_LEFT = 0;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.PAN_RIGHT = 1;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.PAN_UP = 2;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.PAN_DOWN = 3;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.PAN_FORWARDS = 4;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.PAN_BACKWARDS = 5;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.ROTATE_X_POS = 6;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.ROTATE_X_NEG = 7;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.ROTATE_Y_POS = 8;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.ROTATE_Y_NEG = 9;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.DOLLY_FORWARDS = 10;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.DOLLY_BACKWARDS = 11;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.AXIS_VIEW_RIGHT = 12;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.AXIS_VIEW_BACK = 13;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.AXIS_VIEW_LEFT = 14;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.AXIS_VIEW_FRONT = 15;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.AXIS_VIEW_TOP = 16;\r\n\r\n\t\t/**\r\n\t\t * Identifies the XX action.\r\n\t\t * @final\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.AXIS_VIEW_BOTTOM = 17;\r\n\r\n\t\tthis._keyMap = {}; // Maps key codes to the above actions\r\n\r\n\t\tthis.scene.canvas.canvas.oncontextmenu = (e) => {\r\n\t\t\te.preventDefault();\r\n\t\t};\r\n\r\n\t\t// User-settable CameraControl configurations\r\n\r\n\t\tthis._configs = {\r\n\t\t\t// Private\r\n\r\n\t\t\tlongTapTimeout: 600, // Millisecs\r\n\t\t\tlongTapRadius: 5, // Pixels\r\n\r\n\t\t\t// General\r\n\r\n\t\t\tactive: true,\r\n\t\t\tkeyboardLayout: \"qwerty\",\r\n\t\t\tnavMode: \"orbit\",\r\n\t\t\tplanView: false,\r\n\t\t\tfirstPerson: false,\r\n\t\t\tfollowPointer: true,\r\n\t\t\tdoublePickFlyTo: true,\r\n\t\t\tpanRightClick: true,\r\n\t\t\tshowPivot: false,\r\n\t\t\tpointerEnabled: true,\r\n\t\t\tconstrainVertical: false,\r\n\t\t\tsmartPivot: false,\r\n\t\t\tdoubleClickTimeFrame: 250,\r\n\r\n\t\t\tsnapToVertex: DEFAULT_SNAP_VERTEX,\r\n\t\t\tsnapToEdge: DEFAULT_SNAP_EDGE,\r\n\t\t\tsnapRadius: cfg.snapRadius ? cfg.snapRadius : DEFAULT_SNAP_PICK_RADIUS,\r\n\r\n\t\t\t// Rotation\r\n\r\n\t\t\tdragRotationRate: 360.0,\r\n\t\t\tkeyboardRotationRate: 90.0,\r\n\t\t\trotationInertia: 0.0,\r\n\r\n\t\t\t// Panning\r\n\r\n\t\t\tkeyboardPanRate: 1.0,\r\n\t\t\ttouchPanRate: 1.0,\r\n\t\t\tpanInertia: 0.5,\r\n\r\n\t\t\t// Dollying\r\n\r\n\t\t\tkeyboardDollyRate: 10,\r\n\t\t\tmouseWheelDollyRate: 100,\r\n\t\t\ttouchDollyRate: 0.2,\r\n\t\t\tdollyInertia: 0,\r\n\t\t\tdollyProximityThreshold: 30.0,\r\n\t\t\tdollyMinSpeed: 0.04\r\n\t\t};\r\n\r\n\t\t// Current runtime state of the CameraControl\r\n\r\n\t\tthis._states = {\r\n\t\t\tpointerCanvasPos: _math_math_js__WEBPACK_IMPORTED_MODULE_13__.math.vec2(),\r\n\t\t\tmouseover: false,\r\n\t\t\tfollowPointerDirty: true,\r\n\t\t\tmouseDownClientX: 0,\r\n\t\t\tmouseDownClientY: 0,\r\n\t\t\tmouseDownCursorX: 0,\r\n\t\t\tmouseDownCursorY: 0,\r\n\t\t\ttouchStartTime: null,\r\n\t\t\tactiveTouches: [],\r\n\t\t\ttapStartPos: _math_math_js__WEBPACK_IMPORTED_MODULE_13__.math.vec2(),\r\n\t\t\ttapStartTime: -1,\r\n\t\t\tlastTapTime: -1,\r\n\t\t\tlongTouchTimeout: null\r\n\t\t};\r\n\r\n\t\t// Updates for CameraUpdater to process on next Scene \"tick\" event\r\n\r\n\t\tthis._updates = {\r\n\t\t\trotateDeltaX: 0,\r\n\t\t\trotateDeltaY: 0,\r\n\t\t\tpanDeltaX: 0,\r\n\t\t\tpanDeltaY: 0,\r\n\t\t\tpanDeltaZ: 0,\r\n\t\t\tdollyDelta: 0\r\n\t\t};\r\n\r\n\t\t// Controllers to assist input event handlers with controlling the Camera\r\n\r\n\t\tconst scene = this.scene;\r\n\r\n\t\tthis._controllers = {\r\n\t\t\tcameraControl: this,\r\n\t\t\tpickController: new _lib_controllers_PickController_js__WEBPACK_IMPORTED_MODULE_4__.PickController(this, this._configs),\r\n\t\t\tpivotController: new _lib_controllers_PivotController_js__WEBPACK_IMPORTED_MODULE_3__.PivotController(scene, this._configs),\r\n\t\t\tpanController: new _lib_controllers_PanController_js__WEBPACK_IMPORTED_MODULE_2__.PanController(scene),\r\n\t\t\tcameraFlight: new _camera_CameraFlightAnimation_js__WEBPACK_IMPORTED_MODULE_1__.CameraFlightAnimation(this, {\r\n\t\t\t\tduration: 0.5\r\n\t\t\t})\r\n\t\t};\r\n\r\n\t\t// Input event handlers\r\n\r\n\t\tthis._handlers = [\r\n\t\t\tnew _lib_handlers_MouseMiscHandler_js__WEBPACK_IMPORTED_MODULE_10__.MouseMiscHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\r\n\t\t\tnew _lib_handlers_TouchPanRotateAndDollyHandler_js__WEBPACK_IMPORTED_MODULE_11__.TouchPanRotateAndDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\r\n\t\t\tnew _lib_handlers_MousePanRotateDollyHandler_js__WEBPACK_IMPORTED_MODULE_5__.MousePanRotateDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\r\n\t\t\tnew _lib_handlers_KeyboardAxisViewHandler_js__WEBPACK_IMPORTED_MODULE_6__.KeyboardAxisViewHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\r\n\t\t\tnew _lib_handlers_MousePickHandler_js__WEBPACK_IMPORTED_MODULE_7__.MousePickHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\r\n\t\t\tnew _lib_handlers_TouchPickHandler_js__WEBPACK_IMPORTED_MODULE_14__.TouchPickHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\r\n\t\t\tnew _lib_handlers_KeyboardPanRotateDollyHandler_js__WEBPACK_IMPORTED_MODULE_8__.KeyboardPanRotateDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates)\r\n\t\t];\r\n\r\n\t\t// Applies scheduled updates to the Camera on each Scene \"tick\" event\r\n\r\n\t\tthis._cameraUpdater = new _lib_CameraUpdater_js__WEBPACK_IMPORTED_MODULE_9__.CameraUpdater(this.scene, this._controllers, this._configs, this._states, this._updates);\r\n\r\n\t\t// Set initial user configurations\r\n\r\n\t\tthis.navMode = cfg.navMode;\r\n\t\tif (cfg.planView) {\r\n\t\t\tthis.planView = cfg.planView;\r\n\t\t}\r\n\t\tthis.constrainVertical = cfg.constrainVertical;\r\n\t\tif (cfg.keyboardLayout) {\r\n\t\t\tthis.keyboardLayout = cfg.keyboardLayout; // Deprecated\r\n\t\t} else {\r\n\t\t\tthis.keyMap = cfg.keyMap;\r\n\t\t}\r\n\t\tthis.doublePickFlyTo = cfg.doublePickFlyTo;\r\n\t\tthis.panRightClick = cfg.panRightClick;\r\n\t\tthis.active = cfg.active;\r\n\t\tthis.followPointer = cfg.followPointer;\r\n\t\tthis.rotationInertia = cfg.rotationInertia;\r\n\t\tthis.keyboardPanRate = cfg.keyboardPanRate;\r\n\t\tthis.touchPanRate = cfg.touchPanRate;\r\n\t\tthis.keyboardRotationRate = cfg.keyboardRotationRate;\r\n\t\tthis.dragRotationRate = cfg.dragRotationRate;\r\n\t\tthis.touchDollyRate = cfg.touchDollyRate;\r\n\t\tthis.dollyInertia = cfg.dollyInertia;\r\n\t\tthis.dollyProximityThreshold = cfg.dollyProximityThreshold;\r\n\t\tthis.dollyMinSpeed = cfg.dollyMinSpeed;\r\n\t\tthis.panInertia = cfg.panInertia;\r\n\t\tthis.pointerEnabled = true;\r\n\t\tthis.keyboardDollyRate = cfg.keyboardDollyRate;\r\n\t\tthis.mouseWheelDollyRate = cfg.mouseWheelDollyRate;\r\n\t\tthis._moveRate = 1;\r\n\t\tthis.scene.on(\"tick\", () => {\r\n\t\t\t// if (!(this._configs.active && this._configs.pointerEnabled)) return;\r\n\t\t\t// if (!this._states.mouseover) return;\r\n\t\t\tif (!(this._goLeft || this._goRight || this._goUp || this._goDown || this._goForward || this._goBackward)) {\r\n\t\t\t\t// this._inputDirectionCommand = false;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (this._goRight) {\r\n\t\t\t\tthis._updates.panDeltaX += -0.1 * this._moveRate;\r\n\t\t\t} else if (this._goLeft) {\r\n\t\t\t\tthis._updates.panDeltaX += 0.1 * this._moveRate;\r\n\t\t\t}\r\n\r\n\t\t\tif (this._goUp) {\r\n\t\t\t\tthis._updates.panDeltaY += 0.1 * this._moveRate;\r\n\t\t\t} else if (this._goDown) {\r\n\t\t\t\tthis._updates.panDeltaY += -0.1 * this._moveRate;\r\n\t\t\t}\r\n\r\n\t\t\tif (this._goForward) {\r\n\t\t\t\tthis._updates.panDeltaZ += -0.1 * this._moveRate;\r\n\t\t\t} else if (this._goBackward) {\r\n\t\t\t\tthis._updates.panDeltaZ += +0.1 * this._moveRate;\r\n\t\t\t}\r\n\t\t\tthis._inputDirectionCommand = true;\r\n\t\t});\r\n\t}\r\n\t/**\r\n\t * 停止漫游\r\n\t */\r\n\tsetdirectionChangeCancel() {\r\n\t\tthis._goLeft = false;\r\n\t\tthis._goRight = false;\r\n\t\tthis._goUp = false;\r\n\t\tthis._goDown = false;\r\n\t\tthis._goForward = false;\r\n\t\tthis._goBackward = false;\r\n\t}\r\n\r\n\t/**\r\n\t * 设置漫游移动速率\r\n\t * @param {number} rate\r\n\t */\r\n\tset moveRate(rate) {\r\n\t\tthis._moveRate = rate;\r\n\t}\r\n\r\n\t/**\r\n\t * 漫游向右\r\n\t * @param {boolean} go\r\n\t */\r\n\tset goRight(go) {\r\n\t\tthis._goRight = go;\r\n\t}\r\n\t/**\r\n\t * 漫游向左\r\n\t * @param {boolean} go\r\n\t */\r\n\tset goLeft(go) {\r\n\t\tthis._goLeft = go;\r\n\t}\r\n\t/**\r\n\t * 漫游向上\r\n\t * @param {boolean} go\r\n\t */\r\n\tset goUp(go) {\r\n\t\tthis._goUp = go;\r\n\t}\r\n\t/**\r\n\t * 漫游向下\r\n\t * @param {boolean} go\r\n\t */\r\n\tset goDown(go) {\r\n\t\tthis._goDown = go;\r\n\t}\r\n\t/**\r\n\t * 漫游向前\r\n\t * @param {boolean} go\r\n\t */\r\n\tset goForward(go) {\r\n\t\tthis._goForward = go;\r\n\t}\r\n\t/**\r\n\t * 漫游向后\r\n\t * @param {boolean} go\r\n\t */\r\n\tset goBackward(go) {\r\n\t\tthis._goBackward = go;\r\n\t}\r\n\r\n\tupdatePivotElement() {\r\n\t\tthis._controllers.pivotController.updatePivotElement();\r\n\t}\r\n\r\n\t/**\r\n\t * Sets custom mappings of keys to ````CameraControl```` actions.\r\n\t *\r\n\t * See class docs for usage.\r\n\t *\r\n\t * @param {{Number:Number}|String} value Either a set of new key mappings, or a string to select a keyboard layout,\r\n\t * which causes ````CameraControl```` to use the default key mappings for that layout.\r\n\t */\r\n\tset keyMap(value) {\r\n\t\tvalue = value || \"qwerty\";\r\n\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_12__.utils.isString(value)) {\r\n\t\t\tconst input = this.scene.input;\r\n\t\t\tconst keyMap = {};\r\n\r\n\t\t\tswitch (value) {\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tthis.error(\"Unsupported value for 'keyMap': \" + value + \" defaulting to 'qwerty'\");\r\n\t\t\t\t// Intentional fall-through to \"qwerty\"\r\n\t\t\t\tcase \"qwerty\":\r\n\t\t\t\t\tkeyMap[this.PAN_LEFT] = [input.KEY_A];\r\n\t\t\t\t\tkeyMap[this.PAN_RIGHT] = [input.KEY_D];\r\n\t\t\t\t\tkeyMap[this.PAN_UP] = [input.KEY_Z];\r\n\t\t\t\t\tkeyMap[this.PAN_DOWN] = [input.KEY_X];\r\n\t\t\t\t\tkeyMap[this.PAN_BACKWARDS] = [];\r\n\t\t\t\t\tkeyMap[this.PAN_FORWARDS] = [];\r\n\t\t\t\t\tkeyMap[this.DOLLY_FORWARDS] = [input.KEY_W, input.KEY_ADD];\r\n\t\t\t\t\tkeyMap[this.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\r\n\t\t\t\t\tkeyMap[this.ROTATE_X_POS] = [input.KEY_DOWN_ARROW];\r\n\t\t\t\t\tkeyMap[this.ROTATE_X_NEG] = [input.KEY_UP_ARROW];\r\n\t\t\t\t\tkeyMap[this.ROTATE_Y_POS] = [input.KEY_Q, input.KEY_LEFT_ARROW];\r\n\t\t\t\t\tkeyMap[this.ROTATE_Y_NEG] = [input.KEY_E, input.KEY_RIGHT_ARROW];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_RIGHT] = [input.KEY_NUM_1];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_BACK] = [input.KEY_NUM_2];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_LEFT] = [input.KEY_NUM_3];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_FRONT] = [input.KEY_NUM_4];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_TOP] = [input.KEY_NUM_5];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_BOTTOM] = [input.KEY_NUM_6];\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase \"azerty\":\r\n\t\t\t\t\tkeyMap[this.PAN_LEFT] = [input.KEY_Q];\r\n\t\t\t\t\tkeyMap[this.PAN_RIGHT] = [input.KEY_D];\r\n\t\t\t\t\tkeyMap[this.PAN_UP] = [input.KEY_W];\r\n\t\t\t\t\tkeyMap[this.PAN_DOWN] = [input.KEY_X];\r\n\t\t\t\t\tkeyMap[this.PAN_BACKWARDS] = [];\r\n\t\t\t\t\tkeyMap[this.PAN_FORWARDS] = [];\r\n\t\t\t\t\tkeyMap[this.DOLLY_FORWARDS] = [input.KEY_Z, input.KEY_ADD];\r\n\t\t\t\t\tkeyMap[this.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\r\n\t\t\t\t\tkeyMap[this.ROTATE_X_POS] = [input.KEY_DOWN_ARROW];\r\n\t\t\t\t\tkeyMap[this.ROTATE_X_NEG] = [input.KEY_UP_ARROW];\r\n\t\t\t\t\tkeyMap[this.ROTATE_Y_POS] = [input.KEY_A, input.KEY_LEFT_ARROW];\r\n\t\t\t\t\tkeyMap[this.ROTATE_Y_NEG] = [input.KEY_E, input.KEY_RIGHT_ARROW];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_RIGHT] = [input.KEY_NUM_1];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_BACK] = [input.KEY_NUM_2];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_LEFT] = [input.KEY_NUM_3];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_FRONT] = [input.KEY_NUM_4];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_TOP] = [input.KEY_NUM_5];\r\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_BOTTOM] = [input.KEY_NUM_6];\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tthis._keyMap = keyMap;\r\n\t\t} else {\r\n\t\t\tconst keyMap = value;\r\n\t\t\tthis._keyMap = keyMap;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets custom mappings of keys to {@link CameraControl} actions.\r\n\t *\r\n\t * @returns {{Number:Number}} Current key mappings.\r\n\t */\r\n\tget keyMap() {\r\n\t\treturn this._keyMap;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns true if any keys configured for the given action are down.\r\n\t * @param action\r\n\t * @param keyDownMap\r\n\t * @private\r\n\t */\r\n\t_isKeyDownForAction(action, keyDownMap) {\r\n\t\tconst keys = this._keyMap[action];\r\n\t\tif (!keys) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif (!keyDownMap) {\r\n\t\t\tkeyDownMap = this.scene.input.keyDown;\r\n\t\t}\r\n\t\tfor (let i = 0, len = keys.length; i < len; i++) {\r\n\t\t\tconst key = keys[i];\r\n\t\t\tif (keyDownMap[key]) {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the HTMl element to represent the pivot point when {@link CameraControl#followPointer} is true.\r\n\t *\r\n\t * See class comments for an example.\r\n\t *\r\n\t * @param {HTMLElement} element HTML element representing the pivot point.\r\n\t */\r\n\tset pivotElement(element) {\r\n\t\tthis._controllers.pivotController.setPivotElement(element);\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if this ````CameraControl```` is active or not.\r\n\t *\r\n\t * When inactive, the ````CameraControl```` will not react to input.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * @param {Boolean} value Set ````true```` to activate this ````CameraControl````.\r\n\t */\r\n\tset active(value) {\r\n\t\tvalue = value !== false;\r\n\t\tthis._configs.active = value;\r\n\t\tthis._handlers[1]._active = value;\r\n\t\tthis._handlers[5]._active = value;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if this ````CameraControl```` is active or not.\r\n\t *\r\n\t * When inactive, the ````CameraControl```` will not react to input.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` if this ````CameraControl```` is active.\r\n\t */\r\n\tget active() {\r\n\t\treturn this._configs.active;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the pointer snap to vertex.\r\n\t *\r\n\t * @param {boolean} snapToVertex\r\n\t */\r\n\tset snapToVertex(snapToVertex) {\r\n\t\tthis._configs.snapToVertex = !!snapToVertex;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the pointer snap to vertex.\r\n\t *\r\n\t * @returns {boolean}\r\n\t */\r\n\tget snapToVertex() {\r\n\t\treturn this._configs.snapToVertex;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the pointer snap to edge.\r\n\t *\r\n\t * @param {boolean} snapToEdge\r\n\t */\r\n\tset snapToEdge(snapToEdge) {\r\n\t\tthis._configs.snapToEdge = !!snapToEdge;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether the pointer snap to edge.\r\n\t *\r\n\t * @returns {boolean}\r\n\t */\r\n\tget snapToEdge() {\r\n\t\treturn this._configs.snapToEdge;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the current snap radius for \"hoverSnapOrSurface\" events, to specify whether the radius\r\n\t * within which the pointer snaps to the nearest vertex or the nearest edge.\r\n\t *\r\n\t * Default value is 30 pixels.\r\n\t *\r\n\t * @param {Number} snapRadius The snap radius.\r\n\t */\r\n\tset snapRadius(snapRadius) {\r\n\t\tsnapRadius = snapRadius || DEFAULT_SNAP_PICK_RADIUS;\r\n\t\tthis._configs.snapRadius = snapRadius;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current snap radius.\r\n\t *\r\n\t * @returns {Number} The snap radius.\r\n\t */\r\n\tget snapRadius() {\r\n\t\treturn this._configs.snapRadius;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the current navigation mode.\r\n\t *\r\n\t * Accepted values are:\r\n\t *\r\n\t * * \"orbit\" - rotation orbits about the current target or pivot point,\r\n\t * * \"firstPerson\" - rotation is about the current eye position,\r\n\t * * \"planView\" - rotation is disabled.\r\n\t *\r\n\t * See class comments for more info.\r\n\t *\r\n\t * @param {String} navMode The navigation mode: \"orbit\", \"firstPerson\" or \"planView\".\r\n\t */\r\n\tset navMode(navMode) {\r\n\t\tnavMode = navMode || \"orbit\";\r\n\t\tif (navMode !== \"firstPerson\" && navMode !== \"orbit\" && navMode !== \"planView\") {\r\n\t\t\tthis.error(\r\n\t\t\t\t\"Unsupported value for navMode: \" +\r\n\t\t\t\t\tnavMode +\r\n\t\t\t\t\t\" - supported values are 'orbit', 'firstPerson' and 'planView' - defaulting to 'orbit'\"\r\n\t\t\t);\r\n\t\t\tnavMode = \"orbit\";\r\n\t\t}\r\n\t\tthis._configs.firstPerson = navMode === \"firstPerson\";\r\n\t\tthis._configs.planView = navMode === \"planView\";\r\n\t\tif (this._configs.firstPerson || this._configs.planView) {\r\n\t\t\tthis._controllers.pivotController.hidePivot();\r\n\t\t\tthis._controllers.pivotController.endPivot();\r\n\t\t}\r\n\t\tthis._configs.navMode = navMode;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current navigation mode.\r\n\t *\r\n\t * @returns {String} The navigation mode: \"orbit\", \"firstPerson\" or \"planView\".\r\n\t */\r\n\tget navMode() {\r\n\t\treturn this._configs.navMode;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether mouse and touch input is enabled.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * Disabling mouse and touch input on ````CameraControl```` is useful when we want to temporarily use mouse or\r\n\t * touch input to interact with some other 3D control, without disturbing the {@link Camera}.\r\n\t *\r\n\t * @param {Boolean} value Set ````true```` to enable mouse and touch input.\r\n\t */\r\n\tset pointerEnabled(value) {\r\n\t\tthis._reset();\r\n\t\tthis._configs.pointerEnabled = !!value;\r\n\t}\r\n\r\n\t_reset() {\r\n\t\tfor (let i = 0, len = this._handlers.length; i < len; i++) {\r\n\t\t\tconst handler = this._handlers[i];\r\n\t\t\tif (handler.reset) {\r\n\t\t\t\thandler.reset();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis._updates.panDeltaX = 0;\r\n\t\tthis._updates.panDeltaY = 0;\r\n\t\tthis._updates.rotateDeltaX = 0;\r\n\t\tthis._updates.rotateDeltaY = 0;\r\n\t\tthis._updates.dolyDelta = 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether mouse and touch input is enabled.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * Disabling mouse and touch input on ````CameraControl```` is desirable when we want to temporarily use mouse or\r\n\t * touch input to interact with some other 3D control, without interfering with the {@link Camera}.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` if mouse and touch input is enabled.\r\n\t */\r\n\tget pointerEnabled() {\r\n\t\treturn this._configs.pointerEnabled;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the {@link Camera} follows the mouse/touch pointer.\r\n\t *\r\n\t * In orbiting mode, the Camera will orbit about the pointer, and will dolly to and from the pointer.\r\n\t *\r\n\t * In fly-to mode, the Camera will dolly to and from the pointer, however the World will always rotate about the Camera position.\r\n\t *\r\n\t * In plan-view mode, the Camera will dolly to and from the pointer, however the Camera will not rotate.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * See class comments for more info.\r\n\t *\r\n\t * @param {Boolean} value Set ````true```` to enable the Camera to follow the pointer.\r\n\t */\r\n\tset followPointer(value) {\r\n\t\tthis._configs.followPointer = value !== false;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether the {@link Camera} follows the mouse/touch pointer.\r\n\t *\r\n\t * In orbiting mode, the Camera will orbit about the pointer, and will dolly to and from the pointer.\r\n\t *\r\n\t * In fly-to mode, the Camera will dolly to and from the pointer, however the World will always rotate about the Camera position.\r\n\t *\r\n\t * In plan-view mode, the Camera will dolly to and from the pointer, however the Camera will not rotate.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * See class comments for more info.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` if the Camera follows the pointer.\r\n\t */\r\n\tget followPointer() {\r\n\t\treturn this._configs.followPointer;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the current World-space 3D target position.\r\n\t *\r\n\t * Only applies when {@link CameraControl#followPointer} is ````true````.\r\n\t *\r\n\t * @param {Number[]} worldPos The new World-space 3D target position.\r\n\t */\r\n\tset pivotPos(worldPos) {\r\n\t\tthis._controllers.pivotController.setPivotPos(worldPos);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current World-space 3D pivot position.\r\n\t *\r\n\t * Only applies when {@link CameraControl#followPointer} is ````true````.\r\n\t *\r\n\t * @return {Number[]} worldPos The current World-space 3D pivot position.\r\n\t */\r\n\tget pivotPos() {\r\n\t\treturn this._controllers.pivotController.getPivotPos();\r\n\t}\r\n\r\n\t/**\r\n\t * @deprecated\r\n\t * @param {Boolean} value Set ````true```` to enable dolly-to-pointer behaviour.\r\n\t */\r\n\tset dollyToPointer(value) {\r\n\t\tthis.warn(\"dollyToPointer property is deprecated - replaced with followPointer\");\r\n\t\tthis.followPointer = value;\r\n\t}\r\n\r\n\t/**\r\n\t * @deprecated\r\n\t * @returns {Boolean} Returns ````true```` if dolly-to-pointer behaviour is enabled.\r\n\t */\r\n\tget dollyToPointer() {\r\n\t\tthis.warn(\"dollyToPointer property is deprecated - replaced with followPointer\");\r\n\t\treturn this.followPointer;\r\n\t}\r\n\r\n\t/**\r\n\t * @deprecated\r\n\t * @param {Boolean} value Set ````true```` to enable dolly-to-pointer behaviour.\r\n\t */\r\n\tset panToPointer(value) {\r\n\t\tthis.warn(\"panToPointer property is deprecated - replaced with followPointer\");\r\n\t}\r\n\r\n\t/**\r\n\t * @deprecated\r\n\t * @returns {Boolean} Returns ````true```` if dolly-to-pointer behaviour is enabled.\r\n\t */\r\n\tget panToPointer() {\r\n\t\tthis.warn(\"panToPointer property is deprecated - replaced with followPointer\");\r\n\t\treturn false;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether this ````CameraControl```` is in plan-view mode.\r\n\t *\r\n\t * When in plan-view mode, rotation is disabled.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * Deprecated - use {@link CameraControl#navMode} instead.\r\n\t *\r\n\t * @param {Boolean} value Set ````true```` to enable plan-view mode.\r\n\t * @deprecated\r\n\t */\r\n\tset planView(value) {\r\n\t\tthis._configs.planView = !!value;\r\n\t\tthis._configs.firstPerson = false;\r\n\t\tif (this._configs.planView) {\r\n\t\t\tthis._controllers.pivotController.hidePivot();\r\n\t\t\tthis._controllers.pivotController.endPivot();\r\n\t\t}\r\n\t\tthis.warn(\"planView property is deprecated - replaced with navMode\");\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether this ````CameraControl```` is in plan-view mode.\r\n\t *\r\n\t * When in plan-view mode, rotation is disabled.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * Deprecated - use {@link CameraControl#navMode} instead.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` if plan-view mode is enabled.\r\n\t * @deprecated\r\n\t */\r\n\tget planView() {\r\n\t\tthis.warn(\"planView property is deprecated - replaced with navMode\");\r\n\t\treturn this._configs.planView;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether this ````CameraControl```` is in first-person mode.\r\n\t *\r\n\t * In \"first person\" mode (disabled by default) the look position rotates about the eye position. Otherwise, {@link Camera#eye} rotates about {@link Camera#look}.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * Deprecated - use {@link CameraControl#navMode} instead.\r\n\t *\r\n\t * @param {Boolean} value Set ````true```` to enable first-person mode.\r\n\t * @deprecated\r\n\t */\r\n\tset firstPerson(value) {\r\n\t\tthis.warn(\"firstPerson property is deprecated - replaced with navMode\");\r\n\t\tthis._configs.firstPerson = !!value;\r\n\t\tthis._configs.planView = false;\r\n\t\tif (this._configs.firstPerson) {\r\n\t\t\tthis._controllers.pivotController.hidePivot();\r\n\t\t\tthis._controllers.pivotController.endPivot();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether this ````CameraControl```` is in first-person mode.\r\n\t *\r\n\t * In \"first person\" mode (disabled by default) the look position rotates about the eye position. Otherwise, {@link Camera#eye} rotates about {@link Camera#look}.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * Deprecated - use {@link CameraControl#navMode} instead.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` if first-person mode is enabled.\r\n\t * @deprecated\r\n\t */\r\n\tget firstPerson() {\r\n\t\tthis.warn(\"firstPerson property is deprecated - replaced with navMode\");\r\n\t\treturn this._configs.firstPerson;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether to vertically constrain the {@link Camera} position for first-person navigation.\r\n\t *\r\n\t * When set ````true````, this constrains {@link Camera#eye} to its current vertical position.\r\n\t *\r\n\t * Only applies when {@link CameraControl#navMode} is ````\"firstPerson\"````.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * @param {Boolean} value Set ````true```` to vertically constrain the Camera.\r\n\t */\r\n\tset constrainVertical(value) {\r\n\t\tthis._configs.constrainVertical = !!value;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether to vertically constrain the {@link Camera} position for first-person navigation.\r\n\t *\r\n\t * When set ````true````, this constrains {@link Camera#eye} to its current vertical position.\r\n\t *\r\n\t * Only applies when {@link CameraControl#navMode} is ````\"firstPerson\"````.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * @returns {Boolean} ````true```` when Camera is vertically constrained.\r\n\t */\r\n\tget constrainVertical() {\r\n\t\treturn this._configs.constrainVertical;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether double-picking an {@link Entity} causes the {@link Camera} to fly to its boundary.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * @param {Boolean} value Set ````true```` to enable double-pick-fly-to mode.\r\n\t */\r\n\tset doublePickFlyTo(value) {\r\n\t\tthis._configs.doublePickFlyTo = value !== false;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether double-picking an {@link Entity} causes the {@link Camera} to fly to its boundary.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` when double-pick-fly-to mode is enabled.\r\n\t */\r\n\tget doublePickFlyTo() {\r\n\t\treturn this._configs.doublePickFlyTo;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether either right-clicking (true) or middle-clicking (false) pans the {@link Camera}.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * @param {Boolean} value Set ````false```` to disable pan on right-click.\r\n\t */\r\n\tset panRightClick(value) {\r\n\t\tthis._configs.panRightClick = value !== false;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether right-clicking pans the {@link Camera}.\r\n\t *\r\n\t * Default is ````true````.\r\n\t *\r\n\t * @returns {Boolean} Returns ````false```` when pan on right-click is disabled.\r\n\t */\r\n\tget panRightClick() {\r\n\t\treturn this._configs.panRightClick;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a factor in range ````[0..1]```` indicating how much the {@link Camera} keeps moving after you finish rotating it.\r\n\t *\r\n\t * A value of ````0.0```` causes it to immediately stop, ````0.5```` causes its movement to decay 50% on each tick,\r\n\t * while ````1.0```` causes no decay, allowing it continue moving, by the current rate of rotation.\r\n\t *\r\n\t * You may choose an inertia of zero when you want be able to precisely rotate the Camera,\r\n\t * without interference from inertia. Zero inertia can also mean that less frames are rendered while\r\n\t * you are rotating the Camera.\r\n\t *\r\n\t * Default is ````0.0````.\r\n\t *\r\n\t * Does not apply when {@link CameraControl#navMode} is ````\"planView\"````, which disallows rotation.\r\n\t *\r\n\t * @param {Number} rotationInertia New inertial factor.\r\n\t */\r\n\tset rotationInertia(rotationInertia) {\r\n\t\tthis._configs.rotationInertia = rotationInertia !== undefined && rotationInertia !== null ? rotationInertia : 0.0;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the rotation inertia factor.\r\n\t *\r\n\t * Default is ````0.0````.\r\n\t *\r\n\t * Does not apply when {@link CameraControl#navMode} is ````\"planView\"````, which disallows rotation.\r\n\t *\r\n\t * @returns {Number} The inertia factor.\r\n\t */\r\n\tget rotationInertia() {\r\n\t\treturn this._configs.rotationInertia;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets how much the {@link Camera} pans each second with keyboard input.\r\n\t *\r\n\t * Default is ````5.0````, to pan the Camera ````5.0```` World-space units every second that\r\n\t * a panning key is depressed. See the ````CameraControl```` class documentation for which keys control\r\n\t * panning.\r\n\t *\r\n\t * Panning direction is aligned to our Camera's orientation. When we pan horizontally, we pan\r\n\t * to our left and right, when we pan vertically, we pan upwards and downwards, and when we pan forwards\r\n\t * and backwards, we pan along the direction the Camera is pointing.\r\n\t *\r\n\t * Unlike dollying when {@link followPointer} is ````true````, panning does not follow the pointer.\r\n\t *\r\n\t * @param {Number} keyboardPanRate The new keyboard pan rate.\r\n\t */\r\n\tset keyboardPanRate(keyboardPanRate) {\r\n\t\tthis._configs.keyboardPanRate = keyboardPanRate !== null && keyboardPanRate !== undefined ? keyboardPanRate : 5.0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets how fast the camera pans on touch panning\r\n\t *\r\n\t * @param {Number} touchPanRate The new touch pan rate.\r\n\t */\r\n\tset touchPanRate(touchPanRate) {\r\n\t\tthis._configs.touchPanRate = touchPanRate !== null && touchPanRate !== undefined ? touchPanRate : 1.0;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets how fast the {@link Camera} pans on touch panning\r\n\t *\r\n\t * Default is ````1.0````.\r\n\t *\r\n\t * @returns {Number} The current touch pan rate.\r\n\t */\r\n\tget touchPanRate() {\r\n\t\treturn this._configs.touchPanRate;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets how much the {@link Camera} pans each second with keyboard input.\r\n\t *\r\n\t * Default is ````5.0````.\r\n\t *\r\n\t * @returns {Number} The current keyboard pan rate.\r\n\t */\r\n\tget keyboardPanRate() {\r\n\t\treturn this._configs.keyboardPanRate;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets how many degrees per second the {@link Camera} rotates/orbits with keyboard input.\r\n\t *\r\n\t * Default is ````90.0````, to rotate/orbit the Camera ````90.0```` degrees every second that\r\n\t * a rotation key is depressed. See the ````CameraControl```` class documentation for which keys control\r\n\t * rotation/orbit.\r\n\t *\r\n\t * @param {Number} keyboardRotationRate The new keyboard rotation rate.\r\n\t */\r\n\tset keyboardRotationRate(keyboardRotationRate) {\r\n\t\tthis._configs.keyboardRotationRate =\r\n\t\t\tkeyboardRotationRate !== null && keyboardRotationRate !== undefined ? keyboardRotationRate : 90.0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets how many degrees per second the {@link Camera} rotates/orbits with keyboard input.\r\n\t *\r\n\t * Default is ````90.0````.\r\n\t *\r\n\t * @returns {Number} The current keyboard rotation rate.\r\n\t */\r\n\tget keyboardRotationRate() {\r\n\t\treturn this._configs.keyboardRotationRate;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the current drag rotation rate.\r\n\t *\r\n\t * This configures how many degrees the {@link Camera} rotates/orbits for a full sweep of the canvas by mouse or touch dragging.\r\n\t *\r\n\t * For example, a value of ````360.0```` indicates that the ````Camera```` rotates/orbits ````360.0```` degrees horizontally\r\n\t * when we sweep the entire width of the canvas.\r\n\t *\r\n\t * ````CameraControl```` makes vertical rotation half as sensitive as horizontal rotation, so that we don't tend to\r\n\t * flip upside-down. Therefore, a value of ````360.0```` rotates/orbits the ````Camera```` through ````180.0```` degrees\r\n\t * vertically when we sweep the entire height of the canvas.\r\n\t *\r\n\t * Default is ````360.0````.\r\n\t *\r\n\t * @param {Number} dragRotationRate The new drag rotation rate.\r\n\t */\r\n\tset dragRotationRate(dragRotationRate) {\r\n\t\tthis._configs.dragRotationRate =\r\n\t\t\tdragRotationRate !== null && dragRotationRate !== undefined ? dragRotationRate : 360.0;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current drag rotation rate.\r\n\t *\r\n\t * Default is ````360.0````.\r\n\t *\r\n\t * @returns {Number} The current drag rotation rate.\r\n\t */\r\n\tget dragRotationRate() {\r\n\t\treturn this._configs.dragRotationRate;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets how much the {@link Camera} dollys each second with keyboard input.\r\n\t *\r\n\t * Default is ````15.0````, to dolly the {@link Camera} ````15.0```` World-space units per second while we hold down\r\n\t * the ````+```` and ````-```` keys.\r\n\t *\r\n\t * @param {Number} keyboardDollyRate The new keyboard dolly rate.\r\n\t */\r\n\tset keyboardDollyRate(keyboardDollyRate) {\r\n\t\tthis._configs.keyboardDollyRate =\r\n\t\t\tkeyboardDollyRate !== null && keyboardDollyRate !== undefined ? keyboardDollyRate : 15.0;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets how much the {@link Camera} dollys each second with keyboard input.\r\n\t *\r\n\t * Default is ````15.0````.\r\n\t *\r\n\t * @returns {Number} The current keyboard dolly rate.\r\n\t */\r\n\tget keyboardDollyRate() {\r\n\t\treturn this._configs.keyboardDollyRate;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets how much the {@link Camera} dollys with touch input.\r\n\t *\r\n\t * Default is ````0.2````\r\n\t *\r\n\t * @param {Number} touchDollyRate The new touch dolly rate.\r\n\t */\r\n\tset touchDollyRate(touchDollyRate) {\r\n\t\tthis._configs.touchDollyRate = touchDollyRate !== null && touchDollyRate !== undefined ? touchDollyRate : 0.2;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets how much the {@link Camera} dollys each second with touch input.\r\n\t *\r\n\t * Default is ````0.2````.\r\n\t *\r\n\t * @returns {Number} The current touch dolly rate.\r\n\t */\r\n\tget touchDollyRate() {\r\n\t\treturn this._configs.touchDollyRate;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets how much the {@link Camera} dollys each second while the mouse wheel is spinning.\r\n\t *\r\n\t * Default is ````100.0````, to dolly the {@link Camera} ````10.0```` World-space units per second as we spin\r\n\t * the mouse wheel.\r\n\t *\r\n\t * @param {Number} mouseWheelDollyRate The new mouse wheel dolly rate.\r\n\t */\r\n\tset mouseWheelDollyRate(mouseWheelDollyRate) {\r\n\t\tthis._configs.mouseWheelDollyRate =\r\n\t\t\tmouseWheelDollyRate !== null && mouseWheelDollyRate !== undefined ? mouseWheelDollyRate : 100.0;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets how much the {@link Camera} dollys each second while the mouse wheel is spinning.\r\n\t *\r\n\t * Default is ````100.0````.\r\n\t *\r\n\t * @returns {Number} The current mouseWheel dolly rate.\r\n\t */\r\n\tget mouseWheelDollyRate() {\r\n\t\treturn this._configs.mouseWheelDollyRate;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the dolly inertia factor.\r\n\t *\r\n\t * This factor configures how much the {@link Camera} keeps moving after you finish dollying it.\r\n\t *\r\n\t * This factor is a value in range ````[0..1]````. A value of ````0.0```` causes dollying to immediately stop,\r\n\t * ````0.5```` causes dollying to decay 50% on each animation frame, while ````1.0```` causes no decay, which allows dollying\r\n\t * to continue until further input stops it.\r\n\t *\r\n\t * You might set ````dollyInertia```` to zero when you want be able to precisely position or rotate the Camera,\r\n\t * without interference from inertia. This also means that xeokit renders less frames while dollying the Camera,\r\n\t * which can improve rendering performance.\r\n\t *\r\n\t * Default is ````0````.\r\n\t *\r\n\t * @param {Number} dollyInertia New dolly inertia factor.\r\n\t */\r\n\tset dollyInertia(dollyInertia) {\r\n\t\tthis._configs.dollyInertia = dollyInertia !== undefined && dollyInertia !== null ? dollyInertia : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the dolly inertia factor.\r\n\t *\r\n\t * Default is ````0````.\r\n\t *\r\n\t * @returns {Number} The current dolly inertia factor.\r\n\t */\r\n\tget dollyInertia() {\r\n\t\treturn this._configs.dollyInertia;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the proximity to the closest object below which dolly speed decreases, and above which dolly speed increases.\r\n\t *\r\n\t * Default is ````35.0````.\r\n\t *\r\n\t * @param {Number} dollyProximityThreshold New dolly proximity threshold.\r\n\t */\r\n\tset dollyProximityThreshold(dollyProximityThreshold) {\r\n\t\tthis._configs.dollyProximityThreshold =\r\n\t\t\tdollyProximityThreshold !== undefined && dollyProximityThreshold !== null ? dollyProximityThreshold : 35.0;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the proximity to the closest object below which dolly speed decreases, and above which dolly speed increases.\r\n\t *\r\n\t * Default is ````35.0````.\r\n\t *\r\n\t * @returns {Number} The current dolly proximity threshold.\r\n\t */\r\n\tget dollyProximityThreshold() {\r\n\t\treturn this._configs.dollyProximityThreshold;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the minimum dolly speed.\r\n\t *\r\n\t * Default is ````0.04````.\r\n\t *\r\n\t * @param {Number} dollyMinSpeed New dolly minimum speed.\r\n\t */\r\n\tset dollyMinSpeed(dollyMinSpeed) {\r\n\t\tthis._configs.dollyMinSpeed = dollyMinSpeed !== undefined && dollyMinSpeed !== null ? dollyMinSpeed : 0.04;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the minimum dolly speed.\r\n\t *\r\n\t * Default is ````0.04````.\r\n\t *\r\n\t * @returns {Number} The current minimum dolly speed.\r\n\t */\r\n\tget dollyMinSpeed() {\r\n\t\treturn this._configs.dollyMinSpeed;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the pan inertia factor.\r\n\t *\r\n\t * This factor configures how much the {@link Camera} keeps moving after you finish panning it.\r\n\t *\r\n\t * This factor is a value in range ````[0..1]````. A value of ````0.0```` causes panning to immediately stop,\r\n\t * ````0.5```` causes panning to decay 50% on each animation frame, while ````1.0```` causes no decay, which allows panning\r\n\t * to continue until further input stops it.\r\n\t *\r\n\t * You might set ````panInertia```` to zero when you want be able to precisely position or rotate the Camera,\r\n\t * without interference from inertia. This also means that xeokit renders less frames while panning the Camera,\r\n\t * wich can improve rendering performance.\r\n\t *\r\n\t * Default is ````0.5````.\r\n\t *\r\n\t * @param {Number} panInertia New pan inertia factor.\r\n\t */\r\n\tset panInertia(panInertia) {\r\n\t\tthis._configs.panInertia = panInertia !== undefined && panInertia !== null ? panInertia : 0.5;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the pan inertia factor.\r\n\t *\r\n\t * Default is ````0.5````.\r\n\t *\r\n\t * @returns {Number} The current pan inertia factor.\r\n\t */\r\n\tget panInertia() {\r\n\t\treturn this._configs.panInertia;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the keyboard layout.\r\n\t *\r\n\t * Supported layouts are:\r\n\t *\r\n\t * * ````\"qwerty\"```` (default)\r\n\t * * ````\"azerty\"````\r\n\t *\r\n\t * @deprecated\r\n\t * @param {String} value Selects the keyboard layout.\r\n\t */\r\n\tset keyboardLayout(value) {\r\n\t\t// this.warn(\"keyboardLayout property is deprecated - use keyMap property instead\");\r\n\t\tvalue = value || \"qwerty\";\r\n\t\tif (value !== \"qwerty\" && value !== \"azerty\") {\r\n\t\t\tthis.error(\"Unsupported value for keyboardLayout - defaulting to 'qwerty'\");\r\n\t\t\tvalue = \"qwerty\";\r\n\t\t}\r\n\t\tthis._configs.keyboardLayout = value;\r\n\t\tthis.keyMap = this._configs.keyboardLayout;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the keyboard layout.\r\n\t *\r\n\t * Supported layouts are:\r\n\t *\r\n\t * * ````\"qwerty\"```` (default)\r\n\t * * ````\"azerty\"````\r\n\t *\r\n\t * @deprecated\r\n\t * @returns {String} The current keyboard layout.\r\n\t */\r\n\tget keyboardLayout() {\r\n\t\treturn this._configs.keyboardLayout;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a sphere as the representation of the pivot position.\r\n\t *\r\n\t * @param {Object} [cfg] Sphere configuration.\r\n\t * @param {String} [cfg.size=1] Optional size factor of the sphere. Defaults to 1.\r\n\t * @param {String} [cfg.material=PhongMaterial] Optional size factor of the sphere. Defaults to a red opaque material.\r\n\t */\r\n\tenablePivotSphere(cfg = {}) {\r\n\t\tthis._controllers.pivotController.enablePivotSphere(cfg);\r\n\t}\r\n\r\n\t/**\r\n\t * Remove the sphere as the representation of the pivot position.\r\n\t *\r\n\t */\r\n\tdisablePivotSphere() {\r\n\t\tthis._controllers.pivotController.disablePivotSphere();\r\n\t}\r\n\r\n\t/**\r\n\t * Sets whether smart default pivoting is enabled.\r\n\t *\r\n\t * When ````true````, we'll pivot by default about the 3D position of the mouse/touch pointer on an\r\n\t * imaginary sphere that's centered at {@link Camera#eye} and sized to the {@link Scene} boundary.\r\n\t *\r\n\t * When ````false````, we'll pivot by default about {@link Camera#look}.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * @param {Boolean} enabled Set ````true```` to pivot by default about the selected point on the virtual sphere, or ````false```` to pivot by default about {@link Camera#look}.\r\n\t */\r\n\tset smartPivot(enabled) {\r\n\t\tthis._configs.smartPivot = enabled !== false;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets whether smart default pivoting is enabled.\r\n\t *\r\n\t * When ````true````, we'll pivot by default about the 3D position of the mouse/touch pointer on an\r\n\t * imaginary sphere that's centered at {@link Camera#eye} and sized to the {@link Scene} boundary.\r\n\t *\r\n\t * When ````false````, we'll pivot by default about {@link Camera#look}.\r\n\t *\r\n\t * Default is ````false````.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` when pivoting by default about the selected point on the virtual sphere, or ````false```` when pivoting by default about {@link Camera#look}.\r\n\t */\r\n\tget smartPivot() {\r\n\t\treturn this._configs.smartPivot;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the double click time frame length in milliseconds.\r\n\t *\r\n\t * If two mouse click events occur within this time frame, it is considered a double click.\r\n\t *\r\n\t * Default is ````250````\r\n\t *\r\n\t * @param {Number} value New double click time frame.\r\n\t */\r\n\tset doubleClickTimeFrame(value) {\r\n\t\tthis._configs.doubleClickTimeFrame = value !== undefined && value !== null ? value : 250;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the double click time frame length in milliseconds.\r\n\t *\r\n\t * Default is ````250````\r\n\t *\r\n\t * @param {Number} value Current double click time frame.\r\n\t */\r\n\tget doubleClickTimeFrame() {\r\n\t\treturn this._configs.doubleClickTimeFrame;\r\n\t}\r\n\r\n\t/**\r\n\t * Destroys this ````CameraControl````.\r\n\t * @private\r\n\t */\r\n\tdestroy() {\r\n\t\tthis._destroyHandlers();\r\n\t\tthis._destroyControllers();\r\n\t\tthis._cameraUpdater.destroy();\r\n\t\tsuper.destroy();\r\n\t}\r\n\r\n\t_destroyHandlers() {\r\n\t\tfor (let i = 0, len = this._handlers.length; i < len; i++) {\r\n\t\t\tconst handler = this._handlers[i];\r\n\t\t\tif (handler.destroy) {\r\n\t\t\t\thandler.destroy();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t_destroyControllers() {\r\n\t\tfor (let i = 0, len = this._controllers.length; i < len; i++) {\r\n\t\t\tconst controller = this._controllers[i];\r\n\t\t\tif (controller.destroy) {\r\n\t\t\t\tcontroller.destroy();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/CameraControl/CameraControl.js?");
2487
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CameraControl: () => (/* binding */ CameraControl)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _camera_CameraFlightAnimation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./../camera/CameraFlightAnimation.js */ \"./src/viewer/scene/camera/CameraFlightAnimation.js\");\n/* harmony import */ var _lib_controllers_PanController_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lib/controllers/PanController.js */ \"./src/viewer/scene/CameraControl/lib/controllers/PanController.js\");\n/* harmony import */ var _lib_controllers_PivotController_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lib/controllers/PivotController.js */ \"./src/viewer/scene/CameraControl/lib/controllers/PivotController.js\");\n/* harmony import */ var _lib_controllers_PickController_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./lib/controllers/PickController.js */ \"./src/viewer/scene/CameraControl/lib/controllers/PickController.js\");\n/* harmony import */ var _lib_handlers_MousePanRotateDollyHandler_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./lib/handlers/MousePanRotateDollyHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/MousePanRotateDollyHandler.js\");\n/* harmony import */ var _lib_handlers_KeyboardAxisViewHandler_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./lib/handlers/KeyboardAxisViewHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/KeyboardAxisViewHandler.js\");\n/* harmony import */ var _lib_handlers_MousePickHandler_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./lib/handlers/MousePickHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/MousePickHandler.js\");\n/* harmony import */ var _lib_handlers_KeyboardPanRotateDollyHandler_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./lib/handlers/KeyboardPanRotateDollyHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/KeyboardPanRotateDollyHandler.js\");\n/* harmony import */ var _lib_CameraUpdater_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./lib/CameraUpdater.js */ \"./src/viewer/scene/CameraControl/lib/CameraUpdater.js\");\n/* harmony import */ var _lib_handlers_MouseMiscHandler_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./lib/handlers/MouseMiscHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/MouseMiscHandler.js\");\n/* harmony import */ var _lib_handlers_TouchPanRotateAndDollyHandler_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./lib/handlers/TouchPanRotateAndDollyHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _lib_handlers_TouchPickHandler_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./lib/handlers/TouchPickHandler.js */ \"./src/viewer/scene/CameraControl/lib/handlers/TouchPickHandler.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst DEFAULT_SNAP_PICK_RADIUS = 20;\nconst DEFAULT_SNAP_VERTEX = true;\nconst DEFAULT_SNAP_EDGE = true;\n\n/**\n * @desc Controls the {@link Camera} with user input, and fires events when the user interacts with pickable {@link Entity}s.\n *\n * # Contents\n *\n * * [Overview](#overview)\n * * [Examples](#examples)\n * * [Orbit Mode](#orbit-mode)\n * + [Following the Pointer in Orbit Mode](#--following-the-pointer-in-orbit-mode--)\n * + [Showing the Pivot Position](#--showing-the-pivot-position--)\n * + [Axis-Aligned Views in Orbit Mode](#--axis-aligned-views-in-orbit-mode--)\n * + [View-Fitting Entitys in Orbit Mode](#--view-fitting-entitys-in-orbit-mode--)\n * * [First-Person Mode](#first-person-mode)\n * + [Following the Pointer in First-Person Mode](#--following-the-pointer-in-first-person-mode--)\n * + [Constraining Vertical Position in First-Person Mode](#--constraining-vertical-position-in-first-person-mode--)\n * + [Axis-Aligned Views in First-Person Mode](#--axis-aligned-views-in-first-person-mode--)\n * + [View-Fitting Entitys in First-Person Mode](#--view-fitting-entitys-in-first-person-mode--)\n * * [Plan-View Mode](#plan-view-mode)\n * + [Following the Pointer in Plan-View Mode](#--following-the-pointer-in-plan-view-mode--)\n * + [Axis-Aligned Views in Plan-View Mode](#--axis-aligned-views-in-plan-view-mode--)\n * * [CameraControl Events](#cameracontrol-events)\n * + [\"hover\"](#---hover---)\n * + [\"hoverOff\"](#---hoveroff---)\n * + [\"hoverEnter\"](#---hoverenter---)\n * + [\"hoverOut\"](#---hoverout---)\n * + [\"picked\"](#---picked---)\n * + [\"pickedSurface\"](#---pickedsurface---)\n * + [\"pickedNothing\"](#---pickednothing---)\n * + [\"doublePicked\"](#---doublepicked---)\n * + [\"doublePickedSurface\"](#---doublepickedsurface---)\n * + [\"doublePickedNothing\"](#---doublepickednothing---)\n * + [\"rightClick\"](#---rightclick---)\n * * [Custom Keyboard Mappings](#custom-keyboard-mappings)\n *\n * <br><br>\n *\n * # Overview\n *\n * * Each {@link Viewer} has a ````CameraControl````, located at {@link Viewer#cameraControl}.\n * * {@link CameraControl#navMode} selects the navigation mode:\n * * ````\"orbit\"```` rotates the {@link Camera} position about the target.\n * * ````\"firstPerson\"```` rotates the World about the Camera position.\n * * ````\"planView\"```` never rotates, but still allows to pan and dolly, typically for an axis-aligned view.\n * * {@link CameraControl#followPointer} makes the Camera follow the mouse or touch pointer.\n * * {@link CameraControl#constrainVertical} locks the Camera to its current height when in first-person mode.\n * * ````CameraControl```` fires pick events when we hover, click or tap on an {@link Entity}.\n * <br><br>\n *\n * # Examples\n *\n * * [Orbit Navigation - Duplex Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_orbit_Duplex)\n * * [Orbit Navigation - Holter Tower Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_orbit_HolterTower)\n * * [First-Person Navigation - Duplex Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_firstPerson_Duplex)\n * * [First-Person Navigation - Holter Tower Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_firstPerson_HolterTower)\n * * [Plan-view Navigation - Schependomlaan Model](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_planView_Schependomlaan)\n * * [Custom Keyboard Mapping](https://xeokit.github.io/xeokit-sdk/examples/#CameraControl_keyMap)\n * <br><br>\n *\n * # Orbit Mode\n *\n * In orbit mode, ````CameraControl```` orbits the {@link Camera} about the target.\n *\n * To enable orbit mode:\n *\n * ````javascript\n * const cameraControl = myViewer.cameraControl;\n * cameraControl.navMode = \"orbit\";\n * ````\n *\n * Then orbit by:\n *\n * * left-dragging the mouse,\n * * tap-dragging the touch pad, and\n * * pressing arrow keys, or ````Q```` and ````E```` on a QWERTY keyboard, or ````A```` and ````E```` on an AZERTY keyboard.\n * <br><br>\n *\n * Dolly forwards and backwards by:\n *\n * * spinning the mouse wheel,\n * * pinching on the touch pad, and\n * * pressing the ````+```` and ````-```` keys, or ````W```` and ````S```` on a QWERTY keyboard, or ````Z```` and ````S```` for AZERTY.\n * <br><br>\n *\n * Pan horizontally and vertically by:\n *\n * * right-dragging the mouse,\n * * left-dragging the mouse with the SHIFT key down,\n * * tap-dragging the touch pad with SHIFT down,\n * * pressing the ````A````, ````D````, ````Z```` and ````X```` keys on a QWERTY keyboard, and\n * * pressing the ````Q````, ````D````, ````W```` and ````X```` keys on an AZERTY keyboard,\n * <br><br>\n *\n * ## Following the Pointer in Orbit Mode\n *\n * When {@link CameraControl#followPointer} is ````true````in orbiting mode, the mouse or touch pointer will dynamically\n * indicate the target that the {@link Camera} will orbit, as well as dolly to and from.\n *\n * Lets ensure that we're in orbit mode, then enable the {@link Camera} to follow the pointer:\n *\n * ````javascript\n * cameraControl.navMode = \"orbit\";\n * cameraControl.followPointer = true;\n * ````\n *\n * ## Smart Pivoting\n *\n * TODO\n *\n * ## Showing the Pivot Position\n *\n * We can configure {@link CameraControl#pivotElement} with an HTML element to indicate the current\n * pivot position. The indicator will appear momentarily each time we move the {@link Camera} while in orbit mode with\n * {@link CameraControl#followPointer} set ````true````.\n *\n * First we'll define some CSS to style our pivot indicator as a black dot with a white border:\n *\n * ````css\n * .camera-pivot-marker {\n * color: #ffffff;\n * position: absolute;\n * width: 25px;\n * height: 25px;\n * border-radius: 15px;\n * border: 2px solid #ebebeb;\n * background: black;\n * visibility: hidden;\n * box-shadow: 5px 5px 15px 1px #000000;\n * z-index: 10000;\n * pointer-events: none;\n * }\n * ````\n *\n * Then we'll attach our pivot indicator's HTML element to the ````CameraControl````:\n *\n * ````javascript\n * const pivotElement = document.createRange().createContextualFragment(\"<div class='camera-pivot-marker'></div>\").firstChild;\n *\n * document.body.appendChild(pivotElement);\n *\n * cameraControl.pivotElement = pivotElement;\n * ````\n *\n * ## Axis-Aligned Views in Orbit Mode\n *\n * In orbit mode, we can use keys 1-6 to position the {@link Camera} to look at the center of the {@link Scene} from along each of the\n * six World-space axis. Pressing one of these keys will fly the {@link Camera} to the corresponding axis-aligned view.\n *\n * ## View-Fitting Entitys in Orbit Mode\n *\n * When {@link CameraControl#doublePickFlyTo} is ````true````, we can left-double-click or\n * double-tap (ie. \"double-pick\") an {@link Entity} to fit it to view. This will cause the {@link Camera}\n * to fly to that Entity. Our target then becomes the center of that Entity. If we are currently pivoting,\n * then our pivot position is then also set to the Entity center.\n *\n * Disable that behaviour by setting {@link CameraControl#doublePickFlyTo} ````false````.\n *\n * # First-Person Mode\n *\n * In first-person mode, ````CameraControl```` rotates the World about the {@link Camera} position.\n *\n * To enable first-person mode:\n *\n * ````javascript\n * cameraControl.navMode = \"firstPerson\";\n * ````\n *\n * Then rotate by:\n *\n * * left-dragging the mouse,\n * * tap-dragging the touch pad,\n * * pressing arrow keys, or ````Q```` and ````E```` on a QWERTY keyboard, or ````A```` and ````E```` on an AZERTY keyboard.\n * <br><br>\n *\n * Dolly forwards and backwards by:\n *\n * * spinning the mouse wheel,\n * * pinching on the touch pad, and\n * * pressing the ````+```` and ````-```` keys, or ````W```` and ````S```` on a QWERTY keyboard, or ````Z```` and ````S```` for AZERTY.\n * <br><br>\n *\n * Pan left, right, up and down by:\n *\n * * left-dragging or right-dragging the mouse, and\n * * tap-dragging the touch pad with SHIFT down.\n *\n * Pan forwards, backwards, left, right, up and down by pressing the ````WSADZX```` keys on a QWERTY keyboard,\n * or ````WSQDWX```` keys on an AZERTY keyboard.\n * <br><br>\n *\n * ## Following the Pointer in First-Person Mode\n *\n * When {@link CameraControl#followPointer} is ````true```` in first-person mode, the mouse or touch pointer will dynamically\n * indicate the target to which the {@link Camera} will dolly to and from. In first-person mode, however, the World will always rotate\n * about the {@link Camera} position.\n *\n * Lets ensure that we're in first-person mode, then enable the {@link Camera} to follow the pointer:\n *\n * ````javascript\n * cameraControl.navMode = \"firstPerson\";\n * cameraControl.followPointer = true;\n * ````\n *\n * When the pointer is over empty space, the target will remain the last object that the pointer was over.\n *\n * ## Constraining Vertical Position in First-Person Mode\n *\n * In first-person mode, we can lock the {@link Camera} to its current position on the vertical World axis, which is useful for walk-through navigation:\n *\n * ````javascript\n * cameraControl.constrainVertical = true;\n * ````\n *\n * ## Axis-Aligned Views in First-Person Mode\n *\n * In first-person mode we can use keys 1-6 to position the {@link Camera} to look at the center of\n * the {@link Scene} from along each of the six World-space axis. Pressing one of these keys will fly the {@link Camera} to the\n * corresponding axis-aligned view.\n *\n * ## View-Fitting Entitys in First-Person Mode\n *\n * As in orbit mode, when in first-person mode and {@link CameraControl#doublePickFlyTo} is ````true````, we can double-click\n * or double-tap an {@link Entity} (ie. \"double-picking\") to fit it in view. This will cause the {@link Camera} to fly to\n * that Entity. Our target then becomes the center of that Entity.\n *\n * Disable that behaviour by setting {@link CameraControl#doublePickFlyTo} ````false````.\n *\n * # Plan-View Mode\n *\n * In plan-view mode, ````CameraControl```` pans and rotates the {@link Camera}, without rotating it.\n *\n * To enable plan-view mode:\n *\n * ````javascript\n * cameraControl.navMode = \"planView\";\n * ````\n *\n * Dolly forwards and backwards by:\n *\n * * spinning the mouse wheel,\n * * pinching on the touch pad, and\n * * pressing the ````+```` and ````-```` keys.\n *\n * <br>\n * Pan left, right, up and down by:\n *\n * * left-dragging or right-dragging the mouse, and\n * * tap-dragging the touch pad with SHIFT down.\n *\n * Pan forwards, backwards, left, right, up and down by pressing the ````WSADZX```` keys on a QWERTY keyboard,\n * or ````WSQDWX```` keys on an AZERTY keyboard.\n * <br><br>\n *\n * ## Following the Pointer in Plan-View Mode\n *\n * When {@link CameraControl#followPointer} is ````true```` in plan-view mode, the mouse or touch pointer will dynamically\n * indicate the target to which the {@link Camera} will dolly to and from. In plan-view mode, however, the {@link Camera} cannot rotate.\n *\n * Lets ensure that we're in plan-view mode, then enable the {@link Camera} to follow the pointer:\n *\n * ````javascript\n * cameraControl.navMode = \"planView\";\n * cameraControl.followPointer = true; // Default\n * ````\n *\n * When the pointer is over empty space, the target will remain the last object that the pointer was over.\n *\n * ## Axis-Aligned Views in Plan-View Mode\n *\n * As in orbit and first-person modes, in plan-view mode we can use keys 1-6 to position the {@link Camera} to look at the center of\n * the {@link Scene} from along each of the six World-space axis. Pressing one of these keys will fly the {@link Camera} to the\n * corresponding axis-aligned view.\n *\n * # CameraControl Events\n *\n * ````CameraControl```` fires events as we interact with {@link Entity}s using mouse or touch input.\n *\n * The following examples demonstrate how to subscribe to those events.\n *\n * The first example shows how to save a handle to a subscription, which we can later use to unsubscribe.\n *\n * ## \"hover\"\n *\n * Event fired when the pointer moves while hovering over an Entity.\n *\n * ````javascript\n * const onHover = cameraControl.on(\"hover\", (e) => {\n * const entity = e.entity; // Entity\n * const canvasPos = e.canvasPos; // 2D canvas position\n * });\n * ````\n *\n * To unsubscribe from the event:\n *\n * ````javascript\n * cameraControl.off(onHover);\n * ````\n *\n * ## \"hoverOff\"\n *\n * Event fired when the pointer moves while hovering over empty space.\n *\n * ````javascript\n * cameraControl.on(\"hoverOff\", (e) => {\n * const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"hoverEnter\"\n *\n * Event fired when the pointer moves onto an Entity.\n *\n * ````javascript\n * cameraControl.on(\"hoverEnter\", (e) => {\n * const entity = e.entity;\n * const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"hoverOut\"\n *\n * Event fired when the pointer moves off an Entity.\n *\n * ````javascript\n * cameraControl.on(\"hoverOut\", (e) => {\n * const entity = e.entity;\n * const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"picked\"\n *\n * Event fired when we left-click or tap on an Entity.\n *\n * ````javascript\n * cameraControl.on(\"picked\", (e) => {\n * const entity = e.entity;\n * const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"pickedSurface\"\n *\n * Event fired when we left-click or tap on the surface of an Entity.\n *\n * ````javascript\n * cameraControl.on(\"picked\", (e) => {\n * const entity = e.entity;\n * const canvasPos = e.canvasPos;\n * const worldPos = e.worldPos; // 3D World-space position\n * const viewPos = e.viewPos; // 3D View-space position\n * const worldNormal = e.worldNormal; // 3D World-space normal vector\n * });\n * ````\n *\n * ## \"pickedNothing\"\n *\n * Event fired when we left-click or tap on empty space.\n *\n * ````javascript\n * cameraControl.on(\"pickedNothing\", (e) => {\n * const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"doublePicked\"\n *\n * Event fired wwhen we left-double-click or double-tap on an Entity.\n *\n * ````javascript\n * cameraControl.on(\"doublePicked\", (e) => {\n * const entity = e.entity;\n * const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"doublePickedSurface\"\n *\n * Event fired when we left-double-click or double-tap on the surface of an Entity.\n *\n * ````javascript\n * cameraControl.on(\"doublePickedSurface\", (e) => {\n * const entity = e.entity;\n * const canvasPos = e.canvasPos;\n * const worldPos = e.worldPos;\n * const viewPos = e.viewPos;\n * const worldNormal = e.worldNormal;\n * });\n * ````\n *\n * ## \"doublePickedNothing\"\n *\n * Event fired when we left-double-click or double-tap on empty space.\n *\n * ````javascript\n * cameraControl.on(\"doublePickedNothing\", (e) => {\n * const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"rightClick\"\n *\n * Event fired when we right-click on the canvas.\n *\n * ````javascript\n * cameraControl.on(\"rightClick\", (e) => {\n * const event = e.event; // Mouse event\n * const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## Custom Keyboard Mappings\n *\n * We can customize````CameraControl```` key bindings as shown below.\n *\n * In this example, we'll just set the default bindings for a QWERTY keyboard.\n *\n * ````javascript\n * const input = myViewer.scene.input;\n *\n * cameraControl.navMode = \"orbit\";\n * cameraControl.followPointer = true;\n *\n * const keyMap = {};\n *\n * keyMap[cameraControl.PAN_LEFT] = [input.KEY_A];\n * keyMap[cameraControl.PAN_RIGHT] = [input.KEY_D];\n * keyMap[cameraControl.PAN_UP] = [input.KEY_Z];\n * keyMap[cameraControl.PAN_DOWN] = [input.KEY_X];\n * keyMap[cameraControl.DOLLY_FORWARDS] = [input.KEY_W, input.KEY_ADD];\n * keyMap[cameraControl.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\n * keyMap[cameraControl.ROTATE_X_POS] = [input.KEY_DOWN_ARROW];\n * keyMap[cameraControl.ROTATE_X_NEG] = [input.KEY_UP_ARROW];\n * keyMap[cameraControl.ROTATE_Y_POS] = [input.KEY_LEFT_ARROW];\n * keyMap[cameraControl.ROTATE_Y_NEG] = [input.KEY_RIGHT_ARROW];\n * keyMap[cameraControl.AXIS_VIEW_RIGHT] = [input.KEY_NUM_1];\n * keyMap[cameraControl.AXIS_VIEW_BACK] = [input.KEY_NUM_2];\n * keyMap[cameraControl.AXIS_VIEW_LEFT] = [input.KEY_NUM_3];\n * keyMap[cameraControl.AXIS_VIEW_FRONT] = [input.KEY_NUM_4];\n * keyMap[cameraControl.AXIS_VIEW_TOP] = [input.KEY_NUM_5];\n * keyMap[cameraControl.AXIS_VIEW_BOTTOM] = [input.KEY_NUM_6];\n *\n * cameraControl.keyMap = keyMap;\n * ````\n *\n * We can also just configure default bindings for a specified keyboard layout, like this:\n *\n * ````javascript\n * cameraControl.keyMap = \"qwerty\";\n * ````\n *\n * Then, ````CameraControl```` will internally set {@link CameraControl#keyMap} to the default key map for the QWERTY\n * layout (which is the same set of mappings we set in the previous example). In other words, if we subsequently\n * read {@link CameraControl#keyMap}, it will now be a key map, instead of the \"qwerty\" string value we set it to.\n *\n * Supported layouts are, so far:\n *\n * * ````\"qwerty\"````\n * * ````\"azerty\"````\n */\nclass CameraControl extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\n\t/**\n\t * @private\n\t * @constructor\n\t */\n\tconstructor(owner, cfg = {}) {\n\t\tsuper(owner, cfg);\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.PAN_LEFT = 0;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.PAN_RIGHT = 1;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.PAN_UP = 2;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.PAN_DOWN = 3;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.PAN_FORWARDS = 4;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.PAN_BACKWARDS = 5;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.ROTATE_X_POS = 6;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.ROTATE_X_NEG = 7;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.ROTATE_Y_POS = 8;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.ROTATE_Y_NEG = 9;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.DOLLY_FORWARDS = 10;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.DOLLY_BACKWARDS = 11;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.AXIS_VIEW_RIGHT = 12;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.AXIS_VIEW_BACK = 13;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.AXIS_VIEW_LEFT = 14;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.AXIS_VIEW_FRONT = 15;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.AXIS_VIEW_TOP = 16;\n\n\t\t/**\n\t\t * Identifies the XX action.\n\t\t * @final\n\t\t * @type {Number}\n\t\t */\n\t\tthis.AXIS_VIEW_BOTTOM = 17;\n\n\t\tthis._keyMap = {}; // Maps key codes to the above actions\n\n\t\tthis.scene.canvas.canvas.oncontextmenu = (e) => {\n\t\t\te.preventDefault();\n\t\t};\n\n\t\t// User-settable CameraControl configurations\n\n\t\tthis._configs = {\n\t\t\t// Private\n\n\t\t\tlongTapTimeout: 600, // Millisecs\n\t\t\tlongTapRadius: 5, // Pixels\n\n\t\t\t// General\n\n\t\t\tactive: true,\n\t\t\tkeyboardLayout: \"qwerty\",\n\t\t\tnavMode: \"orbit\",\n\t\t\tplanView: false,\n\t\t\tfirstPerson: false,\n\t\t\tfollowPointer: true,\n\t\t\tdoublePickFlyTo: true,\n\t\t\tpanRightClick: true,\n\t\t\tshowPivot: false,\n\t\t\tpointerEnabled: true,\n\t\t\tconstrainVertical: false,\n\t\t\tsmartPivot: false,\n\t\t\tdoubleClickTimeFrame: 250,\n\n\t\t\tsnapToVertex: DEFAULT_SNAP_VERTEX,\n\t\t\tsnapToEdge: DEFAULT_SNAP_EDGE,\n\t\t\tsnapRadius: cfg.snapRadius ? cfg.snapRadius : DEFAULT_SNAP_PICK_RADIUS,\n\n\t\t\t// Rotation\n\n\t\t\tdragRotationRate: 360.0,\n\t\t\tkeyboardRotationRate: 90.0,\n\t\t\trotationInertia: 0.0,\n\n\t\t\t// Panning\n\n\t\t\tkeyboardPanRate: 1.0,\n\t\t\ttouchPanRate: 1.0,\n\t\t\tpanInertia: 0.5,\n\n\t\t\t// Dollying\n\n\t\t\tkeyboardDollyRate: 10,\n\t\t\tmouseWheelDollyRate: 100,\n\t\t\ttouchDollyRate: 0.2,\n\t\t\tdollyInertia: 0,\n\t\t\tdollyProximityThreshold: 30.0,\n\t\t\tdollyMinSpeed: 0.04\n\t\t};\n\n\t\t// Current runtime state of the CameraControl\n\n\t\tthis._states = {\n\t\t\tpointerCanvasPos: _math_math_js__WEBPACK_IMPORTED_MODULE_13__.math.vec2(),\n\t\t\tmouseover: false,\n\t\t\tfollowPointerDirty: true,\n\t\t\tmouseDownClientX: 0,\n\t\t\tmouseDownClientY: 0,\n\t\t\tmouseDownCursorX: 0,\n\t\t\tmouseDownCursorY: 0,\n\t\t\ttouchStartTime: null,\n\t\t\tactiveTouches: [],\n\t\t\ttapStartPos: _math_math_js__WEBPACK_IMPORTED_MODULE_13__.math.vec2(),\n\t\t\ttapStartTime: -1,\n\t\t\tlastTapTime: -1,\n\t\t\tlongTouchTimeout: null\n\t\t};\n\n\t\t// Updates for CameraUpdater to process on next Scene \"tick\" event\n\n\t\tthis._updates = {\n\t\t\trotateDeltaX: 0,\n\t\t\trotateDeltaY: 0,\n\t\t\tpanDeltaX: 0,\n\t\t\tpanDeltaY: 0,\n\t\t\tpanDeltaZ: 0,\n\t\t\tdollyDelta: 0\n\t\t};\n\n\t\t// Controllers to assist input event handlers with controlling the Camera\n\n\t\tconst scene = this.scene;\n\n\t\tthis._controllers = {\n\t\t\tcameraControl: this,\n\t\t\tpickController: new _lib_controllers_PickController_js__WEBPACK_IMPORTED_MODULE_4__.PickController(this, this._configs),\n\t\t\tpivotController: new _lib_controllers_PivotController_js__WEBPACK_IMPORTED_MODULE_3__.PivotController(scene, this._configs),\n\t\t\tpanController: new _lib_controllers_PanController_js__WEBPACK_IMPORTED_MODULE_2__.PanController(scene),\n\t\t\tcameraFlight: new _camera_CameraFlightAnimation_js__WEBPACK_IMPORTED_MODULE_1__.CameraFlightAnimation(this, {\n\t\t\t\tduration: 0.5\n\t\t\t})\n\t\t};\n\n\t\t// Input event handlers\n\n\t\tthis._handlers = [\n\t\t\tnew _lib_handlers_MouseMiscHandler_js__WEBPACK_IMPORTED_MODULE_10__.MouseMiscHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n\t\t\tnew _lib_handlers_TouchPanRotateAndDollyHandler_js__WEBPACK_IMPORTED_MODULE_11__.TouchPanRotateAndDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n\t\t\tnew _lib_handlers_MousePanRotateDollyHandler_js__WEBPACK_IMPORTED_MODULE_5__.MousePanRotateDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n\t\t\tnew _lib_handlers_KeyboardAxisViewHandler_js__WEBPACK_IMPORTED_MODULE_6__.KeyboardAxisViewHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n\t\t\tnew _lib_handlers_MousePickHandler_js__WEBPACK_IMPORTED_MODULE_7__.MousePickHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n\t\t\tnew _lib_handlers_TouchPickHandler_js__WEBPACK_IMPORTED_MODULE_14__.TouchPickHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n\t\t\tnew _lib_handlers_KeyboardPanRotateDollyHandler_js__WEBPACK_IMPORTED_MODULE_8__.KeyboardPanRotateDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates)\n\t\t];\n\n\t\t// Applies scheduled updates to the Camera on each Scene \"tick\" event\n\n\t\tthis._cameraUpdater = new _lib_CameraUpdater_js__WEBPACK_IMPORTED_MODULE_9__.CameraUpdater(this.scene, this._controllers, this._configs, this._states, this._updates);\n\n\t\t// Set initial user configurations\n\n\t\tthis.navMode = cfg.navMode;\n\t\tif (cfg.planView) {\n\t\t\tthis.planView = cfg.planView;\n\t\t}\n\t\tthis.constrainVertical = cfg.constrainVertical;\n\t\tif (cfg.keyboardLayout) {\n\t\t\tthis.keyboardLayout = cfg.keyboardLayout; // Deprecated\n\t\t} else {\n\t\t\tthis.keyMap = cfg.keyMap;\n\t\t}\n\t\tthis.doublePickFlyTo = cfg.doublePickFlyTo;\n\t\tthis.panRightClick = cfg.panRightClick;\n\t\tthis.active = cfg.active;\n\t\tthis.followPointer = cfg.followPointer;\n\t\tthis.rotationInertia = cfg.rotationInertia;\n\t\tthis.keyboardPanRate = cfg.keyboardPanRate;\n\t\tthis.touchPanRate = cfg.touchPanRate;\n\t\tthis.keyboardRotationRate = cfg.keyboardRotationRate;\n\t\tthis.dragRotationRate = cfg.dragRotationRate;\n\t\tthis.touchDollyRate = cfg.touchDollyRate;\n\t\tthis.dollyInertia = cfg.dollyInertia;\n\t\tthis.dollyProximityThreshold = cfg.dollyProximityThreshold;\n\t\tthis.dollyMinSpeed = cfg.dollyMinSpeed;\n\t\tthis.panInertia = cfg.panInertia;\n\t\tthis.pointerEnabled = true;\n\t\tthis.keyboardDollyRate = cfg.keyboardDollyRate;\n\t\tthis.mouseWheelDollyRate = cfg.mouseWheelDollyRate;\n\t\tthis._moveRate = 1;\n\t\tthis.scene.on(\"tick\", () => {\n\t\t\t// if (!(this._configs.active && this._configs.pointerEnabled)) return;\n\t\t\t// if (!this._states.mouseover) return;\n\t\t\tif (!(this._goLeft || this._goRight || this._goUp || this._goDown || this._goForward || this._goBackward)) {\n\t\t\t\t// this._inputDirectionCommand = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this._goRight) {\n\t\t\t\tthis._updates.panDeltaX += -0.1 * this._moveRate;\n\t\t\t} else if (this._goLeft) {\n\t\t\t\tthis._updates.panDeltaX += 0.1 * this._moveRate;\n\t\t\t}\n\n\t\t\tif (this._goUp) {\n\t\t\t\tthis._updates.panDeltaY += 0.1 * this._moveRate;\n\t\t\t} else if (this._goDown) {\n\t\t\t\tthis._updates.panDeltaY += -0.1 * this._moveRate;\n\t\t\t}\n\n\t\t\tif (this._goForward) {\n\t\t\t\tthis._updates.panDeltaZ += -0.1 * this._moveRate;\n\t\t\t} else if (this._goBackward) {\n\t\t\t\tthis._updates.panDeltaZ += +0.1 * this._moveRate;\n\t\t\t}\n\t\t\tthis._inputDirectionCommand = true;\n\t\t});\n\t}\n\t/**\n\t * 停止漫游\n\t */\n\tsetdirectionChangeCancel() {\n\t\tthis._goLeft = false;\n\t\tthis._goRight = false;\n\t\tthis._goUp = false;\n\t\tthis._goDown = false;\n\t\tthis._goForward = false;\n\t\tthis._goBackward = false;\n\t}\n\n\t/**\n\t * 设置漫游移动速率\n\t * @param {number} rate\n\t */\n\tset moveRate(rate) {\n\t\tthis._moveRate = rate;\n\t}\n\n\t/**\n\t * 漫游向右\n\t * @param {boolean} go\n\t */\n\tset goRight(go) {\n\t\tthis._goRight = go;\n\t}\n\t/**\n\t * 漫游向左\n\t * @param {boolean} go\n\t */\n\tset goLeft(go) {\n\t\tthis._goLeft = go;\n\t}\n\t/**\n\t * 漫游向上\n\t * @param {boolean} go\n\t */\n\tset goUp(go) {\n\t\tthis._goUp = go;\n\t}\n\t/**\n\t * 漫游向下\n\t * @param {boolean} go\n\t */\n\tset goDown(go) {\n\t\tthis._goDown = go;\n\t}\n\t/**\n\t * 漫游向前\n\t * @param {boolean} go\n\t */\n\tset goForward(go) {\n\t\tthis._goForward = go;\n\t}\n\t/**\n\t * 漫游向后\n\t * @param {boolean} go\n\t */\n\tset goBackward(go) {\n\t\tthis._goBackward = go;\n\t}\n\n\tupdatePivotElement() {\n\t\tthis._controllers.pivotController.updatePivotElement();\n\t}\n\n\t/**\n\t * Sets custom mappings of keys to ````CameraControl```` actions.\n\t *\n\t * See class docs for usage.\n\t *\n\t * @param {{Number:Number}|String} value Either a set of new key mappings, or a string to select a keyboard layout,\n\t * which causes ````CameraControl```` to use the default key mappings for that layout.\n\t */\n\tset keyMap(value) {\n\t\tvalue = value || \"qwerty\";\n\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_12__.utils.isString(value)) {\n\t\t\tconst input = this.scene.input;\n\t\t\tconst keyMap = {};\n\n\t\t\tswitch (value) {\n\t\t\t\tdefault:\n\t\t\t\t\tthis.error(\"Unsupported value for 'keyMap': \" + value + \" defaulting to 'qwerty'\");\n\t\t\t\t// Intentional fall-through to \"qwerty\"\n\t\t\t\tcase \"qwerty\":\n\t\t\t\t\tkeyMap[this.PAN_LEFT] = [input.KEY_A];\n\t\t\t\t\tkeyMap[this.PAN_RIGHT] = [input.KEY_D];\n\t\t\t\t\tkeyMap[this.PAN_UP] = [input.KEY_Z];\n\t\t\t\t\tkeyMap[this.PAN_DOWN] = [input.KEY_X];\n\t\t\t\t\tkeyMap[this.PAN_BACKWARDS] = [];\n\t\t\t\t\tkeyMap[this.PAN_FORWARDS] = [];\n\t\t\t\t\tkeyMap[this.DOLLY_FORWARDS] = [input.KEY_W, input.KEY_ADD];\n\t\t\t\t\tkeyMap[this.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\n\t\t\t\t\tkeyMap[this.ROTATE_X_POS] = [input.KEY_DOWN_ARROW];\n\t\t\t\t\tkeyMap[this.ROTATE_X_NEG] = [input.KEY_UP_ARROW];\n\t\t\t\t\tkeyMap[this.ROTATE_Y_POS] = [input.KEY_Q, input.KEY_LEFT_ARROW];\n\t\t\t\t\tkeyMap[this.ROTATE_Y_NEG] = [input.KEY_E, input.KEY_RIGHT_ARROW];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_RIGHT] = [input.KEY_NUM_1];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_BACK] = [input.KEY_NUM_2];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_LEFT] = [input.KEY_NUM_3];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_FRONT] = [input.KEY_NUM_4];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_TOP] = [input.KEY_NUM_5];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_BOTTOM] = [input.KEY_NUM_6];\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"azerty\":\n\t\t\t\t\tkeyMap[this.PAN_LEFT] = [input.KEY_Q];\n\t\t\t\t\tkeyMap[this.PAN_RIGHT] = [input.KEY_D];\n\t\t\t\t\tkeyMap[this.PAN_UP] = [input.KEY_W];\n\t\t\t\t\tkeyMap[this.PAN_DOWN] = [input.KEY_X];\n\t\t\t\t\tkeyMap[this.PAN_BACKWARDS] = [];\n\t\t\t\t\tkeyMap[this.PAN_FORWARDS] = [];\n\t\t\t\t\tkeyMap[this.DOLLY_FORWARDS] = [input.KEY_Z, input.KEY_ADD];\n\t\t\t\t\tkeyMap[this.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\n\t\t\t\t\tkeyMap[this.ROTATE_X_POS] = [input.KEY_DOWN_ARROW];\n\t\t\t\t\tkeyMap[this.ROTATE_X_NEG] = [input.KEY_UP_ARROW];\n\t\t\t\t\tkeyMap[this.ROTATE_Y_POS] = [input.KEY_A, input.KEY_LEFT_ARROW];\n\t\t\t\t\tkeyMap[this.ROTATE_Y_NEG] = [input.KEY_E, input.KEY_RIGHT_ARROW];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_RIGHT] = [input.KEY_NUM_1];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_BACK] = [input.KEY_NUM_2];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_LEFT] = [input.KEY_NUM_3];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_FRONT] = [input.KEY_NUM_4];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_TOP] = [input.KEY_NUM_5];\n\t\t\t\t\tkeyMap[this.AXIS_VIEW_BOTTOM] = [input.KEY_NUM_6];\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis._keyMap = keyMap;\n\t\t} else {\n\t\t\tconst keyMap = value;\n\t\t\tthis._keyMap = keyMap;\n\t\t}\n\t}\n\n\t/**\n\t * Gets custom mappings of keys to {@link CameraControl} actions.\n\t *\n\t * @returns {{Number:Number}} Current key mappings.\n\t */\n\tget keyMap() {\n\t\treturn this._keyMap;\n\t}\n\n\t/**\n\t * Returns true if any keys configured for the given action are down.\n\t * @param action\n\t * @param keyDownMap\n\t * @private\n\t */\n\t_isKeyDownForAction(action, keyDownMap) {\n\t\tconst keys = this._keyMap[action];\n\t\tif (!keys) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!keyDownMap) {\n\t\t\tkeyDownMap = this.scene.input.keyDown;\n\t\t}\n\t\tfor (let i = 0, len = keys.length; i < len; i++) {\n\t\t\tconst key = keys[i];\n\t\t\tif (keyDownMap[key]) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Sets the HTMl element to represent the pivot point when {@link CameraControl#followPointer} is true.\n\t *\n\t * See class comments for an example.\n\t *\n\t * @param {HTMLElement} element HTML element representing the pivot point.\n\t */\n\tset pivotElement(element) {\n\t\tthis._controllers.pivotController.setPivotElement(element);\n\t}\n\n\t/**\n\t * Sets if this ````CameraControl```` is active or not.\n\t *\n\t * When inactive, the ````CameraControl```` will not react to input.\n\t *\n\t * Default is ````true````.\n\t *\n\t * @param {Boolean} value Set ````true```` to activate this ````CameraControl````.\n\t */\n\tset active(value) {\n\t\tvalue = value !== false;\n\t\tthis._configs.active = value;\n\t\tthis._handlers[1]._active = value;\n\t\tthis._handlers[5]._active = value;\n\t}\n\n\t/**\n\t * Gets if this ````CameraControl```` is active or not.\n\t *\n\t * When inactive, the ````CameraControl```` will not react to input.\n\t *\n\t * Default is ````true````.\n\t *\n\t * @returns {Boolean} Returns ````true```` if this ````CameraControl```` is active.\n\t */\n\tget active() {\n\t\treturn this._configs.active;\n\t}\n\n\t/**\n\t * Sets whether the pointer snap to vertex.\n\t *\n\t * @param {boolean} snapToVertex\n\t */\n\tset snapToVertex(snapToVertex) {\n\t\tthis._configs.snapToVertex = !!snapToVertex;\n\t}\n\n\t/**\n\t * Gets whether the pointer snap to vertex.\n\t *\n\t * @returns {boolean}\n\t */\n\tget snapToVertex() {\n\t\treturn this._configs.snapToVertex;\n\t}\n\n\t/**\n\t * Sets whether the pointer snap to edge.\n\t *\n\t * @param {boolean} snapToEdge\n\t */\n\tset snapToEdge(snapToEdge) {\n\t\tthis._configs.snapToEdge = !!snapToEdge;\n\t}\n\n\t/**\n\t * Gets whether the pointer snap to edge.\n\t *\n\t * @returns {boolean}\n\t */\n\tget snapToEdge() {\n\t\treturn this._configs.snapToEdge;\n\t}\n\n\t/**\n\t * Sets the current snap radius for \"hoverSnapOrSurface\" events, to specify whether the radius\n\t * within which the pointer snaps to the nearest vertex or the nearest edge.\n\t *\n\t * Default value is 30 pixels.\n\t *\n\t * @param {Number} snapRadius The snap radius.\n\t */\n\tset snapRadius(snapRadius) {\n\t\tsnapRadius = snapRadius || DEFAULT_SNAP_PICK_RADIUS;\n\t\tthis._configs.snapRadius = snapRadius;\n\t}\n\n\t/**\n\t * Gets the current snap radius.\n\t *\n\t * @returns {Number} The snap radius.\n\t */\n\tget snapRadius() {\n\t\treturn this._configs.snapRadius;\n\t}\n\n\t/**\n\t * Sets the current navigation mode.\n\t *\n\t * Accepted values are:\n\t *\n\t * * \"orbit\" - rotation orbits about the current target or pivot point,\n\t * * \"firstPerson\" - rotation is about the current eye position,\n\t * * \"planView\" - rotation is disabled.\n\t *\n\t * See class comments for more info.\n\t *\n\t * @param {String} navMode The navigation mode: \"orbit\", \"firstPerson\" or \"planView\".\n\t */\n\tset navMode(navMode) {\n\t\tnavMode = navMode || \"orbit\";\n\t\tif (navMode !== \"firstPerson\" && navMode !== \"orbit\" && navMode !== \"planView\") {\n\t\t\tthis.error(\n\t\t\t\t\"Unsupported value for navMode: \" +\n\t\t\t\t\tnavMode +\n\t\t\t\t\t\" - supported values are 'orbit', 'firstPerson' and 'planView' - defaulting to 'orbit'\"\n\t\t\t);\n\t\t\tnavMode = \"orbit\";\n\t\t}\n\t\tthis._configs.firstPerson = navMode === \"firstPerson\";\n\t\tthis._configs.planView = navMode === \"planView\";\n\t\tif (this._configs.firstPerson || this._configs.planView) {\n\t\t\tthis._controllers.pivotController.hidePivot();\n\t\t\tthis._controllers.pivotController.endPivot();\n\t\t}\n\t\tthis._configs.navMode = navMode;\n\t}\n\n\t/**\n\t * Gets the current navigation mode.\n\t *\n\t * @returns {String} The navigation mode: \"orbit\", \"firstPerson\" or \"planView\".\n\t */\n\tget navMode() {\n\t\treturn this._configs.navMode;\n\t}\n\n\t/**\n\t * Sets whether mouse and touch input is enabled.\n\t *\n\t * Default is ````true````.\n\t *\n\t * Disabling mouse and touch input on ````CameraControl```` is useful when we want to temporarily use mouse or\n\t * touch input to interact with some other 3D control, without disturbing the {@link Camera}.\n\t *\n\t * @param {Boolean} value Set ````true```` to enable mouse and touch input.\n\t */\n\tset pointerEnabled(value) {\n\t\tthis._reset();\n\t\tthis._configs.pointerEnabled = !!value;\n\t}\n\n\t_reset() {\n\t\tfor (let i = 0, len = this._handlers.length; i < len; i++) {\n\t\t\tconst handler = this._handlers[i];\n\t\t\tif (handler.reset) {\n\t\t\t\thandler.reset();\n\t\t\t}\n\t\t}\n\n\t\tthis._updates.panDeltaX = 0;\n\t\tthis._updates.panDeltaY = 0;\n\t\tthis._updates.rotateDeltaX = 0;\n\t\tthis._updates.rotateDeltaY = 0;\n\t\tthis._updates.dolyDelta = 0;\n\t}\n\n\t/**\n\t * Gets whether mouse and touch input is enabled.\n\t *\n\t * Default is ````true````.\n\t *\n\t * Disabling mouse and touch input on ````CameraControl```` is desirable when we want to temporarily use mouse or\n\t * touch input to interact with some other 3D control, without interfering with the {@link Camera}.\n\t *\n\t * @returns {Boolean} Returns ````true```` if mouse and touch input is enabled.\n\t */\n\tget pointerEnabled() {\n\t\treturn this._configs.pointerEnabled;\n\t}\n\n\t/**\n\t * Sets whether the {@link Camera} follows the mouse/touch pointer.\n\t *\n\t * In orbiting mode, the Camera will orbit about the pointer, and will dolly to and from the pointer.\n\t *\n\t * In fly-to mode, the Camera will dolly to and from the pointer, however the World will always rotate about the Camera position.\n\t *\n\t * In plan-view mode, the Camera will dolly to and from the pointer, however the Camera will not rotate.\n\t *\n\t * Default is ````true````.\n\t *\n\t * See class comments for more info.\n\t *\n\t * @param {Boolean} value Set ````true```` to enable the Camera to follow the pointer.\n\t */\n\tset followPointer(value) {\n\t\tthis._configs.followPointer = value !== false;\n\t}\n\n\t/**\n\t * Sets whether the {@link Camera} follows the mouse/touch pointer.\n\t *\n\t * In orbiting mode, the Camera will orbit about the pointer, and will dolly to and from the pointer.\n\t *\n\t * In fly-to mode, the Camera will dolly to and from the pointer, however the World will always rotate about the Camera position.\n\t *\n\t * In plan-view mode, the Camera will dolly to and from the pointer, however the Camera will not rotate.\n\t *\n\t * Default is ````true````.\n\t *\n\t * See class comments for more info.\n\t *\n\t * @returns {Boolean} Returns ````true```` if the Camera follows the pointer.\n\t */\n\tget followPointer() {\n\t\treturn this._configs.followPointer;\n\t}\n\n\t/**\n\t * Sets the current World-space 3D target position.\n\t *\n\t * Only applies when {@link CameraControl#followPointer} is ````true````.\n\t *\n\t * @param {Number[]} worldPos The new World-space 3D target position.\n\t */\n\tset pivotPos(worldPos) {\n\t\tthis._controllers.pivotController.setPivotPos(worldPos);\n\t}\n\n\t/**\n\t * Gets the current World-space 3D pivot position.\n\t *\n\t * Only applies when {@link CameraControl#followPointer} is ````true````.\n\t *\n\t * @return {Number[]} worldPos The current World-space 3D pivot position.\n\t */\n\tget pivotPos() {\n\t\treturn this._controllers.pivotController.getPivotPos();\n\t}\n\n\t/**\n\t * @deprecated\n\t * @param {Boolean} value Set ````true```` to enable dolly-to-pointer behaviour.\n\t */\n\tset dollyToPointer(value) {\n\t\tthis.warn(\"dollyToPointer property is deprecated - replaced with followPointer\");\n\t\tthis.followPointer = value;\n\t}\n\n\t/**\n\t * @deprecated\n\t * @returns {Boolean} Returns ````true```` if dolly-to-pointer behaviour is enabled.\n\t */\n\tget dollyToPointer() {\n\t\tthis.warn(\"dollyToPointer property is deprecated - replaced with followPointer\");\n\t\treturn this.followPointer;\n\t}\n\n\t/**\n\t * @deprecated\n\t * @param {Boolean} value Set ````true```` to enable dolly-to-pointer behaviour.\n\t */\n\tset panToPointer(value) {\n\t\tthis.warn(\"panToPointer property is deprecated - replaced with followPointer\");\n\t}\n\n\t/**\n\t * @deprecated\n\t * @returns {Boolean} Returns ````true```` if dolly-to-pointer behaviour is enabled.\n\t */\n\tget panToPointer() {\n\t\tthis.warn(\"panToPointer property is deprecated - replaced with followPointer\");\n\t\treturn false;\n\t}\n\n\t/**\n\t * Sets whether this ````CameraControl```` is in plan-view mode.\n\t *\n\t * When in plan-view mode, rotation is disabled.\n\t *\n\t * Default is ````false````.\n\t *\n\t * Deprecated - use {@link CameraControl#navMode} instead.\n\t *\n\t * @param {Boolean} value Set ````true```` to enable plan-view mode.\n\t * @deprecated\n\t */\n\tset planView(value) {\n\t\tthis._configs.planView = !!value;\n\t\tthis._configs.firstPerson = false;\n\t\tif (this._configs.planView) {\n\t\t\tthis._controllers.pivotController.hidePivot();\n\t\t\tthis._controllers.pivotController.endPivot();\n\t\t}\n\t\tthis.warn(\"planView property is deprecated - replaced with navMode\");\n\t}\n\n\t/**\n\t * Gets whether this ````CameraControl```` is in plan-view mode.\n\t *\n\t * When in plan-view mode, rotation is disabled.\n\t *\n\t * Default is ````false````.\n\t *\n\t * Deprecated - use {@link CameraControl#navMode} instead.\n\t *\n\t * @returns {Boolean} Returns ````true```` if plan-view mode is enabled.\n\t * @deprecated\n\t */\n\tget planView() {\n\t\tthis.warn(\"planView property is deprecated - replaced with navMode\");\n\t\treturn this._configs.planView;\n\t}\n\n\t/**\n\t * Sets whether this ````CameraControl```` is in first-person mode.\n\t *\n\t * In \"first person\" mode (disabled by default) the look position rotates about the eye position. Otherwise, {@link Camera#eye} rotates about {@link Camera#look}.\n\t *\n\t * Default is ````false````.\n\t *\n\t * Deprecated - use {@link CameraControl#navMode} instead.\n\t *\n\t * @param {Boolean} value Set ````true```` to enable first-person mode.\n\t * @deprecated\n\t */\n\tset firstPerson(value) {\n\t\tthis.warn(\"firstPerson property is deprecated - replaced with navMode\");\n\t\tthis._configs.firstPerson = !!value;\n\t\tthis._configs.planView = false;\n\t\tif (this._configs.firstPerson) {\n\t\t\tthis._controllers.pivotController.hidePivot();\n\t\t\tthis._controllers.pivotController.endPivot();\n\t\t}\n\t}\n\n\t/**\n\t * Gets whether this ````CameraControl```` is in first-person mode.\n\t *\n\t * In \"first person\" mode (disabled by default) the look position rotates about the eye position. Otherwise, {@link Camera#eye} rotates about {@link Camera#look}.\n\t *\n\t * Default is ````false````.\n\t *\n\t * Deprecated - use {@link CameraControl#navMode} instead.\n\t *\n\t * @returns {Boolean} Returns ````true```` if first-person mode is enabled.\n\t * @deprecated\n\t */\n\tget firstPerson() {\n\t\tthis.warn(\"firstPerson property is deprecated - replaced with navMode\");\n\t\treturn this._configs.firstPerson;\n\t}\n\n\t/**\n\t * Sets whether to vertically constrain the {@link Camera} position for first-person navigation.\n\t *\n\t * When set ````true````, this constrains {@link Camera#eye} to its current vertical position.\n\t *\n\t * Only applies when {@link CameraControl#navMode} is ````\"firstPerson\"````.\n\t *\n\t * Default is ````false````.\n\t *\n\t * @param {Boolean} value Set ````true```` to vertically constrain the Camera.\n\t */\n\tset constrainVertical(value) {\n\t\tthis._configs.constrainVertical = !!value;\n\t}\n\n\t/**\n\t * Gets whether to vertically constrain the {@link Camera} position for first-person navigation.\n\t *\n\t * When set ````true````, this constrains {@link Camera#eye} to its current vertical position.\n\t *\n\t * Only applies when {@link CameraControl#navMode} is ````\"firstPerson\"````.\n\t *\n\t * Default is ````false````.\n\t *\n\t * @returns {Boolean} ````true```` when Camera is vertically constrained.\n\t */\n\tget constrainVertical() {\n\t\treturn this._configs.constrainVertical;\n\t}\n\n\t/**\n\t * Sets whether double-picking an {@link Entity} causes the {@link Camera} to fly to its boundary.\n\t *\n\t * Default is ````false````.\n\t *\n\t * @param {Boolean} value Set ````true```` to enable double-pick-fly-to mode.\n\t */\n\tset doublePickFlyTo(value) {\n\t\tthis._configs.doublePickFlyTo = value !== false;\n\t}\n\n\t/**\n\t * Gets whether double-picking an {@link Entity} causes the {@link Camera} to fly to its boundary.\n\t *\n\t * Default is ````false````.\n\t *\n\t * @returns {Boolean} Returns ````true```` when double-pick-fly-to mode is enabled.\n\t */\n\tget doublePickFlyTo() {\n\t\treturn this._configs.doublePickFlyTo;\n\t}\n\n\t/**\n\t * Sets whether either right-clicking (true) or middle-clicking (false) pans the {@link Camera}.\n\t *\n\t * Default is ````true````.\n\t *\n\t * @param {Boolean} value Set ````false```` to disable pan on right-click.\n\t */\n\tset panRightClick(value) {\n\t\tthis._configs.panRightClick = value !== false;\n\t}\n\n\t/**\n\t * Gets whether right-clicking pans the {@link Camera}.\n\t *\n\t * Default is ````true````.\n\t *\n\t * @returns {Boolean} Returns ````false```` when pan on right-click is disabled.\n\t */\n\tget panRightClick() {\n\t\treturn this._configs.panRightClick;\n\t}\n\n\t/**\n\t * Sets a factor in range ````[0..1]```` indicating how much the {@link Camera} keeps moving after you finish rotating it.\n\t *\n\t * A value of ````0.0```` causes it to immediately stop, ````0.5```` causes its movement to decay 50% on each tick,\n\t * while ````1.0```` causes no decay, allowing it continue moving, by the current rate of rotation.\n\t *\n\t * You may choose an inertia of zero when you want be able to precisely rotate the Camera,\n\t * without interference from inertia. Zero inertia can also mean that less frames are rendered while\n\t * you are rotating the Camera.\n\t *\n\t * Default is ````0.0````.\n\t *\n\t * Does not apply when {@link CameraControl#navMode} is ````\"planView\"````, which disallows rotation.\n\t *\n\t * @param {Number} rotationInertia New inertial factor.\n\t */\n\tset rotationInertia(rotationInertia) {\n\t\tthis._configs.rotationInertia = rotationInertia !== undefined && rotationInertia !== null ? rotationInertia : 0.0;\n\t}\n\n\t/**\n\t * Gets the rotation inertia factor.\n\t *\n\t * Default is ````0.0````.\n\t *\n\t * Does not apply when {@link CameraControl#navMode} is ````\"planView\"````, which disallows rotation.\n\t *\n\t * @returns {Number} The inertia factor.\n\t */\n\tget rotationInertia() {\n\t\treturn this._configs.rotationInertia;\n\t}\n\n\t/**\n\t * Sets how much the {@link Camera} pans each second with keyboard input.\n\t *\n\t * Default is ````5.0````, to pan the Camera ````5.0```` World-space units every second that\n\t * a panning key is depressed. See the ````CameraControl```` class documentation for which keys control\n\t * panning.\n\t *\n\t * Panning direction is aligned to our Camera's orientation. When we pan horizontally, we pan\n\t * to our left and right, when we pan vertically, we pan upwards and downwards, and when we pan forwards\n\t * and backwards, we pan along the direction the Camera is pointing.\n\t *\n\t * Unlike dollying when {@link followPointer} is ````true````, panning does not follow the pointer.\n\t *\n\t * @param {Number} keyboardPanRate The new keyboard pan rate.\n\t */\n\tset keyboardPanRate(keyboardPanRate) {\n\t\tthis._configs.keyboardPanRate = keyboardPanRate !== null && keyboardPanRate !== undefined ? keyboardPanRate : 5.0;\n\t}\n\n\t/**\n\t * Sets how fast the camera pans on touch panning\n\t *\n\t * @param {Number} touchPanRate The new touch pan rate.\n\t */\n\tset touchPanRate(touchPanRate) {\n\t\tthis._configs.touchPanRate = touchPanRate !== null && touchPanRate !== undefined ? touchPanRate : 1.0;\n\t}\n\n\t/**\n\t * Gets how fast the {@link Camera} pans on touch panning\n\t *\n\t * Default is ````1.0````.\n\t *\n\t * @returns {Number} The current touch pan rate.\n\t */\n\tget touchPanRate() {\n\t\treturn this._configs.touchPanRate;\n\t}\n\n\t/**\n\t * Gets how much the {@link Camera} pans each second with keyboard input.\n\t *\n\t * Default is ````5.0````.\n\t *\n\t * @returns {Number} The current keyboard pan rate.\n\t */\n\tget keyboardPanRate() {\n\t\treturn this._configs.keyboardPanRate;\n\t}\n\n\t/**\n\t * Sets how many degrees per second the {@link Camera} rotates/orbits with keyboard input.\n\t *\n\t * Default is ````90.0````, to rotate/orbit the Camera ````90.0```` degrees every second that\n\t * a rotation key is depressed. See the ````CameraControl```` class documentation for which keys control\n\t * rotation/orbit.\n\t *\n\t * @param {Number} keyboardRotationRate The new keyboard rotation rate.\n\t */\n\tset keyboardRotationRate(keyboardRotationRate) {\n\t\tthis._configs.keyboardRotationRate =\n\t\t\tkeyboardRotationRate !== null && keyboardRotationRate !== undefined ? keyboardRotationRate : 90.0;\n\t}\n\n\t/**\n\t * Sets how many degrees per second the {@link Camera} rotates/orbits with keyboard input.\n\t *\n\t * Default is ````90.0````.\n\t *\n\t * @returns {Number} The current keyboard rotation rate.\n\t */\n\tget keyboardRotationRate() {\n\t\treturn this._configs.keyboardRotationRate;\n\t}\n\n\t/**\n\t * Sets the current drag rotation rate.\n\t *\n\t * This configures how many degrees the {@link Camera} rotates/orbits for a full sweep of the canvas by mouse or touch dragging.\n\t *\n\t * For example, a value of ````360.0```` indicates that the ````Camera```` rotates/orbits ````360.0```` degrees horizontally\n\t * when we sweep the entire width of the canvas.\n\t *\n\t * ````CameraControl```` makes vertical rotation half as sensitive as horizontal rotation, so that we don't tend to\n\t * flip upside-down. Therefore, a value of ````360.0```` rotates/orbits the ````Camera```` through ````180.0```` degrees\n\t * vertically when we sweep the entire height of the canvas.\n\t *\n\t * Default is ````360.0````.\n\t *\n\t * @param {Number} dragRotationRate The new drag rotation rate.\n\t */\n\tset dragRotationRate(dragRotationRate) {\n\t\tthis._configs.dragRotationRate =\n\t\t\tdragRotationRate !== null && dragRotationRate !== undefined ? dragRotationRate : 360.0;\n\t}\n\n\t/**\n\t * Gets the current drag rotation rate.\n\t *\n\t * Default is ````360.0````.\n\t *\n\t * @returns {Number} The current drag rotation rate.\n\t */\n\tget dragRotationRate() {\n\t\treturn this._configs.dragRotationRate;\n\t}\n\n\t/**\n\t * Sets how much the {@link Camera} dollys each second with keyboard input.\n\t *\n\t * Default is ````15.0````, to dolly the {@link Camera} ````15.0```` World-space units per second while we hold down\n\t * the ````+```` and ````-```` keys.\n\t *\n\t * @param {Number} keyboardDollyRate The new keyboard dolly rate.\n\t */\n\tset keyboardDollyRate(keyboardDollyRate) {\n\t\tthis._configs.keyboardDollyRate =\n\t\t\tkeyboardDollyRate !== null && keyboardDollyRate !== undefined ? keyboardDollyRate : 15.0;\n\t}\n\n\t/**\n\t * Gets how much the {@link Camera} dollys each second with keyboard input.\n\t *\n\t * Default is ````15.0````.\n\t *\n\t * @returns {Number} The current keyboard dolly rate.\n\t */\n\tget keyboardDollyRate() {\n\t\treturn this._configs.keyboardDollyRate;\n\t}\n\n\t/**\n\t * Sets how much the {@link Camera} dollys with touch input.\n\t *\n\t * Default is ````0.2````\n\t *\n\t * @param {Number} touchDollyRate The new touch dolly rate.\n\t */\n\tset touchDollyRate(touchDollyRate) {\n\t\tthis._configs.touchDollyRate = touchDollyRate !== null && touchDollyRate !== undefined ? touchDollyRate : 0.2;\n\t}\n\n\t/**\n\t * Gets how much the {@link Camera} dollys each second with touch input.\n\t *\n\t * Default is ````0.2````.\n\t *\n\t * @returns {Number} The current touch dolly rate.\n\t */\n\tget touchDollyRate() {\n\t\treturn this._configs.touchDollyRate;\n\t}\n\n\t/**\n\t * Sets how much the {@link Camera} dollys each second while the mouse wheel is spinning.\n\t *\n\t * Default is ````100.0````, to dolly the {@link Camera} ````10.0```` World-space units per second as we spin\n\t * the mouse wheel.\n\t *\n\t * @param {Number} mouseWheelDollyRate The new mouse wheel dolly rate.\n\t */\n\tset mouseWheelDollyRate(mouseWheelDollyRate) {\n\t\tthis._configs.mouseWheelDollyRate =\n\t\t\tmouseWheelDollyRate !== null && mouseWheelDollyRate !== undefined ? mouseWheelDollyRate : 100.0;\n\t}\n\n\t/**\n\t * Gets how much the {@link Camera} dollys each second while the mouse wheel is spinning.\n\t *\n\t * Default is ````100.0````.\n\t *\n\t * @returns {Number} The current mouseWheel dolly rate.\n\t */\n\tget mouseWheelDollyRate() {\n\t\treturn this._configs.mouseWheelDollyRate;\n\t}\n\n\t/**\n\t * Sets the dolly inertia factor.\n\t *\n\t * This factor configures how much the {@link Camera} keeps moving after you finish dollying it.\n\t *\n\t * This factor is a value in range ````[0..1]````. A value of ````0.0```` causes dollying to immediately stop,\n\t * ````0.5```` causes dollying to decay 50% on each animation frame, while ````1.0```` causes no decay, which allows dollying\n\t * to continue until further input stops it.\n\t *\n\t * You might set ````dollyInertia```` to zero when you want be able to precisely position or rotate the Camera,\n\t * without interference from inertia. This also means that xeokit renders less frames while dollying the Camera,\n\t * which can improve rendering performance.\n\t *\n\t * Default is ````0````.\n\t *\n\t * @param {Number} dollyInertia New dolly inertia factor.\n\t */\n\tset dollyInertia(dollyInertia) {\n\t\tthis._configs.dollyInertia = dollyInertia !== undefined && dollyInertia !== null ? dollyInertia : 0;\n\t}\n\n\t/**\n\t * Gets the dolly inertia factor.\n\t *\n\t * Default is ````0````.\n\t *\n\t * @returns {Number} The current dolly inertia factor.\n\t */\n\tget dollyInertia() {\n\t\treturn this._configs.dollyInertia;\n\t}\n\n\t/**\n\t * Sets the proximity to the closest object below which dolly speed decreases, and above which dolly speed increases.\n\t *\n\t * Default is ````35.0````.\n\t *\n\t * @param {Number} dollyProximityThreshold New dolly proximity threshold.\n\t */\n\tset dollyProximityThreshold(dollyProximityThreshold) {\n\t\tthis._configs.dollyProximityThreshold =\n\t\t\tdollyProximityThreshold !== undefined && dollyProximityThreshold !== null ? dollyProximityThreshold : 35.0;\n\t}\n\n\t/**\n\t * Gets the proximity to the closest object below which dolly speed decreases, and above which dolly speed increases.\n\t *\n\t * Default is ````35.0````.\n\t *\n\t * @returns {Number} The current dolly proximity threshold.\n\t */\n\tget dollyProximityThreshold() {\n\t\treturn this._configs.dollyProximityThreshold;\n\t}\n\n\t/**\n\t * Sets the minimum dolly speed.\n\t *\n\t * Default is ````0.04````.\n\t *\n\t * @param {Number} dollyMinSpeed New dolly minimum speed.\n\t */\n\tset dollyMinSpeed(dollyMinSpeed) {\n\t\tthis._configs.dollyMinSpeed = dollyMinSpeed !== undefined && dollyMinSpeed !== null ? dollyMinSpeed : 0.04;\n\t}\n\n\t/**\n\t * Gets the minimum dolly speed.\n\t *\n\t * Default is ````0.04````.\n\t *\n\t * @returns {Number} The current minimum dolly speed.\n\t */\n\tget dollyMinSpeed() {\n\t\treturn this._configs.dollyMinSpeed;\n\t}\n\n\t/**\n\t * Sets the pan inertia factor.\n\t *\n\t * This factor configures how much the {@link Camera} keeps moving after you finish panning it.\n\t *\n\t * This factor is a value in range ````[0..1]````. A value of ````0.0```` causes panning to immediately stop,\n\t * ````0.5```` causes panning to decay 50% on each animation frame, while ````1.0```` causes no decay, which allows panning\n\t * to continue until further input stops it.\n\t *\n\t * You might set ````panInertia```` to zero when you want be able to precisely position or rotate the Camera,\n\t * without interference from inertia. This also means that xeokit renders less frames while panning the Camera,\n\t * wich can improve rendering performance.\n\t *\n\t * Default is ````0.5````.\n\t *\n\t * @param {Number} panInertia New pan inertia factor.\n\t */\n\tset panInertia(panInertia) {\n\t\tthis._configs.panInertia = panInertia !== undefined && panInertia !== null ? panInertia : 0.5;\n\t}\n\n\t/**\n\t * Gets the pan inertia factor.\n\t *\n\t * Default is ````0.5````.\n\t *\n\t * @returns {Number} The current pan inertia factor.\n\t */\n\tget panInertia() {\n\t\treturn this._configs.panInertia;\n\t}\n\n\t/**\n\t * Sets the keyboard layout.\n\t *\n\t * Supported layouts are:\n\t *\n\t * * ````\"qwerty\"```` (default)\n\t * * ````\"azerty\"````\n\t *\n\t * @deprecated\n\t * @param {String} value Selects the keyboard layout.\n\t */\n\tset keyboardLayout(value) {\n\t\t// this.warn(\"keyboardLayout property is deprecated - use keyMap property instead\");\n\t\tvalue = value || \"qwerty\";\n\t\tif (value !== \"qwerty\" && value !== \"azerty\") {\n\t\t\tthis.error(\"Unsupported value for keyboardLayout - defaulting to 'qwerty'\");\n\t\t\tvalue = \"qwerty\";\n\t\t}\n\t\tthis._configs.keyboardLayout = value;\n\t\tthis.keyMap = this._configs.keyboardLayout;\n\t}\n\n\t/**\n\t * Gets the keyboard layout.\n\t *\n\t * Supported layouts are:\n\t *\n\t * * ````\"qwerty\"```` (default)\n\t * * ````\"azerty\"````\n\t *\n\t * @deprecated\n\t * @returns {String} The current keyboard layout.\n\t */\n\tget keyboardLayout() {\n\t\treturn this._configs.keyboardLayout;\n\t}\n\n\t/**\n\t * Sets a sphere as the representation of the pivot position.\n\t *\n\t * @param {Object} [cfg] Sphere configuration.\n\t * @param {String} [cfg.size=1] Optional size factor of the sphere. Defaults to 1.\n\t * @param {String} [cfg.material=PhongMaterial] Optional size factor of the sphere. Defaults to a red opaque material.\n\t */\n\tenablePivotSphere(cfg = {}) {\n\t\tthis._controllers.pivotController.enablePivotSphere(cfg);\n\t}\n\n\t/**\n\t * Remove the sphere as the representation of the pivot position.\n\t *\n\t */\n\tdisablePivotSphere() {\n\t\tthis._controllers.pivotController.disablePivotSphere();\n\t}\n\n\t/**\n\t * Sets whether smart default pivoting is enabled.\n\t *\n\t * When ````true````, we'll pivot by default about the 3D position of the mouse/touch pointer on an\n\t * imaginary sphere that's centered at {@link Camera#eye} and sized to the {@link Scene} boundary.\n\t *\n\t * When ````false````, we'll pivot by default about {@link Camera#look}.\n\t *\n\t * Default is ````false````.\n\t *\n\t * @param {Boolean} enabled Set ````true```` to pivot by default about the selected point on the virtual sphere, or ````false```` to pivot by default about {@link Camera#look}.\n\t */\n\tset smartPivot(enabled) {\n\t\tthis._configs.smartPivot = enabled !== false;\n\t}\n\n\t/**\n\t * Gets whether smart default pivoting is enabled.\n\t *\n\t * When ````true````, we'll pivot by default about the 3D position of the mouse/touch pointer on an\n\t * imaginary sphere that's centered at {@link Camera#eye} and sized to the {@link Scene} boundary.\n\t *\n\t * When ````false````, we'll pivot by default about {@link Camera#look}.\n\t *\n\t * Default is ````false````.\n\t *\n\t * @returns {Boolean} Returns ````true```` when pivoting by default about the selected point on the virtual sphere, or ````false```` when pivoting by default about {@link Camera#look}.\n\t */\n\tget smartPivot() {\n\t\treturn this._configs.smartPivot;\n\t}\n\n\t/**\n\t * Sets the double click time frame length in milliseconds.\n\t *\n\t * If two mouse click events occur within this time frame, it is considered a double click.\n\t *\n\t * Default is ````250````\n\t *\n\t * @param {Number} value New double click time frame.\n\t */\n\tset doubleClickTimeFrame(value) {\n\t\tthis._configs.doubleClickTimeFrame = value !== undefined && value !== null ? value : 250;\n\t}\n\n\t/**\n\t * Gets the double click time frame length in milliseconds.\n\t *\n\t * Default is ````250````\n\t *\n\t * @param {Number} value Current double click time frame.\n\t */\n\tget doubleClickTimeFrame() {\n\t\treturn this._configs.doubleClickTimeFrame;\n\t}\n\n\t/**\n\t * Destroys this ````CameraControl````.\n\t * @private\n\t */\n\tdestroy() {\n\t\tthis._destroyHandlers();\n\t\tthis._destroyControllers();\n\t\tthis._cameraUpdater.destroy();\n\t\tsuper.destroy();\n\t}\n\n\t_destroyHandlers() {\n\t\tfor (let i = 0, len = this._handlers.length; i < len; i++) {\n\t\t\tconst handler = this._handlers[i];\n\t\t\tif (handler.destroy) {\n\t\t\t\thandler.destroy();\n\t\t\t}\n\t\t}\n\t}\n\n\t_destroyControllers() {\n\t\tfor (let i = 0, len = this._controllers.length; i < len; i++) {\n\t\t\tconst controller = this._controllers[i];\n\t\t\tif (controller.destroy) {\n\t\t\t\tcontroller.destroy();\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/CameraControl/CameraControl.js?");
2478
2488
 
2479
2489
  /***/ }),
2480
2490
 
@@ -2514,7 +2524,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2514
2524
  \***************************************************************************/
2515
2525
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2516
2526
 
2517
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ PivotController: () => (/* binding */ PivotController)\n/* harmony export */ });\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _geometry_VBOGeometry_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../geometry/VBOGeometry.js */ \"./src/viewer/scene/geometry/VBOGeometry.js\");\n/* harmony import */ var _geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../geometry/builders/buildSphereGeometry.js */ \"./src/viewer/scene/geometry/builders/buildSphereGeometry.js\");\n/* harmony import */ var _math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst tempVec3a = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\nconst tempVec3b = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\nconst tempVec3c = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\nconst tempVec4a = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\nconst tempVec4b = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\nconst tempVec4c = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\n\r\n/** @private */\r\nclass PivotController {\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tconstructor(scene, configs) {\r\n\t\t// Pivot math by: http://www.derschmale.com/\r\n\r\n\t\tthis._scene = scene;\r\n\t\tthis._configs = configs;\r\n\t\tthis._pivotWorldPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\tthis._cameraOffset = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\tthis._azimuth = 0;\r\n\t\tthis._polar = 0;\r\n\t\tthis._radius = 0;\r\n\t\tthis._pivotPosSet = false; // Initially false, true as soon as _pivotWorldPos has been set to some value\r\n\t\tthis._pivoting = false; // True while pivoting\r\n\t\tthis._shown = false;\r\n\r\n\t\tthis._pivotSphereEnabled = false;\r\n\t\tthis._pivotSphere = null;\r\n\t\tthis._pivotSphereSize = 1;\r\n\t\tthis._pivotSphereGeometry = null;\r\n\t\tthis._pivotSphereMaterial = null;\r\n\t\tthis._rtcCenter = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\tthis._rtcPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n\t\tthis._pivotViewPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\n\t\tthis._pivotProjPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\n\t\tthis._pivotCanvasPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec2();\r\n\t\tthis._cameraDirty = true;\r\n\r\n\t\tthis._onViewMatrix = this._scene.camera.on(\"viewMatrix\", () => {\r\n\t\t\tthis._cameraDirty = true;\r\n\t\t});\r\n\r\n\t\tthis._onProjMatrix = this._scene.camera.on(\"projMatrix\", () => {\r\n\t\t\tthis._cameraDirty = true;\r\n\t\t});\r\n\r\n\t\tthis._onTick = this._scene.on(\"tick\", () => {\r\n\t\t\tthis.updatePivotElement();\r\n\t\t\tthis.updatePivotSphere();\r\n\t\t});\r\n\t}\r\n\r\n\tcreatePivotSphere() {\r\n\t\tconst currentPos = this.getPivotPos();\r\n\t\tconst cameraPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.decomposeMat4(\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(this._scene.viewer.camera.viewMatrix, _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4()),\r\n\t\t\tcameraPos,\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4(),\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3()\r\n\t\t);\r\n\t\tconst length = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.distVec3(cameraPos, currentPos);\r\n\t\tlet radius = Math.tan(Math.PI / 500) * length * this._pivotSphereSize;\r\n\r\n\t\tif (this._scene.camera.projection == \"ortho\") {\r\n\t\t\tradius /= this._scene.camera.ortho.scale / 2;\r\n\t\t}\r\n\r\n\t\t(0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__.worldToRTCPos)(currentPos, this._rtcCenter, this._rtcPos);\r\n\t\tthis._pivotSphereGeometry = new _geometry_VBOGeometry_js__WEBPACK_IMPORTED_MODULE_3__.VBOGeometry(this._scene, (0,_geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_4__.buildSphereGeometry)({ radius }));\r\n\t\tthis._pivotSphere = new _mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_2__.Mesh(this._scene, {\r\n\t\t\tgeometry: this._pivotSphereGeometry,\r\n\t\t\tmaterial: this._pivotSphereMaterial,\r\n\t\t\tpickable: false,\r\n\t\t\tposition: this._rtcPos,\r\n\t\t\trtcCenter: this._rtcCenter\r\n\t\t});\r\n\t}\r\n\r\n\tdestroyPivotSphere() {\r\n\t\tif (this._pivotSphere) {\r\n\t\t\tthis._pivotSphere.destroy();\r\n\t\t\tthis._pivotSphere = null;\r\n\t\t}\r\n\t\tif (this._pivotSphereGeometry) {\r\n\t\t\tthis._pivotSphereGeometry.destroy();\r\n\t\t\tthis._pivotSphereGeometry = null;\r\n\t\t}\r\n\t}\r\n\r\n\tupdatePivotElement() {\r\n\t\tconst camera = this._scene.camera;\r\n\t\tconst canvas = this._scene.canvas;\r\n\r\n\t\tif (this._pivoting && this._cameraDirty) {\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint3(camera.viewMatrix, this.getPivotPos(), this._pivotViewPos);\r\n\t\t\tthis._pivotViewPos[3] = 1;\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint4(camera.projMatrix, this._pivotViewPos, this._pivotProjPos);\r\n\r\n\t\t\tconst canvasAABB = canvas.boundary;\r\n\t\t\tconst canvasWidth = canvasAABB[2];\r\n\t\t\tconst canvasHeight = canvasAABB[3];\r\n\r\n\t\t\tthis._pivotCanvasPos[0] = Math.floor(((1 + this._pivotProjPos[0] / this._pivotProjPos[3]) * canvasWidth) / 2);\r\n\t\t\tthis._pivotCanvasPos[1] = Math.floor(((1 - this._pivotProjPos[1] / this._pivotProjPos[3]) * canvasHeight) / 2);\r\n\r\n\t\t\t// data-textures: avoid to do continuous DOM layout calculations\r\n\t\t\tlet canvasBoundingRect = canvas._lastBoundingClientRect;\r\n\r\n\t\t\tconst canvasElem = canvas.canvas;\r\n\r\n\t\t\tcanvasBoundingRect = canvas._lastBoundingClientRect = canvasElem.getBoundingClientRect();\r\n\r\n\t\t\tif (this._pivotElement) {\r\n\t\t\t\tthis._pivotElement.style.left =\r\n\t\t\t\t\tMath.floor(canvasBoundingRect.left + this._pivotCanvasPos[0]) -\r\n\t\t\t\t\tthis._pivotElement.clientWidth / 2 +\r\n\t\t\t\t\twindow.scrollX +\r\n\t\t\t\t\t\"px\";\r\n\t\t\t\tthis._pivotElement.style.top =\r\n\t\t\t\t\tMath.floor(canvasBoundingRect.top + this._pivotCanvasPos[1]) -\r\n\t\t\t\t\tthis._pivotElement.clientHeight / 2 +\r\n\t\t\t\t\twindow.scrollY +\r\n\t\t\t\t\t\"px\";\r\n\t\t\t}\r\n\t\t\tthis._cameraDirty = false;\r\n\t\t}\r\n\t}\r\n\r\n\tupdatePivotSphere() {\r\n\t\tif (this._pivoting && this._pivotSphere) {\r\n\t\t\t(0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__.worldToRTCPos)(this.getPivotPos(), this._rtcCenter, this._rtcPos);\r\n\t\t\tif (!_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.compareVec3(this._rtcPos, this._pivotSphere.position)) {\r\n\t\t\t\tthis.destroyPivotSphere();\r\n\t\t\t\tthis.createPivotSphere();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t/**\r\n\t * Sets the HTML DOM element that will represent the pivot position.\r\n\t *\r\n\t * @param pivotElement\r\n\t */\r\n\tsetPivotElement(pivotElement) {\r\n\t\tthis._pivotElement = pivotElement;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a sphere as the representation of the pivot position.\r\n\t *\r\n\t * @param {Object} [cfg] Sphere configuration.\r\n\t * @param {String} [cfg.size=1] Optional size factor of the sphere. Defaults to 1.\r\n\t * @param {String} [cfg.color=Array] Optional maretial color. Defaults to a red.\r\n\t */\r\n\tenablePivotSphere(cfg = {}) {\r\n\t\tthis.destroyPivotSphere();\r\n\t\tthis._pivotSphereEnabled = true;\r\n\t\tif (cfg.size) {\r\n\t\t\tthis._pivotSphereSize = cfg.size;\r\n\t\t}\r\n\t\tconst color = cfg.color || [1, 0, 0];\r\n\t\tthis._pivotSphereMaterial = new _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_1__.PhongMaterial(this._scene, {\r\n\t\t\temissive: color,\r\n\t\t\tambient: color,\r\n\t\t\tspecular: [0, 0, 0],\r\n\t\t\tdiffuse: [0, 0, 0]\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Remove the sphere as the representation of the pivot position.\r\n\t *\r\n\t */\r\n\tdisablePivotSphere() {\r\n\t\tthis.destroyPivotSphere();\r\n\t\tthis._pivotSphereEnabled = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Begins pivoting.\r\n\t */\r\n\tstartPivot() {\r\n\t\tif (this._cameraLookingDownwards()) {\r\n\t\t\tthis._pivoting = false;\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tconst camera = this._scene.camera;\r\n\r\n\t\tlet lookat = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lookAtMat4v(camera.eye, camera.look, camera.worldUp);\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint3(lookat, this.getPivotPos(), this._cameraOffset);\r\n\r\n\t\tconst pivotPos = this.getPivotPos();\r\n\t\tthis._cameraOffset[2] += _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.distVec3(camera.eye, pivotPos);\r\n\r\n\t\tlookat = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(lookat);\r\n\r\n\t\tconst offset = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(lookat, this._cameraOffset);\r\n\t\tconst diff = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, pivotPos, diff);\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(diff, offset);\r\n\r\n\t\tif (camera.zUp) {\r\n\t\t\tconst t = diff[1];\r\n\t\t\tdiff[1] = diff[2];\r\n\t\t\tdiff[2] = t;\r\n\t\t}\r\n\r\n\t\tthis._radius = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(diff);\r\n\t\tthis._polar = Math.acos(diff[1] / this._radius);\r\n\t\tthis._azimuth = Math.atan2(diff[0], diff[2]);\r\n\t\tthis._pivoting = true;\r\n\t}\r\n\r\n\t_cameraLookingDownwards() {\r\n\t\t// Returns true if angle between camera viewing direction and World-space \"up\" axis is too small\r\n\t\tconst camera = this._scene.camera;\r\n\t\tconst forwardAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.look, camera.eye, tempVec3a));\r\n\t\tconst rightAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(forwardAxis, camera.worldUp, tempVec3b);\r\n\t\tlet rightAxisLen = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.sqLenVec3(rightAxis);\r\n\t\treturn rightAxisLen <= 0.0001;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns true if we are currently pivoting.\r\n\t *\r\n\t * @returns {Boolean}\r\n\t */\r\n\tgetPivoting() {\r\n\t\treturn this._pivoting;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a 3D World-space position to pivot about.\r\n\t *\r\n\t * @param {Number[]} worldPos The new World-space pivot position.\r\n\t */\r\n\tsetPivotPos(worldPos) {\r\n\t\tif (!!this._pivotWorldPos) this._pivotWorldPos.set(worldPos);\r\n\t\tthis._pivotPosSet = true;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the pivot position to the 3D projection of the given 2D canvas coordinates on a sphere centered\r\n\t * at the viewpoint. The radius of the sphere is configured via {@link CameraControl#smartPivot}.\r\n\t *\r\n\t *\r\n\t * @param canvasPos\r\n\t */\r\n\tsetCanvasPivotPos(canvasPos) {\r\n\t\tconst camera = this._scene.camera;\r\n\t\tconst pivotShereRadius = Math.abs(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.distVec3(this._scene.center, camera.eye));\r\n\t\tconst transposedProjectMat = camera.project.transposedMatrix;\r\n\t\tconst Pt3 = transposedProjectMat.subarray(8, 12);\r\n\t\tconst Pt4 = transposedProjectMat.subarray(12);\r\n\t\tconst D = [0, 0, -1.0, 1];\r\n\t\tconst screenZ = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec4(D, Pt3) / _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec4(D, Pt4);\r\n\t\tconst worldPos = tempVec4a;\r\n\t\tcamera.project.unproject(canvasPos, screenZ, tempVec4b, tempVec4c, worldPos);\r\n\t\tconst eyeWorldPosVec = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(worldPos, camera.eye, tempVec3a));\r\n\t\tconst posOnSphere = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(\r\n\t\t\tcamera.eye,\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(eyeWorldPosVec, pivotShereRadius, tempVec3b),\r\n\t\t\ttempVec3c\r\n\t\t);\r\n\t\tthis.setPivotPos(posOnSphere);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current position we're pivoting about.\r\n\t * @returns {Number[]} The current World-space pivot position.\r\n\t */\r\n\tgetPivotPos() {\r\n\t\treturn this._pivotPosSet ? this._pivotWorldPos : this._scene.camera.look; // Avoid pivoting about [0,0,0] by default\r\n\t}\r\n\r\n\t/**\r\n\t * Continues to pivot.\r\n\t *\r\n\t * @param {Number} yawInc Yaw rotation increment.\r\n\t * @param {Number} pitchInc Pitch rotation increment.\r\n\t */\r\n\tcontinuePivot(yawInc, pitchInc) {\r\n\t\tif (!this._pivoting) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (yawInc === 0 && pitchInc === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst camera = this._scene.camera;\r\n\t\tvar dx = -yawInc;\r\n\t\tconst dy = -pitchInc;\r\n\t\tif (camera.worldUp[2] === 1) {\r\n\t\t\tdx = -dx;\r\n\t\t}\r\n\t\tthis._azimuth += -dx * 0.01;\r\n\t\tthis._polar += dy * 0.01;\r\n\t\tthis._polar = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.clamp(this._polar, 0.001, Math.PI - 0.001);\r\n\t\tconst pos = [\r\n\t\t\tthis._radius * Math.sin(this._polar) * Math.sin(this._azimuth),\r\n\t\t\tthis._radius * Math.cos(this._polar),\r\n\t\t\tthis._radius * Math.sin(this._polar) * Math.cos(this._azimuth)\r\n\t\t];\r\n\t\tif (camera.worldUp[2] === 1) {\r\n\t\t\tconst t = pos[1];\r\n\t\t\tpos[1] = pos[2];\r\n\t\t\tpos[2] = t;\r\n\t\t}\r\n\t\t// Preserve the eye->look distance, since in xeokit \"look\" is the point-of-interest, not the direction vector.\r\n\t\tconst eyeLookLen = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.look, camera.eye, _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3()));\r\n\t\tconst pivotPos = this.getPivotPos();\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(pos, pivotPos);\r\n\t\tlet lookat = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lookAtMat4v(pos, pivotPos, camera.worldUp);\r\n\t\tlookat = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(lookat);\r\n\t\tconst offset = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(lookat, this._cameraOffset);\r\n\t\tlookat[12] -= offset[0];\r\n\t\tlookat[13] -= offset[1];\r\n\t\tlookat[14] -= offset[2];\r\n\t\tconst zAxis = [lookat[8], lookat[9], lookat[10]];\r\n\t\tcamera.eye = [lookat[12], lookat[13], lookat[14]];\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(zAxis, eyeLookLen), camera.look);\r\n\t\tcamera.up = [lookat[4], lookat[5], lookat[6]];\r\n\t\tthis.showPivot();\r\n\t}\r\n\r\n\t/**\r\n\t * Shows the pivot position.\r\n\t *\r\n\t * Only works if we set an HTML DOM element to represent the pivot position.\r\n\t */\r\n\tshowPivot() {\r\n\t\tif (this._shown) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (this._pivotElement) {\r\n\t\t\tthis.updatePivotElement();\r\n\t\t\tthis._pivotElement.style.visibility = \"visible\";\r\n\t\t}\r\n\t\tif (this._pivotSphereEnabled) {\r\n\t\t\tthis.destroyPivotSphere();\r\n\t\t\tthis.createPivotSphere();\r\n\t\t}\r\n\t\tthis._shown = true;\r\n\t}\r\n\r\n\t/**\r\n\t * Hides the pivot position.\r\n\t *\r\n\t * Only works if we set an HTML DOM element to represent the pivot position.\r\n\t */\r\n\thidePivot() {\r\n\t\tif (!this._shown) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (this._pivotElement) {\r\n\t\t\tthis._pivotElement.style.visibility = \"hidden\";\r\n\t\t}\r\n\t\tif (this._pivotSphereEnabled) {\r\n\t\t\tthis.destroyPivotSphere();\r\n\t\t}\r\n\t\tthis._shown = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Finishes pivoting.\r\n\t */\r\n\tendPivot() {\r\n\t\tthis._pivoting = false;\r\n\t}\r\n\r\n\tdestroy() {\r\n\t\tif (this._pivotElement) {\r\n\t\t\tthis._pivotElement.parentNode.removeChild(this._pivotElement);\r\n\t\t}\r\n\t\tthis.destroyPivotSphere();\r\n\t\tthis._scene.camera.off(this._onViewMatrix);\r\n\t\tthis._scene.camera.off(this._onProjMatrix);\r\n\t\tthis._scene.off(this._onTick);\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/CameraControl/lib/controllers/PivotController.js?");
2527
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ PivotController: () => (/* binding */ PivotController)\n/* harmony export */ });\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _geometry_VBOGeometry_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../geometry/VBOGeometry.js */ \"./src/viewer/scene/geometry/VBOGeometry.js\");\n/* harmony import */ var _geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../geometry/builders/buildSphereGeometry.js */ \"./src/viewer/scene/geometry/builders/buildSphereGeometry.js\");\n/* harmony import */ var _math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst tempVec3a = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\nconst tempVec3b = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\nconst tempVec3c = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\nconst tempVec4a = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\nconst tempVec4b = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\nconst tempVec4c = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\n\r\n/** @private */\r\nclass PivotController {\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tconstructor(scene, configs) {\r\n\t\t// Pivot math by: http://www.derschmale.com/\r\n\r\n\t\tthis._scene = scene;\r\n\t\tthis._configs = configs;\r\n\t\tthis._pivotWorldPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\tthis._cameraOffset = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\tthis._azimuth = 0;\r\n\t\tthis._polar = 0;\r\n\t\tthis._radius = 0;\r\n\t\tthis._pivotPosSet = false; // Initially false, true as soon as _pivotWorldPos has been set to some value\r\n\t\tthis._pivoting = false; // True while pivoting\r\n\t\tthis._shown = false;\r\n\r\n\t\tthis._pivotSphereEnabled = false;\r\n\t\tthis._pivotSphere = null;\r\n\t\tthis._pivotSphereSize = 1;\r\n\t\tthis._pivotSphereGeometry = null;\r\n\t\tthis._pivotSphereMaterial = null;\r\n\t\tthis._rtcCenter = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\tthis._rtcPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n\t\tthis._pivotViewPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\n\t\tthis._pivotProjPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\n\t\tthis._pivotCanvasPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec2();\r\n\t\tthis._cameraDirty = true;\r\n\r\n\t\tthis._onViewMatrix = this._scene.camera.on(\"viewMatrix\", () => {\r\n\t\t\tthis._cameraDirty = true;\r\n\t\t});\r\n\r\n\t\tthis._onProjMatrix = this._scene.camera.on(\"projMatrix\", () => {\r\n\t\t\tthis._cameraDirty = true;\r\n\t\t});\r\n\r\n\t\tthis._onTick = this._scene.on(\"tick\", () => {\r\n\t\t\tthis.updatePivotElement();\r\n\t\t\tthis.updatePivotSphere();\r\n\t\t});\r\n\t}\r\n\r\n\tcreatePivotSphere() {\r\n\t\tconst currentPos = this.getPivotPos();\r\n\t\tconst cameraPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.decomposeMat4(\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(this._scene.viewer.camera.viewMatrix, _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4()),\r\n\t\t\tcameraPos,\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4(),\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3()\r\n\t\t);\r\n\t\tconst length = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.distVec3(cameraPos, currentPos);\r\n\t\tlet radius = Math.tan(Math.PI / 500) * length * this._pivotSphereSize;\r\n\r\n\t\tif (this._scene.camera.projection == \"ortho\") {\r\n\t\t\tradius /= this._scene.camera.ortho.scale / 2;\r\n\t\t}\r\n\r\n\t\t(0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__.worldToRTCPos)(currentPos, this._rtcCenter, this._rtcPos);\r\n\t\tthis._pivotSphereGeometry = new _geometry_VBOGeometry_js__WEBPACK_IMPORTED_MODULE_3__.VBOGeometry(this._scene, (0,_geometry_builders_buildSphereGeometry_js__WEBPACK_IMPORTED_MODULE_4__.buildSphereGeometry)({ radius }));\r\n\t\tthis._pivotSphere = new _mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_2__.Mesh(this._scene, {\r\n\t\t\tgeometry: this._pivotSphereGeometry,\r\n\t\t\tmaterial: this._pivotSphereMaterial,\r\n\t\t\tpickable: false,\r\n\t\t\tposition: this._rtcPos,\r\n\t\t\trtcCenter: this._rtcCenter\r\n\t\t});\r\n\t}\r\n\r\n\tdestroyPivotSphere() {\r\n\t\tif (this._pivotSphere) {\r\n\t\t\tthis._pivotSphere.destroy();\r\n\t\t\tthis._pivotSphere = null;\r\n\t\t}\r\n\t\tif (this._pivotSphereGeometry) {\r\n\t\t\tthis._pivotSphereGeometry.destroy();\r\n\t\t\tthis._pivotSphereGeometry = null;\r\n\t\t}\r\n\t}\r\n\r\n\tgetPointScreenPos(pos) {\r\n\t\tconst camera = this._scene.camera;\r\n\t\tconst canvas = this._scene.canvas;\r\n\r\n\t\tconst canvasAABB = canvas.boundary;\r\n\t\tconst canvasWidth = canvasAABB[2];\r\n\t\tconst canvasHeight = canvasAABB[3];\r\n\r\n\t\tconst pos11 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\n\t\tconst pos22 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec4();\r\n\t\tconst screenPos = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec2();\r\n\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint3(camera.viewMatrix, pos, pos11);\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint4(camera.projMatrix, pos, pos22);\r\n\t\tscreenPos[0] = Math.floor(((1 + pos22[0] / pos22[3]) * canvasWidth) / 2);\r\n\t\tscreenPos[1] = Math.floor(((1 - pos22[1] / pos22[3]) * canvasHeight) / 2);\r\n\r\n\t\treturn screenPos;\r\n\t}\r\n\r\n\tupdatePivotElement() {\r\n\t\tconst camera = this._scene.camera;\r\n\t\tconst canvas = this._scene.canvas;\r\n\r\n\t\tif (this._pivoting && this._cameraDirty) {\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint3(camera.viewMatrix, this.getPivotPos(), this._pivotViewPos);\r\n\t\t\tthis._pivotViewPos[3] = 1;\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint4(camera.projMatrix, this._pivotViewPos, this._pivotProjPos);\r\n\r\n\t\t\tconst canvasAABB = canvas.boundary;\r\n\t\t\tconst canvasWidth = canvasAABB[2];\r\n\t\t\tconst canvasHeight = canvasAABB[3];\r\n\r\n\t\t\tthis._pivotCanvasPos[0] = Math.floor(((1 + this._pivotProjPos[0] / this._pivotProjPos[3]) * canvasWidth) / 2);\r\n\t\t\tthis._pivotCanvasPos[1] = Math.floor(((1 - this._pivotProjPos[1] / this._pivotProjPos[3]) * canvasHeight) / 2);\r\n\r\n\t\t\t// data-textures: avoid to do continuous DOM layout calculations\r\n\t\t\tlet canvasBoundingRect = canvas._lastBoundingClientRect;\r\n\r\n\t\t\tconst canvasElem = canvas.canvas;\r\n\r\n\t\t\tcanvasBoundingRect = canvas._lastBoundingClientRect = canvasElem.getBoundingClientRect();\r\n\r\n\t\t\tif (this._pivotElement) {\r\n\t\t\t\tthis._pivotElement.style.left =\r\n\t\t\t\t\tMath.floor(canvasBoundingRect.left + this._pivotCanvasPos[0]) -\r\n\t\t\t\t\tthis._pivotElement.clientWidth / 2 +\r\n\t\t\t\t\twindow.scrollX +\r\n\t\t\t\t\t\"px\";\r\n\t\t\t\tthis._pivotElement.style.top =\r\n\t\t\t\t\tMath.floor(canvasBoundingRect.top + this._pivotCanvasPos[1]) -\r\n\t\t\t\t\tthis._pivotElement.clientHeight / 2 +\r\n\t\t\t\t\twindow.scrollY +\r\n\t\t\t\t\t\"px\";\r\n\t\t\t}\r\n\t\t\tthis._cameraDirty = false;\r\n\t\t}\r\n\t}\r\n\r\n\tupdatePivotSphere() {\r\n\t\tif (this._pivoting && this._pivotSphere) {\r\n\t\t\t(0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_5__.worldToRTCPos)(this.getPivotPos(), this._rtcCenter, this._rtcPos);\r\n\t\t\tif (!_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.compareVec3(this._rtcPos, this._pivotSphere.position)) {\r\n\t\t\t\tthis.destroyPivotSphere();\r\n\t\t\t\tthis.createPivotSphere();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t/**\r\n\t * Sets the HTML DOM element that will represent the pivot position.\r\n\t *\r\n\t * @param pivotElement\r\n\t */\r\n\tsetPivotElement(pivotElement) {\r\n\t\tthis._pivotElement = pivotElement;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a sphere as the representation of the pivot position.\r\n\t *\r\n\t * @param {Object} [cfg] Sphere configuration.\r\n\t * @param {String} [cfg.size=1] Optional size factor of the sphere. Defaults to 1.\r\n\t * @param {String} [cfg.color=Array] Optional maretial color. Defaults to a red.\r\n\t */\r\n\tenablePivotSphere(cfg = {}) {\r\n\t\tthis.destroyPivotSphere();\r\n\t\tthis._pivotSphereEnabled = true;\r\n\t\tif (cfg.size) {\r\n\t\t\tthis._pivotSphereSize = cfg.size;\r\n\t\t}\r\n\t\tconst color = cfg.color || [1, 0, 0];\r\n\t\tthis._pivotSphereMaterial = new _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_1__.PhongMaterial(this._scene, {\r\n\t\t\temissive: color,\r\n\t\t\tambient: color,\r\n\t\t\tspecular: [0, 0, 0],\r\n\t\t\tdiffuse: [0, 0, 0]\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Remove the sphere as the representation of the pivot position.\r\n\t *\r\n\t */\r\n\tdisablePivotSphere() {\r\n\t\tthis.destroyPivotSphere();\r\n\t\tthis._pivotSphereEnabled = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Begins pivoting.\r\n\t */\r\n\tstartPivot() {\r\n\t\tif (this._cameraLookingDownwards()) {\r\n\t\t\tthis._pivoting = false;\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tconst camera = this._scene.camera;\r\n\r\n\t\tlet lookat = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lookAtMat4v(camera.eye, camera.look, camera.worldUp);\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformPoint3(lookat, this.getPivotPos(), this._cameraOffset);\r\n\r\n\t\tconst pivotPos = this.getPivotPos();\r\n\t\tthis._cameraOffset[2] += _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.distVec3(camera.eye, pivotPos);\r\n\r\n\t\tlookat = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(lookat);\r\n\r\n\t\tconst offset = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(lookat, this._cameraOffset);\r\n\t\tconst diff = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, pivotPos, diff);\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(diff, offset);\r\n\r\n\t\tif (camera.zUp) {\r\n\t\t\tconst t = diff[1];\r\n\t\t\tdiff[1] = diff[2];\r\n\t\t\tdiff[2] = t;\r\n\t\t}\r\n\r\n\t\tthis._radius = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(diff);\r\n\t\tthis._polar = Math.acos(diff[1] / this._radius);\r\n\t\tthis._azimuth = Math.atan2(diff[0], diff[2]);\r\n\t\tthis._pivoting = true;\r\n\t}\r\n\r\n\t_cameraLookingDownwards() {\r\n\t\t// Returns true if angle between camera viewing direction and World-space \"up\" axis is too small\r\n\t\tconst camera = this._scene.camera;\r\n\t\tconst forwardAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.look, camera.eye, tempVec3a));\r\n\t\tconst rightAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.cross3Vec3(forwardAxis, camera.worldUp, tempVec3b);\r\n\t\tlet rightAxisLen = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.sqLenVec3(rightAxis);\r\n\t\treturn rightAxisLen <= 0.0001;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns true if we are currently pivoting.\r\n\t *\r\n\t * @returns {Boolean}\r\n\t */\r\n\tgetPivoting() {\r\n\t\treturn this._pivoting;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a 3D World-space position to pivot about.\r\n\t *\r\n\t * @param {Number[]} worldPos The new World-space pivot position.\r\n\t */\r\n\tsetPivotPos(worldPos) {\r\n\t\tif (!!this._pivotWorldPos) this._pivotWorldPos.set(worldPos);\r\n\t\tthis._pivotPosSet = true;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the pivot position to the 3D projection of the given 2D canvas coordinates on a sphere centered\r\n\t * at the viewpoint. The radius of the sphere is configured via {@link CameraControl#smartPivot}.\r\n\t *\r\n\t *\r\n\t * @param canvasPos\r\n\t */\r\n\tsetCanvasPivotPos(canvasPos) {\r\n\t\tconst camera = this._scene.camera;\r\n\t\tconst pivotShereRadius = Math.abs(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.distVec3(this._scene.center, camera.eye));\r\n\t\tconst transposedProjectMat = camera.project.transposedMatrix;\r\n\t\tconst Pt3 = transposedProjectMat.subarray(8, 12);\r\n\t\tconst Pt4 = transposedProjectMat.subarray(12);\r\n\t\tconst D = [0, 0, -1.0, 1];\r\n\t\tconst screenZ = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec4(D, Pt3) / _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.dotVec4(D, Pt4);\r\n\t\tconst worldPos = tempVec4a;\r\n\t\tcamera.project.unproject(canvasPos, screenZ, tempVec4b, tempVec4c, worldPos);\r\n\t\tconst eyeWorldPosVec = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(worldPos, camera.eye, tempVec3a));\r\n\t\tconst posOnSphere = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(\r\n\t\t\tcamera.eye,\r\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(eyeWorldPosVec, pivotShereRadius, tempVec3b),\r\n\t\t\ttempVec3c\r\n\t\t);\r\n\t\tthis.setPivotPos(posOnSphere);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current position we're pivoting about.\r\n\t * @returns {Number[]} The current World-space pivot position.\r\n\t */\r\n\tgetPivotPos() {\r\n\t\treturn this._pivotPosSet ? this._pivotWorldPos : this._scene.camera.look; // Avoid pivoting about [0,0,0] by default\r\n\t}\r\n\r\n\t/**\r\n\t * Continues to pivot.\r\n\t *\r\n\t * @param {Number} yawInc Yaw rotation increment.\r\n\t * @param {Number} pitchInc Pitch rotation increment.\r\n\t */\r\n\tcontinuePivot(yawInc, pitchInc) {\r\n\t\tif (!this._pivoting) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (yawInc === 0 && pitchInc === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst camera = this._scene.camera;\r\n\t\tvar dx = -yawInc;\r\n\t\tconst dy = -pitchInc;\r\n\t\tif (camera.worldUp[2] === 1) {\r\n\t\t\tdx = -dx;\r\n\t\t}\r\n\t\tthis._azimuth += -dx * 0.01;\r\n\t\tthis._polar += dy * 0.01;\r\n\t\tthis._polar = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.clamp(this._polar, 0.001, Math.PI - 0.001);\r\n\t\tconst pos = [\r\n\t\t\tthis._radius * Math.sin(this._polar) * Math.sin(this._azimuth),\r\n\t\t\tthis._radius * Math.cos(this._polar),\r\n\t\t\tthis._radius * Math.sin(this._polar) * Math.cos(this._azimuth)\r\n\t\t];\r\n\t\tif (camera.worldUp[2] === 1) {\r\n\t\t\tconst t = pos[1];\r\n\t\t\tpos[1] = pos[2];\r\n\t\t\tpos[2] = t;\r\n\t\t}\r\n\t\t// Preserve the eye->look distance, since in xeokit \"look\" is the point-of-interest, not the direction vector.\r\n\t\tconst eyeLookLen = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.look, camera.eye, _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3()));\r\n\t\tconst pivotPos = this.getPivotPos();\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(pos, pivotPos);\r\n\t\tlet lookat = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lookAtMat4v(pos, pivotPos, camera.worldUp);\r\n\t\tlookat = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(lookat);\r\n\t\tconst offset = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transformVec3(lookat, this._cameraOffset);\r\n\t\tlookat[12] -= offset[0];\r\n\t\tlookat[13] -= offset[1];\r\n\t\tlookat[14] -= offset[2];\r\n\t\tconst zAxis = [lookat[8], lookat[9], lookat[10]];\r\n\t\tcamera.eye = [lookat[12], lookat[13], lookat[14]];\r\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(zAxis, eyeLookLen), camera.look);\r\n\t\tcamera.up = [lookat[4], lookat[5], lookat[6]];\r\n\t\tthis.showPivot();\r\n\t}\r\n\r\n\t/**\r\n\t * Shows the pivot position.\r\n\t *\r\n\t * Only works if we set an HTML DOM element to represent the pivot position.\r\n\t */\r\n\tshowPivot() {\r\n\t\tif (this._shown) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (this._pivotElement) {\r\n\t\t\tthis.updatePivotElement();\r\n\t\t\tthis._pivotElement.style.visibility = \"visible\";\r\n\t\t}\r\n\t\tif (this._pivotSphereEnabled) {\r\n\t\t\tthis.destroyPivotSphere();\r\n\t\t\tthis.createPivotSphere();\r\n\t\t}\r\n\t\tthis._shown = true;\r\n\t}\r\n\r\n\t/**\r\n\t * Hides the pivot position.\r\n\t *\r\n\t * Only works if we set an HTML DOM element to represent the pivot position.\r\n\t */\r\n\thidePivot() {\r\n\t\tif (!this._shown) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (this._pivotElement) {\r\n\t\t\tthis._pivotElement.style.visibility = \"hidden\";\r\n\t\t}\r\n\t\tif (this._pivotSphereEnabled) {\r\n\t\t\tthis.destroyPivotSphere();\r\n\t\t}\r\n\t\tthis._shown = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Finishes pivoting.\r\n\t */\r\n\tendPivot() {\r\n\t\tthis._pivoting = false;\r\n\t}\r\n\r\n\tdestroy() {\r\n\t\tif (this._pivotElement) {\r\n\t\t\tthis._pivotElement.parentNode.removeChild(this._pivotElement);\r\n\t\t}\r\n\t\tthis.destroyPivotSphere();\r\n\t\tthis._scene.camera.off(this._onViewMatrix);\r\n\t\tthis._scene.camera.off(this._onProjMatrix);\r\n\t\tthis._scene.off(this._onTick);\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/CameraControl/lib/controllers/PivotController.js?");
2518
2528
 
2519
2529
  /***/ }),
2520
2530
 
@@ -2654,7 +2664,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2654
2664
  \**********************************************************/
2655
2665
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2656
2666
 
2657
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CameraFlightAnimation: () => (/* binding */ CameraFlightAnimation)\n/* harmony export */ });\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core.js */ \"./src/viewer/scene/core.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n\r\n\r\n\r\n\r\n\r\nconst tempVec3 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\nconst newLook = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\nconst newEye = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\nconst newUp = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\nconst newLookEyeVec = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n\r\n/**\r\n * @desc Jumps or flies the {@link Scene}'s {@link Camera} to a given target.\r\n *\r\n * * Located at {@link Viewer#cameraFlight}\r\n * * Can fly or jump to its target.\r\n * * While flying, can be stopped, or redirected to a different target.\r\n * * Can also smoothly transition between ortho and perspective projections.\r\n *\r\n *\r\n * A CameraFlightAnimation's target can be:\r\n *\r\n * * specific ````eye````, ````look```` and ````up```` positions,\r\n * * an axis-aligned World-space bounding box (AABB), or\r\n * * an instance or ID of any {@link Component} subtype that provides a World-space AABB.\r\n *\r\n * A target can also contain a ````projection```` type to transition into. For example, if your {@link Camera#projection} is\r\n * currently ````\"perspective\"```` and you supply {@link CameraFlightAnimation#flyTo} with a ````projection```` property\r\n * equal to \"ortho\", then CameraFlightAnimation will smoothly transition the Camera into an orthographic projection.\r\n *\r\n * Configure {@link CameraFlightAnimation#fit} and {@link CameraFlightAnimation#fitFOV} to make it stop at the point\r\n * where the target occupies a certain amount of the field-of-view.\r\n *\r\n * ## Flying to an Entity\r\n *\r\n * Flying to an {@link Entity}:\r\n *\r\n * ````Javascript\r\n * var entity = new Mesh(viewer.scene);\r\n *\r\n * // Fly to the Entity's World-space AABB\r\n * viewer.cameraFlight.flyTo(entity);\r\n * ````\r\n * ## Flying to a Position\r\n *\r\n * Flying the CameraFlightAnimation from the previous example to specified eye, look and up positions:\r\n *\r\n * ````Javascript\r\n * viewer.cameraFlight.flyTo({\r\n * eye: [-5,-5,-5],\r\n * look: [0,0,0]\r\n * up: [0,1,0],\r\n * duration: 1 // Default, seconds\r\n * },() => {\r\n * // Done\r\n * });\r\n * ````\r\n *\r\n * ## Flying to an AABB\r\n *\r\n * Flying the CameraFlightAnimation from the previous two examples explicitly to the {@link Boundary3D\"}}Boundary3D's{{/crossLink}}\r\n * axis-aligned bounding box:\r\n *\r\n * ````Javascript\r\n * viewer.cameraFlight.flyTo(entity.aabb);\r\n * ````\r\n *\r\n * ## Transitioning Between Projections\r\n *\r\n * CameraFlightAnimation also allows us to smoothly transition between Camera projections. We can do that by itself, or\r\n * in addition to flying the Camera to a target.\r\n *\r\n * Let's transition the Camera to orthographic projection:\r\n *\r\n * [[Run example](/examples/#camera_CameraFlightAnimation_projection)]\r\n *\r\n * ````Javascript\r\n * viewer.cameraFlight.flyTo({ projection: \"ortho\", () => {\r\n * // Done\r\n * });\r\n * ````\r\n *\r\n * Now let's transition the Camera back to perspective projection:\r\n *\r\n * ````Javascript\r\n * viewer.cameraFlight.flyTo({ projection: \"perspective\"}, () => {\r\n * // Done\r\n * });\r\n * ````\r\n *\r\n * Fly Camera to a position, while transitioning to orthographic projection:\r\n *\r\n * ````Javascript\r\n * viewer.cameraFlight.flyTo({\r\n * eye: [-100,20,2],\r\n * look: [0,0,-40],\r\n * up: [0,1,0],\r\n * projection: \"ortho\", () => {\r\n * // Done\r\n * });\r\n * ````\r\n */\r\nclass CameraFlightAnimation extends _Component_js__WEBPACK_IMPORTED_MODULE_3__.Component {\r\n\r\n /**\r\n * @private\r\n */\r\n get type() {\r\n return \"CameraFlightAnimation\";\r\n }\r\n\r\n /**\r\n @constructor\r\n @private\r\n */\r\n constructor(owner, cfg = {}) {\r\n\r\n super(owner, cfg);\r\n\r\n this._look1 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n this._eye1 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n this._up1 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n this._look2 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n this._eye2 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n this._up2 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\r\n this._orthoScale1 = 1;\r\n this._orthoScale2 = 1;\r\n this._flying = false;\r\n this._flyEyeLookUp = false;\r\n this._flyingEye = false;\r\n this._flyingLook = false;\r\n this._callback = null;\r\n this._callbackScope = null;\r\n this._time1 = null;\r\n this._time2 = null;\r\n this.easing = cfg.easing !== false;\r\n\r\n this.duration = cfg.duration;\r\n this.fit = cfg.fit;\r\n this.fitFOV = cfg.fitFOV;\r\n this.trail = cfg.trail;\r\n }\r\n\r\n /**\r\n * Flies the {@link Camera} to a target.\r\n *\r\n * * When the target is a boundary, the {@link Camera} will fly towards the target and stop when the target fills most of the canvas.\r\n * * When the target is an explicit {@link Camera} position, given as ````eye````, ````look```` and ````up````, then CameraFlightAnimation will interpolate the {@link Camera} to that target and stop there.\r\n *\r\n * @param {Object|Component} [params=Scene] Either a parameters object or a {@link Component} subtype that has\r\n * an AABB. Defaults to the {@link Scene}, which causes the {@link Camera} to fit the Scene in view.\r\n * @param {Number} [params.arc=0] Factor in range ````[0..1]```` indicating how much the {@link Camera#eye} position\r\n * will swing away from its {@link Camera#look} position as it flies to the target.\r\n * @param {Number|String|Component} [params.component] ID or instance of a component to fly to. Defaults to the entire {@link Scene}.\r\n * @param {Number[]} [params.aabb] World-space axis-aligned bounding box (AABB) target to fly to.\r\n * @param {Number[]} [params.eye] Position to fly the eye position to.\r\n * @param {Number[]} [params.look] Position to fly the look position to.\r\n * @param {Number[]} [params.up] Position to fly the up vector to.\r\n * @param {String} [params.projection] Projection type to transition into as we fly. Can be any of the values of {@link Camera.projection}.\r\n * @param {Boolean} [params.fit=true] Whether to fit the target to the view volume. Overrides {@link CameraFlightAnimation#fit}.\r\n * @param {Number} [params.fitFOV] How much of field-of-view, in degrees, that a target {@link Entity} or its AABB should\r\n * fill the canvas on arrival. Overrides {@link CameraFlightAnimation#fitFOV}.\r\n * @param {Number} [params.duration] Flight duration in seconds. Overrides {@link CameraFlightAnimation#duration}.\r\n * @param {Number} [params.orthoScale] Animate the Camera's orthographic scale to this target value. See {@link Ortho#scale}.\r\n * @param {Function} [callback] Callback fired on arrival.\r\n * @param {Object} [scope] Optional scope for callback.\r\n */\r\n flyTo(params, callback, scope) {\r\n\r\n params = params || this.scene;\r\n\r\n if (this._flying) {\r\n this.stop();\r\n }\r\n\r\n this._flying = false;\r\n this._flyingEye = false;\r\n this._flyingLook = false;\r\n this._flyingEyeLookUp = false;\r\n\r\n this._callback = callback;\r\n this._callbackScope = scope;\r\n\r\n const camera = this.scene.camera;\r\n const flyToProjection = (!!params.projection) && (params.projection !== camera.projection);\r\n\r\n this._eye1[0] = camera.eye[0];\r\n this._eye1[1] = camera.eye[1];\r\n this._eye1[2] = camera.eye[2];\r\n\r\n this._look1[0] = camera.look[0];\r\n this._look1[1] = camera.look[1];\r\n this._look1[2] = camera.look[2];\r\n\r\n this._up1[0] = camera.up[0];\r\n this._up1[1] = camera.up[1];\r\n this._up1[2] = camera.up[2];\r\n\r\n this._orthoScale1 = camera.ortho.scale;\r\n this._orthoScale2 = params.orthoScale || this._orthoScale1;\r\n\r\n let aabb;\r\n let eye;\r\n let look;\r\n let up;\r\n let componentId;\r\n\r\n if (params.aabb) {\r\n aabb = params.aabb;\r\n\r\n } else if (params.length === 6) {\r\n aabb = params;\r\n\r\n } else if ((params.eye && params.look) || params.up) {\r\n eye = params.eye;\r\n look = params.look;\r\n up = params.up;\r\n\r\n } else if (params.eye) {\r\n eye = params.eye;\r\n\r\n } else if (params.look) {\r\n look = params.look;\r\n\r\n } else { // Argument must be an instance or ID of a Component (subtype)\r\n\r\n let component = params;\r\n\r\n if (_utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.isNumeric(component) || _utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.isString(component)) {\r\n\r\n componentId = component;\r\n component = this.scene.components[componentId];\r\n\r\n if (!component) {\r\n this.error(\"Component not found: \" + _utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.inQuotes(componentId));\r\n if (callback) {\r\n if (scope) {\r\n callback.call(scope);\r\n } else {\r\n callback();\r\n }\r\n }\r\n return;\r\n }\r\n }\r\n if (!flyToProjection) {\r\n aabb = component.aabb || this.scene.aabb;\r\n }\r\n }\r\n\r\n const poi = params.poi;\r\n\r\n if (aabb) {\r\n\r\n if (aabb[3] < aabb[0] || aabb[4] < aabb[1] || aabb[5] < aabb[2]) { // Don't fly to an inverted boundary\r\n return;\r\n }\r\n\r\n if (aabb[3] === aabb[0] && aabb[4] === aabb[1] && aabb[5] === aabb[2]) { // Don't fly to an empty boundary\r\n return;\r\n }\r\n\r\n aabb = aabb.slice();\r\n const aabbCenter = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\r\n\r\n this._look2 = poi || aabbCenter;\r\n\r\n const eyeLookVec = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(this._eye1, this._look1, tempVec3);\r\n const eyeLookVecNorm = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(eyeLookVec);\r\n const diag = poi ? _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3DiagPoint(aabb, poi) : _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Diag(aabb);\r\n const fitFOV = params.fitFOV || this._fitFOV;\r\n const sca = Math.abs(diag / Math.tan(fitFOV * _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD));\r\n\r\n this._orthoScale2 = diag * 1.1;\r\n\r\n this._eye2[0] = this._look2[0] + (eyeLookVecNorm[0] * sca);\r\n this._eye2[1] = this._look2[1] + (eyeLookVecNorm[1] * sca);\r\n this._eye2[2] = this._look2[2] + (eyeLookVecNorm[2] * sca);\r\n\r\n this._up2[0] = this._up1[0];\r\n this._up2[1] = this._up1[1];\r\n this._up2[2] = this._up1[2];\r\n\r\n this._flyingEyeLookUp = true;\r\n\r\n } else if (eye || look || up) {\r\n\r\n this._flyingEyeLookUp = !!eye && !!look && !!up;\r\n this._flyingEye = !!eye && !look;\r\n this._flyingLook = !!look && !eye;\r\n\r\n if (eye) {\r\n this._eye2[0] = eye[0];\r\n this._eye2[1] = eye[1];\r\n this._eye2[2] = eye[2];\r\n }\r\n\r\n if (look) {\r\n this._look2[0] = look[0];\r\n this._look2[1] = look[1];\r\n this._look2[2] = look[2];\r\n }\r\n\r\n if (up) {\r\n this._up2[0] = up[0];\r\n this._up2[1] = up[1];\r\n this._up2[2] = up[2];\r\n }\r\n }\r\n\r\n if (flyToProjection) {\r\n\r\n if (params.projection === \"ortho\" && camera.projection !== \"ortho\") {\r\n this._projection2 = \"ortho\";\r\n this._projMatrix1 = camera.projMatrix.slice();\r\n this._projMatrix2 = camera.ortho.matrix.slice();\r\n camera.projection = \"customProjection\";\r\n }\r\n\r\n if (params.projection === \"perspective\" && camera.projection !== \"perspective\") {\r\n this._projection2 = \"perspective\";\r\n this._projMatrix1 = camera.projMatrix.slice();\r\n this._projMatrix2 = camera.perspective.matrix.slice();\r\n camera.projection = \"customProjection\";\r\n }\r\n } else {\r\n this._projection2 = null;\r\n }\r\n\r\n this.fire(\"started\", params, true);\r\n\r\n this._time1 = Date.now();\r\n this._time2 = this._time1 + (params.duration ? params.duration * 1000 : this._duration);\r\n\r\n this._flying = true; // False as soon as we stop\r\n\r\n _core_js__WEBPACK_IMPORTED_MODULE_2__.core.scheduleTask(this._update, this);\r\n }\r\n\r\n /**\r\n * Jumps the {@link Scene}'s {@link Camera} to the given target.\r\n *\r\n * * When the target is a boundary, this CameraFlightAnimation will position the {@link Camera} at where the target fills most of the canvas.\r\n * * When the target is an explicit {@link Camera} position, given as ````eye````, ````look```` and ````up```` vectors, then this CameraFlightAnimation will jump the {@link Camera} to that target.\r\n *\r\n * @param {*|Component} params Either a parameters object or a {@link Component} subtype that has a World-space AABB.\r\n * @param {Number} [params.arc=0] Factor in range [0..1] indicating how much the {@link Camera#eye} will swing away from its {@link Camera#look} as it flies to the target.\r\n * @param {Number|String|Component} [params.component] ID or instance of a component to fly to.\r\n * @param {Number[]} [params.aabb] World-space axis-aligned bounding box (AABB) target to fly to.\r\n * @param {Number[]} [params.eye] Position to fly the eye position to.\r\n * @param {Number[]} [params.look] Position to fly the look position to.\r\n * @param {Number[]} [params.up] Position to fly the up vector to.\r\n * @param {String} [params.projection] Projection type to transition into. Can be any of the values of {@link Camera.projection}.\r\n * @param {Number} [params.fitFOV] How much of field-of-view, in degrees, that a target {@link Entity} or its AABB should fill the canvas on arrival. Overrides {@link CameraFlightAnimation#fitFOV}.\r\n * @param {Boolean} [params.fit] Whether to fit the target to the view volume. Overrides {@link CameraFlightAnimation#fit}.\r\n */\r\n jumpTo(params) {\r\n this._jumpTo(params);\r\n }\r\n\r\n _jumpTo(params) {\r\n\r\n if (this._flying) {\r\n this.stop();\r\n }\r\n\r\n const camera = this.scene.camera;\r\n\r\n var aabb;\r\n var componentId;\r\n var newEye;\r\n var newLook;\r\n var newUp;\r\n\r\n if (params.aabb) { // Boundary3D\r\n aabb = params.aabb;\r\n\r\n } else if (params.length === 6) { // AABB\r\n aabb = params;\r\n\r\n } else if (params.eye || params.look || params.up) { // Camera pose\r\n newEye = params.eye;\r\n newLook = params.look;\r\n newUp = params.up;\r\n\r\n } else { // Argument must be an instance or ID of a Component (subtype)\r\n\r\n let component = params;\r\n\r\n if (_utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.isNumeric(component) || _utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.isString(component)) {\r\n componentId = component;\r\n component = this.scene.components[componentId];\r\n if (!component) {\r\n this.error(\"Component not found: \" + _utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.inQuotes(componentId));\r\n return;\r\n }\r\n }\r\n aabb = component.aabb || this.scene.aabb;\r\n }\r\n\r\n const poi = params.poi;\r\n\r\n if (aabb) {\r\n\r\n if (aabb[3] <= aabb[0] || aabb[4] <= aabb[1] || aabb[5] <= aabb[2]) { // Don't fly to an empty boundary\r\n return;\r\n }\r\n\r\n var diag = poi ? _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3DiagPoint(aabb, poi) : _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Diag(aabb);\r\n\r\n newLook = poi || _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb, newLook);\r\n\r\n if (this._trail) {\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.look, newLook, newLookEyeVec);\r\n } else {\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, camera.look, newLookEyeVec);\r\n }\r\n\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(newLookEyeVec);\r\n let dist;\r\n const fit = (params.fit !== undefined) ? params.fit : this._fit;\r\n\r\n if (fit) {\r\n dist = Math.abs((diag) / Math.tan((params.fitFOV || this._fitFOV) * _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD));\r\n\r\n } else {\r\n dist = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, camera.look, tempVec3));\r\n }\r\n\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(newLookEyeVec, dist);\r\n\r\n camera.eye = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(newLook, newLookEyeVec, tempVec3);\r\n camera.look = newLook;\r\n\r\n this.scene.camera.ortho.scale = diag * 1.1;\r\n\r\n } else if (newEye || newLook || newUp) {\r\n\r\n if (newEye) {\r\n camera.eye = newEye;\r\n }\r\n if (newLook) {\r\n camera.look = newLook;\r\n }\r\n if (newUp) {\r\n camera.up = newUp;\r\n }\r\n }\r\n\r\n if (params.projection) {\r\n camera.projection = params.projection;\r\n }\r\n }\r\n\r\n _update() {\r\n if (!this._flying) {\r\n return;\r\n }\r\n const time = Date.now();\r\n let t = (time - this._time1) / (this._time2 - this._time1);\r\n const stopping = (t >= 1);\r\n\r\n if (t > 1) {\r\n t = 1;\r\n }\r\n\r\n const tFlight = this.easing ? CameraFlightAnimation._ease(t, 0, 1, 1) : t;\r\n const camera = this.scene.camera;\r\n\r\n if (this._flyingEye || this._flyingLook) {\r\n\r\n if (this._flyingEye) {\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, camera.look, newLookEyeVec);\r\n camera.eye = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._eye1, this._eye2, newEye);\r\n camera.look = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(newEye, newLookEyeVec, newLook);\r\n } else if (this._flyingLook) {\r\n camera.look = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._look1, this._look2, newLook);\r\n camera.up = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._up1, this._up2, newUp);\r\n }\r\n\r\n } else if (this._flyingEyeLookUp) {\r\n\r\n camera.eye = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._eye1, this._eye2, newEye);\r\n camera.look = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._look1, this._look2, newLook);\r\n camera.up = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._up1, this._up2, newUp);\r\n }\r\n\r\n if (this._projection2) {\r\n const tProj = (this._projection2 === \"ortho\") ? CameraFlightAnimation._easeOutExpo(t, 0, 1, 1) : CameraFlightAnimation._easeInCubic(t, 0, 1, 1);\r\n camera.customProjection.matrix = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpMat4(tProj, 0, 1, this._projMatrix1, this._projMatrix2);\r\n\r\n } else {\r\n camera.ortho.scale = this._orthoScale1 + (t * (this._orthoScale2 - this._orthoScale1));\r\n }\r\n\r\n if (stopping) {\r\n camera.ortho.scale = this._orthoScale2;\r\n this.stop();\r\n return;\r\n }\r\n _core_js__WEBPACK_IMPORTED_MODULE_2__.core.scheduleTask(this._update, this); // Keep flying\r\n }\r\n\r\n static _ease(t, b, c, d) { // Quadratic easing out - decelerating to zero velocity http://gizma.com/easing\r\n t /= d;\r\n return -c * t * (t - 2) + b;\r\n }\r\n\r\n static _easeInCubic(t, b, c, d) {\r\n t /= d;\r\n return c * t * t * t + b;\r\n }\r\n\r\n static _easeOutExpo(t, b, c, d) {\r\n return c * (-Math.pow(2, -10 * t / d) + 1) + b;\r\n }\r\n\r\n /**\r\n * Stops an earlier flyTo, fires arrival callback.\r\n */\r\n stop() {\r\n if (!this._flying) {\r\n return;\r\n }\r\n this._flying = false;\r\n this._time1 = null;\r\n this._time2 = null;\r\n if (this._projection2) {\r\n this.scene.camera.projection = this._projection2;\r\n }\r\n const callback = this._callback;\r\n if (callback) {\r\n this._callback = null;\r\n if (this._callbackScope) {\r\n callback.call(this._callbackScope);\r\n } else {\r\n callback();\r\n }\r\n }\r\n this.fire(\"stopped\", true, true);\r\n }\r\n\r\n /**\r\n * Cancels an earlier flyTo without calling the arrival callback.\r\n */\r\n cancel() {\r\n if (!this._flying) {\r\n return;\r\n }\r\n this._flying = false;\r\n this._time1 = null;\r\n this._time2 = null;\r\n if (this._callback) {\r\n this._callback = null;\r\n }\r\n this.fire(\"canceled\", true, true);\r\n }\r\n\r\n /**\r\n * Sets the flight duration, in seconds, when calling {@link CameraFlightAnimation#flyTo}.\r\n *\r\n * Stops any flight currently in progress.\r\n *\r\n * default value is ````0.5````.\r\n *\r\n * @param {Number} value New duration value.\r\n */\r\n set duration(value) {\r\n this._duration = value ? (value * 1000.0) : 500;\r\n this.stop();\r\n }\r\n\r\n /**\r\n * Gets the flight duration, in seconds, when calling {@link CameraFlightAnimation#flyTo}.\r\n *\r\n * default value is ````0.5````.\r\n *\r\n * @returns {Number} New duration value.\r\n */\r\n get duration() {\r\n return this._duration / 1000.0;\r\n }\r\n\r\n /**\r\n * Sets if, when CameraFlightAnimation is flying to a boundary, it will always adjust the distance between the\r\n * {@link Camera#eye} and {@link Camera#look} so as to ensure that the target boundary is always filling the view volume.\r\n *\r\n * When false, the eye will remain at its current distance from the look position.\r\n *\r\n * Default value is ````true````.\r\n *\r\n * @param {Boolean} value Set ````true```` to activate this behaviour.\r\n */\r\n set fit(value) {\r\n this._fit = value !== false;\r\n }\r\n\r\n /**\r\n * Gets if, when CameraFlightAnimation is flying to a boundary, it will always adjust the distance between the\r\n * {@link Camera#eye} and {@link Camera#look} so as to ensure that the target boundary is always filling the view volume.\r\n *\r\n * When false, the eye will remain at its current distance from the look position.\r\n *\r\n * Default value is ````true````.\r\n *\r\n * @returns {Boolean} value Set ````true```` to activate this behaviour.\r\n */\r\n get fit() {\r\n return this._fit;\r\n }\r\n\r\n /**\r\n * Sets how much of the perspective field-of-view, in degrees, that a target {@link Entity#aabb} should\r\n * fill the canvas when calling {@link CameraFlightAnimation#flyTo} or {@link CameraFlightAnimation#jumpTo}.\r\n *\r\n * Default value is ````45````.\r\n *\r\n * @param {Number} value New FOV value.\r\n */\r\n set fitFOV(value) {\r\n this._fitFOV = value || 45;\r\n }\r\n\r\n /**\r\n * Gets how much of the perspective field-of-view, in degrees, that a target {@link Entity#aabb} should\r\n * fill the canvas when calling {@link CameraFlightAnimation#flyTo} or {@link CameraFlightAnimation#jumpTo}.\r\n *\r\n * Default value is ````45````.\r\n *\r\n * @returns {Number} Current FOV value.\r\n */\r\n get fitFOV() {\r\n return this._fitFOV;\r\n }\r\n\r\n /**\r\n * Sets if this CameraFlightAnimation to point the {@link Camera}\r\n * in the direction that it is travelling when flying to a target after calling {@link CameraFlightAnimation#flyTo}.\r\n *\r\n * Default value is ````true````.\r\n *\r\n * @param {Boolean} value Set ````true```` to activate trailing behaviour.\r\n */\r\n set trail(value) {\r\n this._trail = !!value;\r\n }\r\n\r\n /**\r\n * Gets if this CameraFlightAnimation points the {@link Camera}\r\n * in the direction that it is travelling when flying to a target after calling {@link CameraFlightAnimation#flyTo}.\r\n *\r\n * Default value is ````true````.\r\n *\r\n * @returns {Boolean} True if trailing behaviour is active.\r\n */\r\n get trail() {\r\n return this._trail;\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n destroy() {\r\n this.stop();\r\n super.destroy();\r\n }\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/camera/CameraFlightAnimation.js?");
2667
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CameraFlightAnimation: () => (/* binding */ CameraFlightAnimation)\n/* harmony export */ });\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core.js */ \"./src/viewer/scene/core.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n\n\n\n\n\nconst tempVec3 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\nconst newLook = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\nconst newEye = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\nconst newUp = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\nconst newLookEyeVec = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n\n/**\n * @desc Jumps or flies the {@link Scene}'s {@link Camera} to a given target.\n *\n * * Located at {@link Viewer#cameraFlight}\n * * Can fly or jump to its target.\n * * While flying, can be stopped, or redirected to a different target.\n * * Can also smoothly transition between ortho and perspective projections.\n *\n *\n * A CameraFlightAnimation's target can be:\n *\n * * specific ````eye````, ````look```` and ````up```` positions,\n * * an axis-aligned World-space bounding box (AABB), or\n * * an instance or ID of any {@link Component} subtype that provides a World-space AABB.\n *\n * A target can also contain a ````projection```` type to transition into. For example, if your {@link Camera#projection} is\n * currently ````\"perspective\"```` and you supply {@link CameraFlightAnimation#flyTo} with a ````projection```` property\n * equal to \"ortho\", then CameraFlightAnimation will smoothly transition the Camera into an orthographic projection.\n *\n * Configure {@link CameraFlightAnimation#fit} and {@link CameraFlightAnimation#fitFOV} to make it stop at the point\n * where the target occupies a certain amount of the field-of-view.\n *\n * ## Flying to an Entity\n *\n * Flying to an {@link Entity}:\n *\n * ````Javascript\n * var entity = new Mesh(viewer.scene);\n *\n * // Fly to the Entity's World-space AABB\n * viewer.cameraFlight.flyTo(entity);\n * ````\n * ## Flying to a Position\n *\n * Flying the CameraFlightAnimation from the previous example to specified eye, look and up positions:\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo({\n * eye: [-5,-5,-5],\n * look: [0,0,0]\n * up: [0,1,0],\n * duration: 1 // Default, seconds\n * },() => {\n * // Done\n * });\n * ````\n *\n * ## Flying to an AABB\n *\n * Flying the CameraFlightAnimation from the previous two examples explicitly to the {@link Boundary3D\"}}Boundary3D's{{/crossLink}}\n * axis-aligned bounding box:\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo(entity.aabb);\n * ````\n *\n * ## Transitioning Between Projections\n *\n * CameraFlightAnimation also allows us to smoothly transition between Camera projections. We can do that by itself, or\n * in addition to flying the Camera to a target.\n *\n * Let's transition the Camera to orthographic projection:\n *\n * [[Run example](/examples/#camera_CameraFlightAnimation_projection)]\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo({ projection: \"ortho\", () => {\n * // Done\n * });\n * ````\n *\n * Now let's transition the Camera back to perspective projection:\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo({ projection: \"perspective\"}, () => {\n * // Done\n * });\n * ````\n *\n * Fly Camera to a position, while transitioning to orthographic projection:\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo({\n * eye: [-100,20,2],\n * look: [0,0,-40],\n * up: [0,1,0],\n * projection: \"ortho\", () => {\n * // Done\n * });\n * ````\n */\nclass CameraFlightAnimation extends _Component_js__WEBPACK_IMPORTED_MODULE_3__.Component {\n\n /**\n * @private\n */\n get type() {\n return \"CameraFlightAnimation\";\n }\n\n /**\n @constructor\n @private\n */\n constructor(owner, cfg = {}) {\n\n super(owner, cfg);\n\n this._look1 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n this._eye1 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n this._up1 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n this._look2 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n this._eye2 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n this._up2 = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.vec3();\n this._orthoScale1 = 1;\n this._orthoScale2 = 1;\n this._flying = false;\n this._flyEyeLookUp = false;\n this._flyingEye = false;\n this._flyingLook = false;\n this._callback = null;\n this._callbackScope = null;\n this._time1 = null;\n this._time2 = null;\n this.easing = cfg.easing !== false;\n\n this.duration = cfg.duration;\n this.fit = cfg.fit;\n this.fitFOV = cfg.fitFOV;\n this.trail = cfg.trail;\n }\n\n /**\n * Flies the {@link Camera} to a target.\n *\n * * When the target is a boundary, the {@link Camera} will fly towards the target and stop when the target fills most of the canvas.\n * * When the target is an explicit {@link Camera} position, given as ````eye````, ````look```` and ````up````, then CameraFlightAnimation will interpolate the {@link Camera} to that target and stop there.\n *\n * @param {Object|Component} [params=Scene] Either a parameters object or a {@link Component} subtype that has\n * an AABB. Defaults to the {@link Scene}, which causes the {@link Camera} to fit the Scene in view.\n * @param {Number} [params.arc=0] Factor in range ````[0..1]```` indicating how much the {@link Camera#eye} position\n * will swing away from its {@link Camera#look} position as it flies to the target.\n * @param {Number|String|Component} [params.component] ID or instance of a component to fly to. Defaults to the entire {@link Scene}.\n * @param {Number[]} [params.aabb] World-space axis-aligned bounding box (AABB) target to fly to.\n * @param {Number[]} [params.eye] Position to fly the eye position to.\n * @param {Number[]} [params.look] Position to fly the look position to.\n * @param {Number[]} [params.up] Position to fly the up vector to.\n * @param {String} [params.projection] Projection type to transition into as we fly. Can be any of the values of {@link Camera.projection}.\n * @param {Boolean} [params.fit=true] Whether to fit the target to the view volume. Overrides {@link CameraFlightAnimation#fit}.\n * @param {Number} [params.fitFOV] How much of field-of-view, in degrees, that a target {@link Entity} or its AABB should\n * fill the canvas on arrival. Overrides {@link CameraFlightAnimation#fitFOV}.\n * @param {Number} [params.duration] Flight duration in seconds. Overrides {@link CameraFlightAnimation#duration}.\n * @param {Number} [params.orthoScale] Animate the Camera's orthographic scale to this target value. See {@link Ortho#scale}.\n * @param {Function} [callback] Callback fired on arrival.\n * @param {Object} [scope] Optional scope for callback.\n */\n flyTo(params, callback, scope) {\n\n params = params || this.scene;\n\n if (this._flying) {\n this.stop();\n }\n\n this._flying = false;\n this._flyingEye = false;\n this._flyingLook = false;\n this._flyingEyeLookUp = false;\n\n this._callback = callback;\n this._callbackScope = scope;\n\n const camera = this.scene.camera;\n const flyToProjection = (!!params.projection) && (params.projection !== camera.projection);\n\n this._eye1[0] = camera.eye[0];\n this._eye1[1] = camera.eye[1];\n this._eye1[2] = camera.eye[2];\n\n this._look1[0] = camera.look[0];\n this._look1[1] = camera.look[1];\n this._look1[2] = camera.look[2];\n\n this._up1[0] = camera.up[0];\n this._up1[1] = camera.up[1];\n this._up1[2] = camera.up[2];\n\n this._orthoScale1 = camera.ortho.scale;\n this._orthoScale2 = params.orthoScale || this._orthoScale1;\n\n let aabb;\n let eye;\n let look;\n let up;\n let componentId;\n\n if (params.aabb) {\n aabb = params.aabb;\n\n } else if (params.length === 6) {\n aabb = params;\n\n } else if ((params.eye && params.look) || params.up) {\n eye = params.eye;\n look = params.look;\n up = params.up;\n\n } else if (params.eye) {\n eye = params.eye;\n\n } else if (params.look) {\n look = params.look;\n\n } else { // Argument must be an instance or ID of a Component (subtype)\n\n let component = params;\n\n if (_utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.isNumeric(component) || _utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.isString(component)) {\n\n componentId = component;\n component = this.scene.components[componentId];\n\n if (!component) {\n this.error(\"Component not found: \" + _utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.inQuotes(componentId));\n if (callback) {\n if (scope) {\n callback.call(scope);\n } else {\n callback();\n }\n }\n return;\n }\n }\n if (!flyToProjection) {\n aabb = component.aabb || this.scene.aabb;\n }\n }\n\n const poi = params.poi;\n\n if (aabb) {\n\n if (aabb[3] < aabb[0] || aabb[4] < aabb[1] || aabb[5] < aabb[2]) { // Don't fly to an inverted boundary\n return;\n }\n\n if (aabb[3] === aabb[0] && aabb[4] === aabb[1] && aabb[5] === aabb[2]) { // Don't fly to an empty boundary\n return;\n }\n\n aabb = aabb.slice();\n const aabbCenter = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb);\n\n this._look2 = poi || aabbCenter;\n\n const eyeLookVec = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(this._eye1, this._look1, tempVec3);\n const eyeLookVecNorm = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(eyeLookVec);\n const diag = poi ? _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3DiagPoint(aabb, poi) : _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Diag(aabb);\n const fitFOV = params.fitFOV || this._fitFOV;\n const sca = Math.abs(diag / Math.tan(fitFOV * _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD));\n\n this._orthoScale2 = diag * 1.1;\n\n this._eye2[0] = this._look2[0] + (eyeLookVecNorm[0] * sca);\n this._eye2[1] = this._look2[1] + (eyeLookVecNorm[1] * sca);\n this._eye2[2] = this._look2[2] + (eyeLookVecNorm[2] * sca);\n\n this._up2[0] = this._up1[0];\n this._up2[1] = this._up1[1];\n this._up2[2] = this._up1[2];\n\n this._flyingEyeLookUp = true;\n\n } else if (eye || look || up) {\n\n this._flyingEyeLookUp = !!eye && !!look && !!up;\n this._flyingEye = !!eye && !look;\n this._flyingLook = !!look && !eye;\n\n if (eye) {\n this._eye2[0] = eye[0];\n this._eye2[1] = eye[1];\n this._eye2[2] = eye[2];\n }\n\n if (look) {\n this._look2[0] = look[0];\n this._look2[1] = look[1];\n this._look2[2] = look[2];\n }\n\n if (up) {\n this._up2[0] = up[0];\n this._up2[1] = up[1];\n this._up2[2] = up[2];\n }\n }\n\n if (flyToProjection) {\n\n if (params.projection === \"ortho\" && camera.projection !== \"ortho\") {\n this._projection2 = \"ortho\";\n this._projMatrix1 = camera.projMatrix.slice();\n this._projMatrix2 = camera.ortho.matrix.slice();\n camera.projection = \"customProjection\";\n }\n\n if (params.projection === \"perspective\" && camera.projection !== \"perspective\") {\n this._projection2 = \"perspective\";\n this._projMatrix1 = camera.projMatrix.slice();\n this._projMatrix2 = camera.perspective.matrix.slice();\n camera.projection = \"customProjection\";\n }\n } else {\n this._projection2 = null;\n }\n\n this.fire(\"started\", params, true);\n\n this._time1 = Date.now();\n this._time2 = this._time1 + (params.duration ? params.duration * 1000 : this._duration);\n\n this._flying = true; // False as soon as we stop\n\n _core_js__WEBPACK_IMPORTED_MODULE_2__.core.scheduleTask(this._update, this);\n }\n\n /**\n * Jumps the {@link Scene}'s {@link Camera} to the given target.\n *\n * * When the target is a boundary, this CameraFlightAnimation will position the {@link Camera} at where the target fills most of the canvas.\n * * When the target is an explicit {@link Camera} position, given as ````eye````, ````look```` and ````up```` vectors, then this CameraFlightAnimation will jump the {@link Camera} to that target.\n *\n * @param {*|Component} params Either a parameters object or a {@link Component} subtype that has a World-space AABB.\n * @param {Number} [params.arc=0] Factor in range [0..1] indicating how much the {@link Camera#eye} will swing away from its {@link Camera#look} as it flies to the target.\n * @param {Number|String|Component} [params.component] ID or instance of a component to fly to.\n * @param {Number[]} [params.aabb] World-space axis-aligned bounding box (AABB) target to fly to.\n * @param {Number[]} [params.eye] Position to fly the eye position to.\n * @param {Number[]} [params.look] Position to fly the look position to.\n * @param {Number[]} [params.up] Position to fly the up vector to.\n * @param {String} [params.projection] Projection type to transition into. Can be any of the values of {@link Camera.projection}.\n * @param {Number} [params.fitFOV] How much of field-of-view, in degrees, that a target {@link Entity} or its AABB should fill the canvas on arrival. Overrides {@link CameraFlightAnimation#fitFOV}.\n * @param {Boolean} [params.fit] Whether to fit the target to the view volume. Overrides {@link CameraFlightAnimation#fit}.\n */\n jumpTo(params) {\n this._jumpTo(params);\n }\n\n _jumpTo(params) {\n\n if (this._flying) {\n this.stop();\n }\n\n const camera = this.scene.camera;\n\n var aabb;\n var componentId;\n var newEye;\n var newLook;\n var newUp;\n\n if (params.aabb) { // Boundary3D\n aabb = params.aabb;\n\n } else if (params.length === 6) { // AABB\n aabb = params;\n\n } else if (params.eye || params.look || params.up) { // Camera pose\n newEye = params.eye;\n newLook = params.look;\n newUp = params.up;\n\n } else { // Argument must be an instance or ID of a Component (subtype)\n\n let component = params;\n\n if (_utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.isNumeric(component) || _utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.isString(component)) {\n componentId = component;\n component = this.scene.components[componentId];\n if (!component) {\n this.error(\"Component not found: \" + _utils_js__WEBPACK_IMPORTED_MODULE_1__.utils.inQuotes(componentId));\n return;\n }\n }\n aabb = component.aabb || this.scene.aabb;\n }\n\n const poi = params.poi;\n\n if (aabb) {\n\n if (aabb[3] <= aabb[0] || aabb[4] <= aabb[1] || aabb[5] <= aabb[2]) { // Don't fly to an empty boundary\n return;\n }\n\n var diag = poi ? _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3DiagPoint(aabb, poi) : _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Diag(aabb);\n\n newLook = poi || _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.getAABB3Center(aabb, newLook);\n\n if (this._trail) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.look, newLook, newLookEyeVec);\n } else {\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, camera.look, newLookEyeVec);\n }\n\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.normalizeVec3(newLookEyeVec);\n let dist;\n const fit = (params.fit !== undefined) ? params.fit : this._fit;\n\n if (fit) {\n dist = Math.abs((diag) / Math.tan((params.fitFOV || this._fitFOV) * _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.DEGTORAD));\n\n } else {\n dist = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lenVec3(_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, camera.look, tempVec3));\n }\n\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(newLookEyeVec, dist);\n\n camera.eye = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.addVec3(newLook, newLookEyeVec, tempVec3);\n camera.look = newLook;\n\n this.scene.camera.ortho.scale = diag * 1.1;\n\n } else if (newEye || newLook || newUp) {\n\n if (newEye) {\n camera.eye = newEye;\n }\n if (newLook) {\n camera.look = newLook;\n }\n if (newUp) {\n camera.up = newUp;\n }\n }\n\n if (params.projection) {\n camera.projection = params.projection;\n }\n }\n\n _update() {\n if (!this._flying) {\n return;\n }\n const time = Date.now();\n let t = (time - this._time1) / (this._time2 - this._time1);\n const stopping = (t >= 1);\n\n if (t > 1) {\n t = 1;\n }\n\n const tFlight = this.easing ? CameraFlightAnimation._ease(t, 0, 1, 1) : t;\n const camera = this.scene.camera;\n\n if (this._flyingEye || this._flyingLook) {\n\n if (this._flyingEye) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(camera.eye, camera.look, newLookEyeVec);\n camera.eye = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._eye1, this._eye2, newEye);\n camera.look = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.subVec3(newEye, newLookEyeVec, newLook);\n } else if (this._flyingLook) {\n camera.look = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._look1, this._look2, newLook);\n camera.up = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._up1, this._up2, newUp);\n }\n\n } else if (this._flyingEyeLookUp) {\n\n camera.eye = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._eye1, this._eye2, newEye);\n camera.look = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._look1, this._look2, newLook);\n camera.up = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpVec3(tFlight, 0, 1, this._up1, this._up2, newUp);\n }\n\n if (this._projection2) {\n const tProj = (this._projection2 === \"ortho\") ? CameraFlightAnimation._easeOutExpo(t, 0, 1, 1) : CameraFlightAnimation._easeInCubic(t, 0, 1, 1);\n camera.customProjection.matrix = _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.lerpMat4(tProj, 0, 1, this._projMatrix1, this._projMatrix2);\n\n } else {\n camera.ortho.scale = this._orthoScale1 + (t * (this._orthoScale2 - this._orthoScale1));\n }\n\n if (stopping) {\n camera.ortho.scale = this._orthoScale2;\n this.stop();\n return;\n }\n _core_js__WEBPACK_IMPORTED_MODULE_2__.core.scheduleTask(this._update, this); // Keep flying\n }\n\n static _ease(t, b, c, d) { // Quadratic easing out - decelerating to zero velocity http://gizma.com/easing\n t /= d;\n return -c * t * (t - 2) + b;\n }\n\n static _easeInCubic(t, b, c, d) {\n t /= d;\n return c * t * t * t + b;\n }\n\n static _easeOutExpo(t, b, c, d) {\n return c * (-Math.pow(2, -10 * t / d) + 1) + b;\n }\n\n /**\n * Stops an earlier flyTo, fires arrival callback.\n */\n stop() {\n if (!this._flying) {\n return;\n }\n this._flying = false;\n this._time1 = null;\n this._time2 = null;\n if (this._projection2) {\n this.scene.camera.projection = this._projection2;\n }\n const callback = this._callback;\n if (callback) {\n this._callback = null;\n if (this._callbackScope) {\n callback.call(this._callbackScope);\n } else {\n callback();\n }\n }\n this.fire(\"stopped\", true, true);\n }\n\n /**\n * Cancels an earlier flyTo without calling the arrival callback.\n */\n cancel() {\n if (!this._flying) {\n return;\n }\n this._flying = false;\n this._time1 = null;\n this._time2 = null;\n if (this._callback) {\n this._callback = null;\n }\n this.fire(\"canceled\", true, true);\n }\n\n /**\n * Sets the flight duration, in seconds, when calling {@link CameraFlightAnimation#flyTo}.\n *\n * Stops any flight currently in progress.\n *\n * default value is ````0.5````.\n *\n * @param {Number} value New duration value.\n */\n set duration(value) {\n this._duration = value ? (value * 1000.0) : 500;\n this.stop();\n }\n\n /**\n * Gets the flight duration, in seconds, when calling {@link CameraFlightAnimation#flyTo}.\n *\n * default value is ````0.5````.\n *\n * @returns {Number} New duration value.\n */\n get duration() {\n return this._duration / 1000.0;\n }\n\n /**\n * Sets if, when CameraFlightAnimation is flying to a boundary, it will always adjust the distance between the\n * {@link Camera#eye} and {@link Camera#look} so as to ensure that the target boundary is always filling the view volume.\n *\n * When false, the eye will remain at its current distance from the look position.\n *\n * Default value is ````true````.\n *\n * @param {Boolean} value Set ````true```` to activate this behaviour.\n */\n set fit(value) {\n this._fit = value !== false;\n }\n\n /**\n * Gets if, when CameraFlightAnimation is flying to a boundary, it will always adjust the distance between the\n * {@link Camera#eye} and {@link Camera#look} so as to ensure that the target boundary is always filling the view volume.\n *\n * When false, the eye will remain at its current distance from the look position.\n *\n * Default value is ````true````.\n *\n * @returns {Boolean} value Set ````true```` to activate this behaviour.\n */\n get fit() {\n return this._fit;\n }\n\n /**\n * Sets how much of the perspective field-of-view, in degrees, that a target {@link Entity#aabb} should\n * fill the canvas when calling {@link CameraFlightAnimation#flyTo} or {@link CameraFlightAnimation#jumpTo}.\n *\n * Default value is ````45````.\n *\n * @param {Number} value New FOV value.\n */\n set fitFOV(value) {\n this._fitFOV = value || 45;\n }\n\n /**\n * Gets how much of the perspective field-of-view, in degrees, that a target {@link Entity#aabb} should\n * fill the canvas when calling {@link CameraFlightAnimation#flyTo} or {@link CameraFlightAnimation#jumpTo}.\n *\n * Default value is ````45````.\n *\n * @returns {Number} Current FOV value.\n */\n get fitFOV() {\n return this._fitFOV;\n }\n\n /**\n * Sets if this CameraFlightAnimation to point the {@link Camera}\n * in the direction that it is travelling when flying to a target after calling {@link CameraFlightAnimation#flyTo}.\n *\n * Default value is ````true````.\n *\n * @param {Boolean} value Set ````true```` to activate trailing behaviour.\n */\n set trail(value) {\n this._trail = !!value;\n }\n\n /**\n * Gets if this CameraFlightAnimation points the {@link Camera}\n * in the direction that it is travelling when flying to a target after calling {@link CameraFlightAnimation#flyTo}.\n *\n * Default value is ````true````.\n *\n * @returns {Boolean} True if trailing behaviour is active.\n */\n get trail() {\n return this._trail;\n }\n\n /**\n * @private\n */\n destroy() {\n this.stop();\n super.destroy();\n }\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/camera/CameraFlightAnimation.js?");
2658
2668
 
2659
2669
  /***/ }),
2660
2670
 
@@ -2714,7 +2724,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2714
2724
  \************************************************/
2715
2725
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2716
2726
 
2717
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Perspective: () => (/* binding */ Perspective)\n/* harmony export */ });\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../webgl/RenderState.js */ \"./src/viewer/scene/webgl/RenderState.js\");\n\r\n\r\n\r\n\r\n/**\r\n * @desc Defines its {@link Camera}'s perspective projection using a field-of-view angle.\r\n *\r\n * * Located at {@link Camera#perspective}.\r\n * * Implicitly sets the left, right, top, bottom frustum planes using {@link Perspective#fov}.\r\n * * {@link Perspective#near} and {@link Perspective#far} specify the distances to the WebGL clipping planes.\r\n */\r\nclass Perspective extends _Component_js__WEBPACK_IMPORTED_MODULE_1__.Component {\r\n\r\n /**\r\n @private\r\n */\r\n get type() {\r\n return \"Perspective\";\r\n }\r\n\r\n /**\r\n * @constructor\r\n * @private\r\n */\r\n constructor(camera, cfg = {}) {\r\n\r\n super(camera, cfg);\r\n\r\n /**\r\n * The Camera this Perspective belongs to.\r\n *\r\n * @property camera\r\n * @type {Camera}\r\n * @final\r\n */\r\n this.camera = camera;\r\n\r\n this._state = new _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_2__.RenderState({\r\n matrix: _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4(),\r\n inverseMatrix: _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4(),\r\n transposedMatrix: _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4(),\r\n near: 0.1,\r\n far: 2000.0\r\n });\r\n\r\n this._inverseMatrixDirty = true;\r\n this._transposedMatrixDirty = true;\r\n\r\n this._fov = 60.0;\r\n\r\n // Recompute aspect from change in canvas size\r\n this._canvasResized = this.scene.canvas.on(\"boundary\", this._needUpdate, this);\r\n\r\n this.fov = cfg.fov;\r\n this.fovAxis = cfg.fovAxis;\r\n this.near = cfg.near;\r\n this.far = cfg.far;\r\n }\r\n\r\n _update() {\r\n\r\n const WIDTH_INDEX = 2;\r\n const HEIGHT_INDEX = 3;\r\n const boundary = this.scene.canvas.boundary;\r\n const aspect = boundary[WIDTH_INDEX] / boundary[HEIGHT_INDEX];\r\n const fovAxis = this._fovAxis;\r\n\r\n let fov = this._fov;\r\n if (fovAxis === \"x\" || (fovAxis === \"min\" && aspect < 1) || (fovAxis === \"max\" && aspect > 1)) {\r\n fov = fov / aspect;\r\n }\r\n fov = Math.min(fov, 120);\r\n\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.perspectiveMat4(fov * (Math.PI / 180.0), aspect, this._state.near, this._state.far, this._state.matrix);\r\n\r\n this._inverseMatrixDirty = true;\r\n this._transposedMatrixDirty = true;\r\n\r\n this.glRedraw();\r\n\r\n this.camera._updateScheduled = true;\r\n\r\n this.fire(\"matrix\", this._state.matrix);\r\n }\r\n\r\n /**\r\n * Sets the Perspective's field-of-view angle (FOV).\r\n *\r\n * Fires an \"fov\" event on change.\r\n\r\n * Default value is ````60.0````.\r\n *\r\n * @param {Number} value New field-of-view.\r\n */\r\n set fov(value) {\r\n value = (value !== undefined && value !== null) ? value : 60.0;\r\n if (value === this._fov) {\r\n return;\r\n }\r\n this._fov = value;\r\n this._needUpdate(0); // Ensure matrix built on next \"tick\"\r\n this.fire(\"fov\", this._fov);\r\n }\r\n\r\n /**\r\n * Gets the Perspective's field-of-view angle (FOV).\r\n *\r\n * Default value is ````60.0````.\r\n *\r\n * @returns {Number} Current field-of-view.\r\n */\r\n get fov() {\r\n return this._fov;\r\n }\r\n\r\n /**\r\n * Sets the Perspective's FOV axis.\r\n *\r\n * Options are ````\"x\"````, ````\"y\"```` or ````\"min\"````, to use the minimum axis.\r\n *\r\n * Fires an \"fovAxis\" event on change.\r\n\r\n * Default value ````\"min\"````.\r\n *\r\n * @param {String} value New FOV axis value.\r\n */\r\n set fovAxis(value) {\r\n value = value || \"min\";\r\n if (this._fovAxis === value) {\r\n return;\r\n }\r\n if (value !== \"x\" && value !== \"y\" && value !== \"min\") {\r\n this.error(\"Unsupported value for 'fovAxis': \" + value + \" - defaulting to 'min'\");\r\n value = \"min\";\r\n }\r\n this._fovAxis = value;\r\n this._needUpdate(0); // Ensure matrix built on next \"tick\"\r\n this.fire(\"fovAxis\", this._fovAxis);\r\n }\r\n\r\n /**\r\n * Gets the Perspective's FOV axis.\r\n *\r\n * Options are ````\"x\"````, ````\"y\"```` or ````\"min\"````, to use the minimum axis.\r\n *\r\n * Fires an \"fovAxis\" event on change.\r\n\r\n * Default value is ````\"min\"````.\r\n *\r\n * @returns {String} The current FOV axis value.\r\n */\r\n get fovAxis() {\r\n return this._fovAxis;\r\n }\r\n\r\n /**\r\n * Sets the position of the Perspective's near plane on the positive View-space Z-axis.\r\n *\r\n * Fires a \"near\" event on change.\r\n *\r\n * Default value is ````0.1````.\r\n *\r\n * @param {Number} value New Perspective near plane position.\r\n */\r\n set near(value) {\r\n const near = (value !== undefined && value !== null) ? value : 0.1;\r\n if (this._state.near === near) {\r\n return;\r\n }\r\n this._state.near = near;\r\n this._needUpdate(0); // Ensure matrix built on next \"tick\"\r\n this.fire(\"near\", this._state.near);\r\n }\r\n\r\n /**\r\n * Gets the position of the Perspective's near plane on the positive View-space Z-axis.\r\n *\r\n * Fires an \"emits\" emits on change.\r\n *\r\n * Default value is ````0.1````.\r\n *\r\n * @returns The Perspective's near plane position.\r\n */\r\n get near() {\r\n return this._state.near;\r\n }\r\n\r\n /**\r\n * Sets the position of this Perspective's far plane on the positive View-space Z-axis.\r\n *\r\n * Fires a \"far\" event on change.\r\n *\r\n * @param {Number} value New Perspective far plane position.\r\n */\r\n set far(value) {\r\n const far = (value !== undefined && value !== null) ? value : 2000.0;\r\n if (this._state.far === far) {\r\n return;\r\n }\r\n this._state.far = far;\r\n this._needUpdate(0); // Ensure matrix built on next \"tick\"\r\n this.fire(\"far\", this._state.far);\r\n }\r\n\r\n /**\r\n * Gets the position of this Perspective's far plane on the positive View-space Z-axis.\r\n *\r\n * @return {Number} The Perspective's far plane position.\r\n */\r\n get far() {\r\n return this._state.far;\r\n }\r\n\r\n /**\r\n * Gets the Perspective's projection transform matrix.\r\n *\r\n * Fires a \"matrix\" event on change.\r\n *\r\n * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\r\n *\r\n * @returns {Number[]} The Perspective's projection matrix.\r\n */\r\n get matrix() {\r\n if (this._updateScheduled) {\r\n this._doUpdate();\r\n }\r\n return this._state.matrix;\r\n }\r\n\r\n /**\r\n * Gets the inverse of {@link Perspective#matrix}.\r\n *\r\n * @returns {Number[]} The inverse of {@link Perspective#matrix}.\r\n */\r\n get inverseMatrix() {\r\n if (this._updateScheduled) {\r\n this._doUpdate();\r\n }\r\n if (this._inverseMatrixDirty) {\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(this._state.matrix, this._state.inverseMatrix);\r\n this._inverseMatrixDirty = false;\r\n }\r\n return this._state.inverseMatrix;\r\n }\r\n\r\n /**\r\n * Gets the transpose of {@link Perspective#matrix}.\r\n *\r\n * @returns {Number[]} The transpose of {@link Perspective#matrix}.\r\n */\r\n get transposedMatrix() {\r\n if (this._updateScheduled) {\r\n this._doUpdate();\r\n }\r\n if (this._transposedMatrixDirty) {\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transposeMat4(this._state.matrix, this._state.transposedMatrix);\r\n this._transposedMatrixDirty = false;\r\n }\r\n return this._state.transposedMatrix;\r\n }\r\n\r\n /**\r\n * Un-projects the given Canvas-space coordinates and Screen-space depth, using this Perspective projection.\r\n *\r\n * @param {Number[]} canvasPos Inputs 2D Canvas-space coordinates.\r\n * @param {Number} screenZ Inputs Screen-space Z coordinate.\r\n * @param {Number[]} screenPos Outputs 3D Screen/Clip-space coordinates.\r\n * @param {Number[]} viewPos Outputs un-projected 3D View-space coordinates.\r\n * @param {Number[]} worldPos Outputs un-projected 3D World-space coordinates.\r\n */\r\n unproject(canvasPos, screenZ, screenPos, viewPos, worldPos) {\r\n\r\n const canvas = this.scene.canvas.canvas;\r\n\r\n const halfCanvasWidth = canvas.offsetWidth / 2.0;\r\n const halfCanvasHeight = canvas.offsetHeight / 2.0;\r\n\r\n screenPos[0] = (canvasPos[0] - halfCanvasWidth) / halfCanvasWidth;\r\n screenPos[1] = (canvasPos[1] - halfCanvasHeight) / halfCanvasHeight;\r\n screenPos[2] = screenZ;\r\n screenPos[3] = 1.0;\r\n\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4v4(this.inverseMatrix, screenPos, viewPos);\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(viewPos, 1.0 / viewPos[3]);\r\n\r\n viewPos[3] = 1.0;\r\n viewPos[1] *= -1;\r\n\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4v4(this.camera.inverseViewMatrix, viewPos, worldPos);\r\n\r\n return worldPos;\r\n }\r\n\r\n /** @private\r\n *\r\n */\r\n destroy() {\r\n super.destroy();\r\n this._state.destroy();\r\n this.scene.canvas.off(this._canvasResized);\r\n }\r\n}\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/camera/Perspective.js?");
2727
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Perspective: () => (/* binding */ Perspective)\n/* harmony export */ });\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../webgl/RenderState.js */ \"./src/viewer/scene/webgl/RenderState.js\");\n\n\n\n\n/**\n * @desc Defines its {@link Camera}'s perspective projection using a field-of-view angle.\n *\n * * Located at {@link Camera#perspective}.\n * * Implicitly sets the left, right, top, bottom frustum planes using {@link Perspective#fov}.\n * * {@link Perspective#near} and {@link Perspective#far} specify the distances to the WebGL clipping planes.\n */\nclass Perspective extends _Component_js__WEBPACK_IMPORTED_MODULE_1__.Component {\n\t/**\n @private\n */\n\tget type() {\n\t\treturn \"Perspective\";\n\t}\n\n\t/**\n\t * @constructor\n\t * @private\n\t */\n\tconstructor(camera, cfg = {}) {\n\t\tsuper(camera, cfg);\n\n\t\t/**\n\t\t * The Camera this Perspective belongs to.\n\t\t *\n\t\t * @property camera\n\t\t * @type {Camera}\n\t\t * @final\n\t\t */\n\t\tthis.camera = camera;\n\n\t\tthis._state = new _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_2__.RenderState({\n\t\t\tmatrix: _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4(),\n\t\t\tinverseMatrix: _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4(),\n\t\t\ttransposedMatrix: _math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mat4(),\n\t\t\tnear: 0.1,\n\t\t\tfar: 2000.0\n\t\t});\n\n\t\tthis._inverseMatrixDirty = true;\n\t\tthis._transposedMatrixDirty = true;\n\n\t\tthis._fov = 60.0;\n\n\t\t// Recompute aspect from change in canvas size\n\t\tthis._canvasResized = this.scene.canvas.on(\"boundary\", this._needUpdate, this);\n\n\t\tthis.fov = cfg.fov;\n\t\tthis.fovAxis = cfg.fovAxis;\n\t\tthis.near = cfg.near;\n\t\tthis.far = cfg.far;\n\t}\n\n\t_update() {\n\t\tconst WIDTH_INDEX = 2;\n\t\tconst HEIGHT_INDEX = 3;\n\t\tconst boundary = this.scene.canvas.boundary;\n\t\tconst aspect = boundary[WIDTH_INDEX] / boundary[HEIGHT_INDEX];\n\t\tconst fovAxis = this._fovAxis;\n\n\t\tlet fov = this._fov;\n\t\tif (fovAxis === \"x\" || (fovAxis === \"min\" && aspect < 1) || (fovAxis === \"max\" && aspect > 1)) {\n\t\t\tfov = fov / aspect;\n\t\t}\n\t\tfov = Math.min(fov, 120);\n\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.perspectiveMat4(fov * (Math.PI / 180.0), aspect, this._state.near, this._state.far, this._state.matrix);\n\n\t\tthis._inverseMatrixDirty = true;\n\t\tthis._transposedMatrixDirty = true;\n\n\t\tthis.glRedraw();\n\n\t\tthis.camera._updateScheduled = true;\n\n\t\tthis.fire(\"matrix\", this._state.matrix);\n\t}\n\n\t/**\n * Sets the Perspective's field-of-view angle (FOV).\n *\n * Fires an \"fov\" event on change.\n\n * Default value is ````60.0````.\n *\n * @param {Number} value New field-of-view.\n */\n\tset fov(value) {\n\t\tvalue = value !== undefined && value !== null ? value : 60.0;\n\t\tif (value === this._fov) {\n\t\t\treturn;\n\t\t}\n\t\tthis._fov = value;\n\t\tthis._needUpdate(0); // Ensure matrix built on next \"tick\"\n\t\tthis.fire(\"fov\", this._fov);\n\t}\n\n\t/**\n\t * Gets the Perspective's field-of-view angle (FOV).\n\t *\n\t * Default value is ````60.0````.\n\t *\n\t * @returns {Number} Current field-of-view.\n\t */\n\tget fov() {\n\t\treturn this._fov;\n\t}\n\n\t/**\n * Sets the Perspective's FOV axis.\n *\n * Options are ````\"x\"````, ````\"y\"```` or ````\"min\"````, to use the minimum axis.\n *\n * Fires an \"fovAxis\" event on change.\n\n * Default value ````\"min\"````.\n *\n * @param {String} value New FOV axis value.\n */\n\tset fovAxis(value) {\n\t\tvalue = value || \"min\";\n\t\tif (this._fovAxis === value) {\n\t\t\treturn;\n\t\t}\n\t\tif (value !== \"x\" && value !== \"y\" && value !== \"min\") {\n\t\t\tthis.error(\"Unsupported value for 'fovAxis': \" + value + \" - defaulting to 'min'\");\n\t\t\tvalue = \"min\";\n\t\t}\n\t\tthis._fovAxis = value;\n\t\tthis._needUpdate(0); // Ensure matrix built on next \"tick\"\n\t\tthis.fire(\"fovAxis\", this._fovAxis);\n\t}\n\n\t/**\n * Gets the Perspective's FOV axis.\n *\n * Options are ````\"x\"````, ````\"y\"```` or ````\"min\"````, to use the minimum axis.\n *\n * Fires an \"fovAxis\" event on change.\n\n * Default value is ````\"min\"````.\n *\n * @returns {String} The current FOV axis value.\n */\n\tget fovAxis() {\n\t\treturn this._fovAxis;\n\t}\n\n\t/**\n\t * Sets the position of the Perspective's near plane on the positive View-space Z-axis.\n\t *\n\t * Fires a \"near\" event on change.\n\t *\n\t * Default value is ````0.1````.\n\t *\n\t * @param {Number} value New Perspective near plane position.\n\t */\n\tset near(value) {\n\t\tconst near = value !== undefined && value !== null ? value : 0.1;\n\t\tif (this._state.near === near) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state.near = near;\n\t\tthis._needUpdate(0); // Ensure matrix built on next \"tick\"\n\t\tthis.fire(\"near\", this._state.near);\n\t}\n\n\t/**\n\t * Gets the position of the Perspective's near plane on the positive View-space Z-axis.\n\t *\n\t * Fires an \"emits\" emits on change.\n\t *\n\t * Default value is ````0.1````.\n\t *\n\t * @returns The Perspective's near plane position.\n\t */\n\tget near() {\n\t\treturn this._state.near;\n\t}\n\n\t/**\n\t * Sets the position of this Perspective's far plane on the positive View-space Z-axis.\n\t *\n\t * Fires a \"far\" event on change.\n\t *\n\t * @param {Number} value New Perspective far plane position.\n\t */\n\tset far(value) {\n\t\tconst far = value !== undefined && value !== null ? value : 2000.0;\n\t\tif (this._state.far === far) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state.far = far;\n\t\tthis._needUpdate(0); // Ensure matrix built on next \"tick\"\n\t\tthis.fire(\"far\", this._state.far);\n\t}\n\n\t/**\n\t * Gets the position of this Perspective's far plane on the positive View-space Z-axis.\n\t *\n\t * @return {Number} The Perspective's far plane position.\n\t */\n\tget far() {\n\t\treturn this._state.far;\n\t}\n\n\t/**\n\t * Gets the Perspective's projection transform matrix.\n\t *\n\t * Fires a \"matrix\" event on change.\n\t *\n\t * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n\t *\n\t * @returns {Number[]} The Perspective's projection matrix.\n\t */\n\tget matrix() {\n\t\tif (this._updateScheduled) {\n\t\t\tthis._doUpdate();\n\t\t}\n\t\treturn this._state.matrix;\n\t}\n\n\t/**\n\t * Gets the inverse of {@link Perspective#matrix}.\n\t *\n\t * @returns {Number[]} The inverse of {@link Perspective#matrix}.\n\t */\n\tget inverseMatrix() {\n\t\tif (this._updateScheduled) {\n\t\t\tthis._doUpdate();\n\t\t}\n\t\tif (this._inverseMatrixDirty) {\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.inverseMat4(this._state.matrix, this._state.inverseMatrix);\n\t\t\tthis._inverseMatrixDirty = false;\n\t\t}\n\t\treturn this._state.inverseMatrix;\n\t}\n\n\t/**\n\t * Gets the transpose of {@link Perspective#matrix}.\n\t *\n\t * @returns {Number[]} The transpose of {@link Perspective#matrix}.\n\t */\n\tget transposedMatrix() {\n\t\tif (this._updateScheduled) {\n\t\t\tthis._doUpdate();\n\t\t}\n\t\tif (this._transposedMatrixDirty) {\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.transposeMat4(this._state.matrix, this._state.transposedMatrix);\n\t\t\tthis._transposedMatrixDirty = false;\n\t\t}\n\t\treturn this._state.transposedMatrix;\n\t}\n\n\t/**\n\t * Un-projects the given Canvas-space coordinates and Screen-space depth, using this Perspective projection.\n\t *\n\t * @param {Number[]} canvasPos Inputs 2D Canvas-space coordinates.\n\t * @param {Number} screenZ Inputs Screen-space Z coordinate.\n\t * @param {Number[]} screenPos Outputs 3D Screen/Clip-space coordinates.\n\t * @param {Number[]} viewPos Outputs un-projected 3D View-space coordinates.\n\t * @param {Number[]} worldPos Outputs un-projected 3D World-space coordinates.\n\t */\n\tunproject(canvasPos, screenZ, screenPos, viewPos, worldPos) {\n\t\tconst canvas = this.scene.canvas.canvas;\n\n\t\tconst halfCanvasWidth = canvas.offsetWidth / 2.0;\n\t\tconst halfCanvasHeight = canvas.offsetHeight / 2.0;\n\n\t\tscreenPos[0] = (canvasPos[0] - halfCanvasWidth) / halfCanvasWidth;\n\t\tscreenPos[1] = (canvasPos[1] - halfCanvasHeight) / halfCanvasHeight;\n\t\tscreenPos[2] = screenZ;\n\t\tscreenPos[3] = 1.0;\n\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4v4(this.inverseMatrix, screenPos, viewPos);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulVec3Scalar(viewPos, 1.0 / viewPos[3]);\n\n\t\tviewPos[3] = 1.0;\n\t\tviewPos[1] *= -1;\n\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_0__.math.mulMat4v4(this.camera.inverseViewMatrix, viewPos, worldPos);\n\n\t\treturn worldPos;\n\t}\n\n\t/** @private\n\t *\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\t\tthis._state.destroy();\n\t\tthis.scene.canvas.off(this._canvasResized);\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/camera/Perspective.js?");
2718
2728
 
2719
2729
  /***/ }),
2720
2730
 
@@ -2748,13 +2758,23 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2748
2758
 
2749
2759
  /***/ }),
2750
2760
 
2761
+ /***/ "./src/viewer/scene/canvas/index.js":
2762
+ /*!******************************************!*\
2763
+ !*** ./src/viewer/scene/canvas/index.js ***!
2764
+ \******************************************/
2765
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2766
+
2767
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Canvas: () => (/* reexport safe */ _Canvas_js__WEBPACK_IMPORTED_MODULE_0__.Canvas)\n/* harmony export */ });\n/* harmony import */ var _Canvas_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Canvas.js */ \"./src/viewer/scene/canvas/Canvas.js\");\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/canvas/index.js?");
2768
+
2769
+ /***/ }),
2770
+
2751
2771
  /***/ "./src/viewer/scene/constants/constants.js":
2752
2772
  /*!*************************************************!*\
2753
2773
  !*** ./src/viewer/scene/constants/constants.js ***!
2754
2774
  \*************************************************/
2755
2775
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2756
2776
 
2757
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AlphaFormat: () => (/* binding */ AlphaFormat),\n/* harmony export */ ByteType: () => (/* binding */ ByteType),\n/* harmony export */ ClampToEdgeWrapping: () => (/* binding */ ClampToEdgeWrapping),\n/* harmony export */ CompressedMediaType: () => (/* binding */ CompressedMediaType),\n/* harmony export */ DepthFormat: () => (/* binding */ DepthFormat),\n/* harmony export */ DepthStencilFormat: () => (/* binding */ DepthStencilFormat),\n/* harmony export */ FloatType: () => (/* binding */ FloatType),\n/* harmony export */ GIFMediaType: () => (/* binding */ GIFMediaType),\n/* harmony export */ HalfFloatType: () => (/* binding */ HalfFloatType),\n/* harmony export */ IntType: () => (/* binding */ IntType),\n/* harmony export */ JPEGMediaType: () => (/* binding */ JPEGMediaType),\n/* harmony export */ LinearEncoding: () => (/* binding */ LinearEncoding),\n/* harmony export */ LinearFilter: () => (/* binding */ LinearFilter),\n/* harmony export */ LinearMipMapLinearFilter: () => (/* binding */ LinearMipMapLinearFilter),\n/* harmony export */ LinearMipMapNearestFilter: () => (/* binding */ LinearMipMapNearestFilter),\n/* harmony export */ LinearMipmapLinearFilter: () => (/* binding */ LinearMipmapLinearFilter),\n/* harmony export */ LinearMipmapNearestFilter: () => (/* binding */ LinearMipmapNearestFilter),\n/* harmony export */ LuminanceAlphaFormat: () => (/* binding */ LuminanceAlphaFormat),\n/* harmony export */ LuminanceFormat: () => (/* binding */ LuminanceFormat),\n/* harmony export */ MirroredRepeatWrapping: () => (/* binding */ MirroredRepeatWrapping),\n/* harmony export */ NearestFilter: () => (/* binding */ NearestFilter),\n/* harmony export */ NearestMipMapLinearFilter: () => (/* binding */ NearestMipMapLinearFilter),\n/* harmony export */ NearestMipMapNearestFilter: () => (/* binding */ NearestMipMapNearestFilter),\n/* harmony export */ NearestMipmapLinearFilter: () => (/* binding */ NearestMipmapLinearFilter),\n/* harmony export */ NearestMipmapNearestFilter: () => (/* binding */ NearestMipmapNearestFilter),\n/* harmony export */ PNGMediaType: () => (/* binding */ PNGMediaType),\n/* harmony export */ RGBAFormat: () => (/* binding */ RGBAFormat),\n/* harmony export */ RGBAIntegerFormat: () => (/* binding */ RGBAIntegerFormat),\n/* harmony export */ RGBA_ASTC_10x10_Format: () => (/* binding */ RGBA_ASTC_10x10_Format),\n/* harmony export */ RGBA_ASTC_10x5_Format: () => (/* binding */ RGBA_ASTC_10x5_Format),\n/* harmony export */ RGBA_ASTC_10x6_Format: () => (/* binding */ RGBA_ASTC_10x6_Format),\n/* harmony export */ RGBA_ASTC_10x8_Format: () => (/* binding */ RGBA_ASTC_10x8_Format),\n/* harmony export */ RGBA_ASTC_12x10_Format: () => (/* binding */ RGBA_ASTC_12x10_Format),\n/* harmony export */ RGBA_ASTC_12x12_Format: () => (/* binding */ RGBA_ASTC_12x12_Format),\n/* harmony export */ RGBA_ASTC_4x4_Format: () => (/* binding */ RGBA_ASTC_4x4_Format),\n/* harmony export */ RGBA_ASTC_5x4_Format: () => (/* binding */ RGBA_ASTC_5x4_Format),\n/* harmony export */ RGBA_ASTC_5x5_Format: () => (/* binding */ RGBA_ASTC_5x5_Format),\n/* harmony export */ RGBA_ASTC_6x5_Format: () => (/* binding */ RGBA_ASTC_6x5_Format),\n/* harmony export */ RGBA_ASTC_6x6_Format: () => (/* binding */ RGBA_ASTC_6x6_Format),\n/* harmony export */ RGBA_ASTC_8x5_Format: () => (/* binding */ RGBA_ASTC_8x5_Format),\n/* harmony export */ RGBA_ASTC_8x6_Format: () => (/* binding */ RGBA_ASTC_8x6_Format),\n/* harmony export */ RGBA_ASTC_8x8_Format: () => (/* binding */ RGBA_ASTC_8x8_Format),\n/* harmony export */ RGBA_BPTC_Format: () => (/* binding */ RGBA_BPTC_Format),\n/* harmony export */ RGBA_ETC2_EAC_Format: () => (/* binding */ RGBA_ETC2_EAC_Format),\n/* harmony export */ RGBA_PVRTC_2BPPV1_Format: () => (/* binding */ RGBA_PVRTC_2BPPV1_Format),\n/* harmony export */ RGBA_PVRTC_4BPPV1_Format: () => (/* binding */ RGBA_PVRTC_4BPPV1_Format),\n/* harmony export */ RGBA_S3TC_DXT1_Format: () => (/* binding */ RGBA_S3TC_DXT1_Format),\n/* harmony export */ RGBA_S3TC_DXT3_Format: () => (/* binding */ RGBA_S3TC_DXT3_Format),\n/* harmony export */ RGBA_S3TC_DXT5_Format: () => (/* binding */ RGBA_S3TC_DXT5_Format),\n/* harmony export */ RGBFormat: () => (/* binding */ RGBFormat),\n/* harmony export */ RGB_ETC1_Format: () => (/* binding */ RGB_ETC1_Format),\n/* harmony export */ RGB_ETC2_Format: () => (/* binding */ RGB_ETC2_Format),\n/* harmony export */ RGB_PVRTC_2BPPV1_Format: () => (/* binding */ RGB_PVRTC_2BPPV1_Format),\n/* harmony export */ RGB_PVRTC_4BPPV1_Format: () => (/* binding */ RGB_PVRTC_4BPPV1_Format),\n/* harmony export */ RGB_S3TC_DXT1_Format: () => (/* binding */ RGB_S3TC_DXT1_Format),\n/* harmony export */ RGFormat: () => (/* binding */ RGFormat),\n/* harmony export */ RGIntegerFormat: () => (/* binding */ RGIntegerFormat),\n/* harmony export */ RedFormat: () => (/* binding */ RedFormat),\n/* harmony export */ RedIntegerFormat: () => (/* binding */ RedIntegerFormat),\n/* harmony export */ RepeatWrapping: () => (/* binding */ RepeatWrapping),\n/* harmony export */ ShortType: () => (/* binding */ ShortType),\n/* harmony export */ UnsignedByteType: () => (/* binding */ UnsignedByteType),\n/* harmony export */ UnsignedInt248Type: () => (/* binding */ UnsignedInt248Type),\n/* harmony export */ UnsignedIntType: () => (/* binding */ UnsignedIntType),\n/* harmony export */ UnsignedShort4444Type: () => (/* binding */ UnsignedShort4444Type),\n/* harmony export */ UnsignedShort5551Type: () => (/* binding */ UnsignedShort5551Type),\n/* harmony export */ UnsignedShortType: () => (/* binding */ UnsignedShortType),\n/* harmony export */ sRGBEncoding: () => (/* binding */ sRGBEncoding)\n/* harmony export */ });\n/**\r\n * Texture wrapping mode in which the texture repeats to infinity.\r\n */\r\nconst RepeatWrapping = 1000;\r\n\r\n/**\r\n * Texture wrapping mode in which the last pixel of the texture stretches to the edge of the mesh.\r\n */\r\nconst ClampToEdgeWrapping = 1001;\r\n\r\n/**\r\n * Texture wrapping mode in which the texture repeats to infinity, mirroring on each repeat.\r\n */\r\nconst MirroredRepeatWrapping = 1002;\r\n\r\n/**\r\n * Texture magnification and minification filter that returns the nearest texel to the given sample coordinates.\r\n */\r\nconst NearestFilter = 1003;\r\n\r\n/**\r\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and returns the nearest texel to the given sample coordinates.\r\n */\r\nconst NearestMipMapNearestFilter = 1004;\r\n\r\n/**\r\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured\r\n * and returns the nearest texel to the given sample coordinates.\r\n */\r\nconst NearestMipmapNearestFilter = 1004;\r\n\r\n/**\r\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\r\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\r\n */\r\nconst NearestMipmapLinearFilter = 1005;\r\n\r\n/**\r\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\r\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\r\n */\r\nconst NearestMipMapLinearFilter = 1005;\r\n\r\n/**\r\n * Texture magnification and minification filter that returns the weighted average of the four nearest texels to the given sample coordinates.\r\n */\r\nconst LinearFilter = 1006;\r\n\r\n/**\r\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\r\n * returns the weighted average of the four nearest texels to the given sample coordinates.\r\n */\r\nconst LinearMipmapNearestFilter = 1007;\r\n\r\n/**\r\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\r\n * returns the weighted average of the four nearest texels to the given sample coordinates.\r\n */\r\nconst LinearMipMapNearestFilter = 1007;\r\n\r\n/**\r\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\r\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\r\n * weighted average of those two values.\r\n */\r\nconst LinearMipmapLinearFilter = 1008;\r\n\r\n/**\r\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\r\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\r\n * weighted average of those two values.\r\n */\r\nconst LinearMipMapLinearFilter = 1008;\r\n\r\n/**\r\n * Unsigned 8-bit integer type.\r\n */\r\nconst UnsignedByteType = 1009;\r\n\r\n/**\r\n * Signed 8-bit integer type.\r\n */\r\nconst ByteType = 1010;\r\n\r\n/**\r\n * Signed 16-bit integer type.\r\n */\r\nconst ShortType = 1011;\r\n\r\n/**\r\n * Unsigned 16-bit integer type.\r\n */\r\nconst UnsignedShortType = 1012;\r\n\r\n/**\r\n * Signed 32-bit integer type.\r\n */\r\nconst IntType = 1013;\r\n\r\n/**\r\n * Unsigned 32-bit integer type.\r\n */\r\nconst UnsignedIntType = 1014;\r\n\r\n/**\r\n * Signed 32-bit floating-point type.\r\n */\r\nconst FloatType = 1015;\r\n\r\n/**\r\n * Signed 16-bit half-precision floating-point type.\r\n */\r\nconst HalfFloatType = 1016;\r\n\r\n/**\r\n * Texture packing mode in which each ````RGBA```` channel is packed into 4 bits, for a combined total of 16 bits.\r\n */\r\nconst UnsignedShort4444Type = 1017;\r\n\r\n/**\r\n * Texture packing mode in which the ````RGB```` channels are each packed into 5 bits, and the ````A```` channel is packed into 1 bit, for a combined total of 16 bits.\r\n */\r\nconst UnsignedShort5551Type = 1018;\r\n\r\n/**\r\n * Unsigned integer type for 24-bit depth texture data.\r\n */\r\nconst UnsignedInt248Type = 1020;\r\n\r\n/**\r\n * Texture sampling mode that discards the ````RGBA```` components and just reads the ````A```` component.\r\n */\r\nconst AlphaFormat = 1021;\r\n\r\n/**\r\n * Texture sampling mode that discards the ````A```` component and reads the ````RGB```` components.\r\n */\r\nconst RGBFormat = 1022;\r\n\r\n/**\r\n * Texture sampling mode that reads the ````RGBA```` components.\r\n */\r\nconst RGBAFormat = 1023;\r\n\r\n/**\r\n * Texture sampling mode that reads each ````RGB```` texture component as a luminance value, converted to a float and clamped\r\n * to ````[0,1]````, while always reading the ````A```` channel as ````1.0````.\r\n */\r\nconst LuminanceFormat = 1024;\r\n\r\n/**\r\n * Texture sampling mode that reads each of the ````RGBA```` texture components as a luminance/alpha value, converted to a float and clamped to ````[0,1]````.\r\n */\r\nconst LuminanceAlphaFormat = 1025;\r\n\r\n/**\r\n * Texture sampling mode that reads each element as a single depth value, converts it to a float and clamps to ````[0,1]````.\r\n */\r\nconst DepthFormat = 1026;\r\n\r\n/**\r\n * Texture sampling mode that\r\n */\r\nconst DepthStencilFormat = 1027;\r\n\r\n/**\r\n * Texture sampling mode that discards the ````GBA```` components and just reads the ````R```` component.\r\n */\r\nconst RedFormat = 1028;\r\n\r\n/**\r\n * Texture sampling mode that discards the ````GBA```` components and just reads the ````R```` component, as an integer instead of as a float.\r\n */\r\nconst RedIntegerFormat = 1029;\r\n\r\n/**\r\n * Texture sampling mode that discards the ````A```` and ````B```` components and just reads the ````R```` and ````G```` components.\r\n */\r\nconst RGFormat = 1030;\r\n\r\n/**\r\n * Texture sampling mode that discards the ````A```` and ````B```` components and just reads the ````R```` and ````G```` components, as integers instead of floats.\r\n */\r\nconst RGIntegerFormat = 1031;\r\n\r\n/**\r\n * Texture sampling mode that reads the ````RGBA```` components as integers instead of floats.\r\n */\r\nconst RGBAIntegerFormat = 1033;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT1 compressed</a> ````RGB```` image.\r\n */\r\nconst RGB_S3TC_DXT1_Format = 33776;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT1 compressed</a> ````RGBA```` image.\r\n */\r\nconst RGBA_S3TC_DXT1_Format = 33777;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT3 compressed</a> ````RGBA```` image.\r\n */\r\nconst RGBA_S3TC_DXT3_Format = 33778;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT5 compressed</a> ````RGBA```` image.\r\n */\r\nconst RGBA_S3TC_DXT5_Format = 33779;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\r\n * image, with ````RGB```` compression in 4-bit mode and one block for each 4×4 pixels.\r\n */\r\nconst RGB_PVRTC_4BPPV1_Format = 35840;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\r\n * image, with ````RGB```` compression in 2-bit mode and one block for each 8×4 pixels.\r\n */\r\nconst RGB_PVRTC_2BPPV1_Format = 35841;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\r\n * image, with ````RGBA```` compression in 4-bit mode and one block for each 4×4 pixels.\r\n */\r\nconst RGBA_PVRTC_4BPPV1_Format = 35842;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\r\n * image, with ````RGBA```` compression in 2-bit mode and one block for each 8×4 pixels.\r\n */\r\nconst RGBA_PVRTC_2BPPV1_Format = 35843;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc1/\">ETC1 compressed</a>\r\n * ````RGB```` image.\r\n */\r\nconst RGB_ETC1_Format = 36196;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc2/\">ETC2 compressed</a>\r\n * ````RGB```` image.\r\n */\r\nconst RGB_ETC2_Format = 37492;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc2/\">ETC2 compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ETC2_EAC_Format = 37496;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_4x4_Format = 37808;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_5x4_Format = 37809;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_5x5_Format = 37810;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_6x5_Format = 37811;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_6x6_Format = 37812;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_8x5_Format = 37813;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_8x6_Format = 37814;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_8x8_Format = 37815;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_10x5_Format = 37816;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_10x6_Format = 37817;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_10x8_Format = 37818;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_10x10_Format = 37819;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_12x10_Format = 37820;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_ASTC_12x12_Format = 37821;\r\n\r\n/**\r\n * Texture format mode in which the texture is formatted as an <a href=\"https://www.khronos.org/opengl/wiki/BPTC_Texture_Compression\">BPTC compressed</a>\r\n * ````RGBA```` image.\r\n */\r\nconst RGBA_BPTC_Format = 36492;\r\n\r\n/**\r\n * Texture encoding mode in which the texture image is in linear color space.\r\n */\r\nconst LinearEncoding = 3000;\r\n\r\n/**\r\n * Texture encoding mode in which the texture image is in sRGB color space.\r\n */\r\nconst sRGBEncoding = 3001;\r\n\r\n/**\r\n * Media type for GIF images.\r\n */\r\nconst GIFMediaType = 10000;\r\n\r\n/**\r\n * Media type for JPEG images.\r\n */\r\nconst JPEGMediaType = 10001;\r\n\r\n/**\r\n * Media type for PNG images.\r\n */\r\nconst PNGMediaType = 10002;\r\n\r\n/**\r\n * Media type for compressed texture data.\r\n */\r\nconst CompressedMediaType = 10003;\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/constants/constants.js?");
2777
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AlphaFormat: () => (/* binding */ AlphaFormat),\n/* harmony export */ ByteType: () => (/* binding */ ByteType),\n/* harmony export */ ClampToEdgeWrapping: () => (/* binding */ ClampToEdgeWrapping),\n/* harmony export */ CompressedMediaType: () => (/* binding */ CompressedMediaType),\n/* harmony export */ DepthFormat: () => (/* binding */ DepthFormat),\n/* harmony export */ DepthStencilFormat: () => (/* binding */ DepthStencilFormat),\n/* harmony export */ FloatType: () => (/* binding */ FloatType),\n/* harmony export */ GIFMediaType: () => (/* binding */ GIFMediaType),\n/* harmony export */ HalfFloatType: () => (/* binding */ HalfFloatType),\n/* harmony export */ IntType: () => (/* binding */ IntType),\n/* harmony export */ JPEGMediaType: () => (/* binding */ JPEGMediaType),\n/* harmony export */ LinearEncoding: () => (/* binding */ LinearEncoding),\n/* harmony export */ LinearFilter: () => (/* binding */ LinearFilter),\n/* harmony export */ LinearMipMapLinearFilter: () => (/* binding */ LinearMipMapLinearFilter),\n/* harmony export */ LinearMipMapNearestFilter: () => (/* binding */ LinearMipMapNearestFilter),\n/* harmony export */ LinearMipmapLinearFilter: () => (/* binding */ LinearMipmapLinearFilter),\n/* harmony export */ LinearMipmapNearestFilter: () => (/* binding */ LinearMipmapNearestFilter),\n/* harmony export */ LuminanceAlphaFormat: () => (/* binding */ LuminanceAlphaFormat),\n/* harmony export */ LuminanceFormat: () => (/* binding */ LuminanceFormat),\n/* harmony export */ MirroredRepeatWrapping: () => (/* binding */ MirroredRepeatWrapping),\n/* harmony export */ NearestFilter: () => (/* binding */ NearestFilter),\n/* harmony export */ NearestMipMapLinearFilter: () => (/* binding */ NearestMipMapLinearFilter),\n/* harmony export */ NearestMipMapNearestFilter: () => (/* binding */ NearestMipMapNearestFilter),\n/* harmony export */ NearestMipmapLinearFilter: () => (/* binding */ NearestMipmapLinearFilter),\n/* harmony export */ NearestMipmapNearestFilter: () => (/* binding */ NearestMipmapNearestFilter),\n/* harmony export */ PNGMediaType: () => (/* binding */ PNGMediaType),\n/* harmony export */ RGBAFormat: () => (/* binding */ RGBAFormat),\n/* harmony export */ RGBAIntegerFormat: () => (/* binding */ RGBAIntegerFormat),\n/* harmony export */ RGBA_ASTC_10x10_Format: () => (/* binding */ RGBA_ASTC_10x10_Format),\n/* harmony export */ RGBA_ASTC_10x5_Format: () => (/* binding */ RGBA_ASTC_10x5_Format),\n/* harmony export */ RGBA_ASTC_10x6_Format: () => (/* binding */ RGBA_ASTC_10x6_Format),\n/* harmony export */ RGBA_ASTC_10x8_Format: () => (/* binding */ RGBA_ASTC_10x8_Format),\n/* harmony export */ RGBA_ASTC_12x10_Format: () => (/* binding */ RGBA_ASTC_12x10_Format),\n/* harmony export */ RGBA_ASTC_12x12_Format: () => (/* binding */ RGBA_ASTC_12x12_Format),\n/* harmony export */ RGBA_ASTC_4x4_Format: () => (/* binding */ RGBA_ASTC_4x4_Format),\n/* harmony export */ RGBA_ASTC_5x4_Format: () => (/* binding */ RGBA_ASTC_5x4_Format),\n/* harmony export */ RGBA_ASTC_5x5_Format: () => (/* binding */ RGBA_ASTC_5x5_Format),\n/* harmony export */ RGBA_ASTC_6x5_Format: () => (/* binding */ RGBA_ASTC_6x5_Format),\n/* harmony export */ RGBA_ASTC_6x6_Format: () => (/* binding */ RGBA_ASTC_6x6_Format),\n/* harmony export */ RGBA_ASTC_8x5_Format: () => (/* binding */ RGBA_ASTC_8x5_Format),\n/* harmony export */ RGBA_ASTC_8x6_Format: () => (/* binding */ RGBA_ASTC_8x6_Format),\n/* harmony export */ RGBA_ASTC_8x8_Format: () => (/* binding */ RGBA_ASTC_8x8_Format),\n/* harmony export */ RGBA_BPTC_Format: () => (/* binding */ RGBA_BPTC_Format),\n/* harmony export */ RGBA_ETC2_EAC_Format: () => (/* binding */ RGBA_ETC2_EAC_Format),\n/* harmony export */ RGBA_PVRTC_2BPPV1_Format: () => (/* binding */ RGBA_PVRTC_2BPPV1_Format),\n/* harmony export */ RGBA_PVRTC_4BPPV1_Format: () => (/* binding */ RGBA_PVRTC_4BPPV1_Format),\n/* harmony export */ RGBA_S3TC_DXT1_Format: () => (/* binding */ RGBA_S3TC_DXT1_Format),\n/* harmony export */ RGBA_S3TC_DXT3_Format: () => (/* binding */ RGBA_S3TC_DXT3_Format),\n/* harmony export */ RGBA_S3TC_DXT5_Format: () => (/* binding */ RGBA_S3TC_DXT5_Format),\n/* harmony export */ RGBFormat: () => (/* binding */ RGBFormat),\n/* harmony export */ RGB_ETC1_Format: () => (/* binding */ RGB_ETC1_Format),\n/* harmony export */ RGB_ETC2_Format: () => (/* binding */ RGB_ETC2_Format),\n/* harmony export */ RGB_PVRTC_2BPPV1_Format: () => (/* binding */ RGB_PVRTC_2BPPV1_Format),\n/* harmony export */ RGB_PVRTC_4BPPV1_Format: () => (/* binding */ RGB_PVRTC_4BPPV1_Format),\n/* harmony export */ RGB_S3TC_DXT1_Format: () => (/* binding */ RGB_S3TC_DXT1_Format),\n/* harmony export */ RGFormat: () => (/* binding */ RGFormat),\n/* harmony export */ RGIntegerFormat: () => (/* binding */ RGIntegerFormat),\n/* harmony export */ RedFormat: () => (/* binding */ RedFormat),\n/* harmony export */ RedIntegerFormat: () => (/* binding */ RedIntegerFormat),\n/* harmony export */ RepeatWrapping: () => (/* binding */ RepeatWrapping),\n/* harmony export */ ShortType: () => (/* binding */ ShortType),\n/* harmony export */ UnsignedByteType: () => (/* binding */ UnsignedByteType),\n/* harmony export */ UnsignedInt248Type: () => (/* binding */ UnsignedInt248Type),\n/* harmony export */ UnsignedIntType: () => (/* binding */ UnsignedIntType),\n/* harmony export */ UnsignedShort4444Type: () => (/* binding */ UnsignedShort4444Type),\n/* harmony export */ UnsignedShort5551Type: () => (/* binding */ UnsignedShort5551Type),\n/* harmony export */ UnsignedShortType: () => (/* binding */ UnsignedShortType),\n/* harmony export */ sRGBEncoding: () => (/* binding */ sRGBEncoding)\n/* harmony export */ });\n/**\n * Texture wrapping mode in which the texture repeats to infinity.\n */\nconst RepeatWrapping = 1000;\n\n/**\n * Texture wrapping mode in which the last pixel of the texture stretches to the edge of the mesh.\n */\nconst ClampToEdgeWrapping = 1001;\n\n/**\n * Texture wrapping mode in which the texture repeats to infinity, mirroring on each repeat.\n */\nconst MirroredRepeatWrapping = 1002;\n\n/**\n * Texture magnification and minification filter that returns the nearest texel to the given sample coordinates.\n */\nconst NearestFilter = 1003;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and returns the nearest texel to the given sample coordinates.\n */\nconst NearestMipMapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured\n * and returns the nearest texel to the given sample coordinates.\n */\nconst NearestMipmapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nconst NearestMipmapLinearFilter = 1005;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nconst NearestMipMapLinearFilter = 1005;\n\n/**\n * Texture magnification and minification filter that returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nconst LinearFilter = 1006;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nconst LinearMipmapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nconst LinearMipMapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nconst LinearMipmapLinearFilter = 1008;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nconst LinearMipMapLinearFilter = 1008;\n\n/**\n * Unsigned 8-bit integer type.\n */\nconst UnsignedByteType = 1009;\n\n/**\n * Signed 8-bit integer type.\n */\nconst ByteType = 1010;\n\n/**\n * Signed 16-bit integer type.\n */\nconst ShortType = 1011;\n\n/**\n * Unsigned 16-bit integer type.\n */\nconst UnsignedShortType = 1012;\n\n/**\n * Signed 32-bit integer type.\n */\nconst IntType = 1013;\n\n/**\n * Unsigned 32-bit integer type.\n */\nconst UnsignedIntType = 1014;\n\n/**\n * Signed 32-bit floating-point type.\n */\nconst FloatType = 1015;\n\n/**\n * Signed 16-bit half-precision floating-point type.\n */\nconst HalfFloatType = 1016;\n\n/**\n * Texture packing mode in which each ````RGBA```` channel is packed into 4 bits, for a combined total of 16 bits.\n */\nconst UnsignedShort4444Type = 1017;\n\n/**\n * Texture packing mode in which the ````RGB```` channels are each packed into 5 bits, and the ````A```` channel is packed into 1 bit, for a combined total of 16 bits.\n */\nconst UnsignedShort5551Type = 1018;\n\n/**\n * Unsigned integer type for 24-bit depth texture data.\n */\nconst UnsignedInt248Type = 1020;\n\n/**\n * Texture sampling mode that discards the ````RGBA```` components and just reads the ````A```` component.\n */\nconst AlphaFormat = 1021;\n\n/**\n * Texture sampling mode that discards the ````A```` component and reads the ````RGB```` components.\n */\nconst RGBFormat = 1022;\n\n/**\n * Texture sampling mode that reads the ````RGBA```` components.\n */\nconst RGBAFormat = 1023;\n\n/**\n * Texture sampling mode that reads each ````RGB```` texture component as a luminance value, converted to a float and clamped\n * to ````[0,1]````, while always reading the ````A```` channel as ````1.0````.\n */\nconst LuminanceFormat = 1024;\n\n/**\n * Texture sampling mode that reads each of the ````RGBA```` texture components as a luminance/alpha value, converted to a float and clamped to ````[0,1]````.\n */\nconst LuminanceAlphaFormat = 1025;\n\n/**\n * Texture sampling mode that reads each element as a single depth value, converts it to a float and clamps to ````[0,1]````.\n */\nconst DepthFormat = 1026;\n\n/**\n * Texture sampling mode that\n */\nconst DepthStencilFormat = 1027;\n\n/**\n * Texture sampling mode that discards the ````GBA```` components and just reads the ````R```` component.\n */\nconst RedFormat = 1028;\n\n/**\n * Texture sampling mode that discards the ````GBA```` components and just reads the ````R```` component, as an integer instead of as a float.\n */\nconst RedIntegerFormat = 1029;\n\n/**\n * Texture sampling mode that discards the ````A```` and ````B```` components and just reads the ````R```` and ````G```` components.\n */\nconst RGFormat = 1030;\n\n/**\n * Texture sampling mode that discards the ````A```` and ````B```` components and just reads the ````R```` and ````G```` components, as integers instead of floats.\n */\nconst RGIntegerFormat = 1031;\n\n/**\n * Texture sampling mode that reads the ````RGBA```` components as integers instead of floats.\n */\nconst RGBAIntegerFormat = 1033;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT1 compressed</a> ````RGB```` image.\n */\nconst RGB_S3TC_DXT1_Format = 33776;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT1 compressed</a> ````RGBA```` image.\n */\nconst RGBA_S3TC_DXT1_Format = 33777;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT3 compressed</a> ````RGBA```` image.\n */\nconst RGBA_S3TC_DXT3_Format = 33778;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT5 compressed</a> ````RGBA```` image.\n */\nconst RGBA_S3TC_DXT5_Format = 33779;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\n * image, with ````RGB```` compression in 4-bit mode and one block for each 4×4 pixels.\n */\nconst RGB_PVRTC_4BPPV1_Format = 35840;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\n * image, with ````RGB```` compression in 2-bit mode and one block for each 8×4 pixels.\n */\nconst RGB_PVRTC_2BPPV1_Format = 35841;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\n * image, with ````RGBA```` compression in 4-bit mode and one block for each 4×4 pixels.\n */\nconst RGBA_PVRTC_4BPPV1_Format = 35842;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\n * image, with ````RGBA```` compression in 2-bit mode and one block for each 8×4 pixels.\n */\nconst RGBA_PVRTC_2BPPV1_Format = 35843;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc1/\">ETC1 compressed</a>\n * ````RGB```` image.\n */\nconst RGB_ETC1_Format = 36196;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc2/\">ETC2 compressed</a>\n * ````RGB```` image.\n */\nconst RGB_ETC2_Format = 37492;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc2/\">ETC2 compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ETC2_EAC_Format = 37496;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_4x4_Format = 37808;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_5x4_Format = 37809;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_5x5_Format = 37810;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_6x5_Format = 37811;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_6x6_Format = 37812;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_8x5_Format = 37813;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_8x6_Format = 37814;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_8x8_Format = 37815;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_10x5_Format = 37816;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_10x6_Format = 37817;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_10x8_Format = 37818;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_10x10_Format = 37819;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_12x10_Format = 37820;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_12x12_Format = 37821;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://www.khronos.org/opengl/wiki/BPTC_Texture_Compression\">BPTC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_BPTC_Format = 36492;\n\n/**\n * Texture encoding mode in which the texture image is in linear color space.\n */\nconst LinearEncoding = 3000;\n\n/**\n * Texture encoding mode in which the texture image is in sRGB color space.\n */\nconst sRGBEncoding = 3001;\n\n/**\n * Media type for GIF images.\n */\nconst GIFMediaType = 10000;\n\n/**\n * Media type for JPEG images.\n */\nconst JPEGMediaType = 10001;\n\n/**\n * Media type for PNG images.\n */\nconst PNGMediaType = 10002;\n\n/**\n * Media type for compressed texture data.\n */\nconst CompressedMediaType = 10003;\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/constants/constants.js?");
2758
2778
 
2759
2779
  /***/ }),
2760
2780
 
@@ -2934,7 +2954,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2934
2954
  \***********************************/
2935
2955
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2936
2956
 
2937
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AlphaFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.AlphaFormat),\n/* harmony export */ AmbientLight: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_5__.AmbientLight),\n/* harmony export */ Bitmap: () => (/* reexport safe */ _Bitmap_index_js__WEBPACK_IMPORTED_MODULE_3__.Bitmap),\n/* harmony export */ ByteType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.ByteType),\n/* harmony export */ CameraMemento: () => (/* reexport safe */ _mementos_index_js__WEBPACK_IMPORTED_MODULE_9__.CameraMemento),\n/* harmony export */ CameraPath: () => (/* reexport safe */ _camera_index_js__WEBPACK_IMPORTED_MODULE_0__.CameraPath),\n/* harmony export */ CameraPathAnimation: () => (/* reexport safe */ _camera_index_js__WEBPACK_IMPORTED_MODULE_0__.CameraPathAnimation),\n/* harmony export */ ClampToEdgeWrapping: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.ClampToEdgeWrapping),\n/* harmony export */ Component: () => (/* reexport safe */ _Component_js__WEBPACK_IMPORTED_MODULE_18__.Component),\n/* harmony export */ CompressedMediaType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.CompressedMediaType),\n/* harmony export */ CubicBezierCurve: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_12__.CubicBezierCurve),\n/* harmony export */ Curve: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_12__.Curve),\n/* harmony export */ DefaultLoadingManager: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_17__.DefaultLoadingManager),\n/* harmony export */ DepthFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.DepthFormat),\n/* harmony export */ DepthStencilFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.DepthStencilFormat),\n/* harmony export */ DirLight: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_5__.DirLight),\n/* harmony export */ EdgeMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_7__.EdgeMaterial),\n/* harmony export */ EmphasisMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_7__.EmphasisMaterial),\n/* harmony export */ FloatType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.FloatType),\n/* harmony export */ Fresnel: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_7__.Fresnel),\n/* harmony export */ Frustum: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.Frustum),\n/* harmony export */ FrustumPlane: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.FrustumPlane),\n/* harmony export */ GIFMediaType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.GIFMediaType),\n/* harmony export */ HalfFloatType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.HalfFloatType),\n/* harmony export */ ImagePlane: () => (/* reexport safe */ _ImagePlane_index_js__WEBPACK_IMPORTED_MODULE_2__.ImagePlane),\n/* harmony export */ IntType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.IntType),\n/* harmony export */ JPEGMediaType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.JPEGMediaType),\n/* harmony export */ KTX2TextureTranscoder: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_17__.KTX2TextureTranscoder),\n/* harmony export */ LambertMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_7__.LambertMaterial),\n/* harmony export */ LightMap: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_5__.LightMap),\n/* harmony export */ LineSet: () => (/* reexport safe */ _LineSet_index_js__WEBPACK_IMPORTED_MODULE_4__.LineSet),\n/* harmony export */ LinearEncoding: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearEncoding),\n/* harmony export */ LinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearFilter),\n/* harmony export */ LinearMipMapLinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipMapLinearFilter),\n/* harmony export */ LinearMipMapNearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipMapNearestFilter),\n/* harmony export */ LinearMipmapLinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipmapLinearFilter),\n/* harmony export */ LinearMipmapNearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipmapNearestFilter),\n/* harmony export */ Loader: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_17__.Loader),\n/* harmony export */ LoadingManager: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_17__.LoadingManager),\n/* harmony export */ LuminanceAlphaFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LuminanceAlphaFormat),\n/* harmony export */ LuminanceFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LuminanceFormat),\n/* harmony export */ Map: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_17__.Map),\n/* harmony export */ Marker: () => (/* reexport safe */ _marker_index_js__WEBPACK_IMPORTED_MODULE_6__.Marker),\n/* harmony export */ Mesh: () => (/* reexport safe */ _mesh_index_js__WEBPACK_IMPORTED_MODULE_10__.Mesh),\n/* harmony export */ MetallicMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_7__.MetallicMaterial),\n/* harmony export */ MirroredRepeatWrapping: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.MirroredRepeatWrapping),\n/* harmony export */ ModelMemento: () => (/* reexport safe */ _mementos_index_js__WEBPACK_IMPORTED_MODULE_9__.ModelMemento),\n/* harmony export */ NearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestFilter),\n/* harmony export */ NearestMipMapLinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestMipMapLinearFilter),\n/* harmony export */ NearestMipMapNearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestMipMapNearestFilter),\n/* harmony export */ NearestMipmapLinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestMipmapLinearFilter),\n/* harmony export */ NearestMipmapNearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestMipmapNearestFilter),\n/* harmony export */ Node: () => (/* reexport safe */ _nodes_index_js__WEBPACK_IMPORTED_MODULE_11__.Node),\n/* harmony export */ ObjectsMemento: () => (/* reexport safe */ _mementos_index_js__WEBPACK_IMPORTED_MODULE_9__.ObjectsMemento),\n/* harmony export */ PNGMediaType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.PNGMediaType),\n/* harmony export */ Path: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_12__.Path),\n/* harmony export */ PerformanceModel: () => (/* reexport safe */ _model_index_js__WEBPACK_IMPORTED_MODULE_13__.PerformanceModel),\n/* harmony export */ PhongMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_7__.PhongMaterial),\n/* harmony export */ PointLight: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_5__.PointLight),\n/* harmony export */ QuadraticBezierCurve: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_12__.QuadraticBezierCurve),\n/* harmony export */ Queue: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_17__.Queue),\n/* harmony export */ RGBAFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBAFormat),\n/* harmony export */ RGBAIntegerFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBAIntegerFormat),\n/* harmony export */ RGBA_ASTC_10x10_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_10x10_Format),\n/* harmony export */ RGBA_ASTC_10x5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_10x5_Format),\n/* harmony export */ RGBA_ASTC_10x6_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_10x6_Format),\n/* harmony export */ RGBA_ASTC_10x8_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_10x8_Format),\n/* harmony export */ RGBA_ASTC_12x10_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_12x10_Format),\n/* harmony export */ RGBA_ASTC_12x12_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_12x12_Format),\n/* harmony export */ RGBA_ASTC_4x4_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_4x4_Format),\n/* harmony export */ RGBA_ASTC_5x4_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_5x4_Format),\n/* harmony export */ RGBA_ASTC_5x5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_5x5_Format),\n/* harmony export */ RGBA_ASTC_6x5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_6x5_Format),\n/* harmony export */ RGBA_ASTC_6x6_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_6x6_Format),\n/* harmony export */ RGBA_ASTC_8x5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_8x5_Format),\n/* harmony export */ RGBA_ASTC_8x6_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_8x6_Format),\n/* harmony export */ RGBA_ASTC_8x8_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ASTC_8x8_Format),\n/* harmony export */ RGBA_BPTC_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_BPTC_Format),\n/* harmony export */ RGBA_ETC2_EAC_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_ETC2_EAC_Format),\n/* harmony export */ RGBA_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_PVRTC_2BPPV1_Format),\n/* harmony export */ RGBA_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_PVRTC_4BPPV1_Format),\n/* harmony export */ RGBA_S3TC_DXT1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_S3TC_DXT1_Format),\n/* harmony export */ RGBA_S3TC_DXT3_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_S3TC_DXT3_Format),\n/* harmony export */ RGBA_S3TC_DXT5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBA_S3TC_DXT5_Format),\n/* harmony export */ RGBFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGBFormat),\n/* harmony export */ RGB_ETC1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGB_ETC1_Format),\n/* harmony export */ RGB_ETC2_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGB_ETC2_Format),\n/* harmony export */ RGB_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGB_PVRTC_2BPPV1_Format),\n/* harmony export */ RGB_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGB_PVRTC_4BPPV1_Format),\n/* harmony export */ RGB_S3TC_DXT1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGB_S3TC_DXT1_Format),\n/* harmony export */ RGFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGFormat),\n/* harmony export */ RGIntegerFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RGIntegerFormat),\n/* harmony export */ ReadableGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.ReadableGeometry),\n/* harmony export */ RedFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RedFormat),\n/* harmony export */ RedIntegerFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RedIntegerFormat),\n/* harmony export */ ReflectionMap: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_5__.ReflectionMap),\n/* harmony export */ RepeatWrapping: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping),\n/* harmony export */ SceneModel: () => (/* reexport safe */ _model_index_js__WEBPACK_IMPORTED_MODULE_13__.SceneModel),\n/* harmony export */ SceneModelMesh: () => (/* reexport safe */ _model_index_js__WEBPACK_IMPORTED_MODULE_13__.SceneModelMesh),\n/* harmony export */ SceneModelTransform: () => (/* reexport safe */ _model_index_js__WEBPACK_IMPORTED_MODULE_13__.SceneModelTransform),\n/* harmony export */ SectionBox: () => (/* reexport safe */ _sectionBox_index_js__WEBPACK_IMPORTED_MODULE_15__.SectionBox),\n/* harmony export */ SectionPlane: () => (/* reexport safe */ _sectionPlane_index_js__WEBPACK_IMPORTED_MODULE_14__.SectionPlane),\n/* harmony export */ ShortType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.ShortType),\n/* harmony export */ Skybox: () => (/* reexport safe */ _skybox_index_js__WEBPACK_IMPORTED_MODULE_16__.Skybox),\n/* harmony export */ SpecularMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_7__.SpecularMaterial),\n/* harmony export */ SplineCurve: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_12__.SplineCurve),\n/* harmony export */ SpriteMarker: () => (/* reexport safe */ _marker_index_js__WEBPACK_IMPORTED_MODULE_6__.SpriteMarker),\n/* harmony export */ Texture: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_7__.Texture),\n/* harmony export */ TextureTranscoder: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_17__.TextureTranscoder),\n/* harmony export */ UnsignedByteType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.UnsignedByteType),\n/* harmony export */ UnsignedInt248Type: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.UnsignedInt248Type),\n/* harmony export */ UnsignedIntType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.UnsignedIntType),\n/* harmony export */ UnsignedShort4444Type: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.UnsignedShort4444Type),\n/* harmony export */ UnsignedShort5551Type: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.UnsignedShort5551Type),\n/* harmony export */ UnsignedShortType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.UnsignedShortType),\n/* harmony export */ VBOGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.VBOGeometry),\n/* harmony export */ WorkerPool: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_17__.WorkerPool),\n/* harmony export */ buildBoxGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.buildBoxGeometry),\n/* harmony export */ buildBoxLinesGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.buildBoxLinesGeometry),\n/* harmony export */ buildCylinderGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.buildCylinderGeometry),\n/* harmony export */ buildGridGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.buildGridGeometry),\n/* harmony export */ buildPlaneGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.buildPlaneGeometry),\n/* harmony export */ buildSphereGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.buildSphereGeometry),\n/* harmony export */ buildTorusGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.buildTorusGeometry),\n/* harmony export */ buildVectorTextGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.buildVectorTextGeometry),\n/* harmony export */ createRTCViewMat: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.createRTCViewMat),\n/* harmony export */ frustumIntersectsAABB3: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.frustumIntersectsAABB3),\n/* harmony export */ getKTX2TextureTranscoder: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_17__.getKTX2TextureTranscoder),\n/* harmony export */ getPlaneRTCPos: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.getPlaneRTCPos),\n/* harmony export */ load3DSGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.load3DSGeometry),\n/* harmony export */ loadOBJGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__.loadOBJGeometry),\n/* harmony export */ math: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.math),\n/* harmony export */ rtcToWorldPos: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.rtcToWorldPos),\n/* harmony export */ sRGBEncoding: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.sRGBEncoding),\n/* harmony export */ setFrustum: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.setFrustum),\n/* harmony export */ stats: () => (/* reexport safe */ _stats_js__WEBPACK_IMPORTED_MODULE_20__.stats),\n/* harmony export */ utils: () => (/* reexport safe */ _utils_js__WEBPACK_IMPORTED_MODULE_19__.utils),\n/* harmony export */ worldToRTCPos: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.worldToRTCPos),\n/* harmony export */ worldToRTCPositions: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_8__.worldToRTCPositions)\n/* harmony export */ });\n/* harmony import */ var _camera_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./camera/index.js */ \"./src/viewer/scene/camera/index.js\");\n/* harmony import */ var _geometry_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./geometry/index.js */ \"./src/viewer/scene/geometry/index.js\");\n/* harmony import */ var _ImagePlane_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ImagePlane/index.js */ \"./src/viewer/scene/ImagePlane/index.js\");\n/* harmony import */ var _Bitmap_index_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Bitmap/index.js */ \"./src/viewer/scene/Bitmap/index.js\");\n/* harmony import */ var _LineSet_index_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./LineSet/index.js */ \"./src/viewer/scene/LineSet/index.js\");\n/* harmony import */ var _lights_index_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./lights/index.js */ \"./src/viewer/scene/lights/index.js\");\n/* harmony import */ var _marker_index_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./marker/index.js */ \"./src/viewer/scene/marker/index.js\");\n/* harmony import */ var _materials_index_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./materials/index.js */ \"./src/viewer/scene/materials/index.js\");\n/* harmony import */ var _math_index_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./math/index.js */ \"./src/viewer/scene/math/index.js\");\n/* harmony import */ var _mementos_index_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./mementos/index.js */ \"./src/viewer/scene/mementos/index.js\");\n/* harmony import */ var _mesh_index_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./mesh/index.js */ \"./src/viewer/scene/mesh/index.js\");\n/* harmony import */ var _nodes_index_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./nodes/index.js */ \"./src/viewer/scene/nodes/index.js\");\n/* harmony import */ var _paths_index_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./paths/index.js */ \"./src/viewer/scene/paths/index.js\");\n/* harmony import */ var _model_index_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./model/index.js */ \"./src/viewer/scene/model/index.js\");\n/* harmony import */ var _sectionPlane_index_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./sectionPlane/index.js */ \"./src/viewer/scene/sectionPlane/index.js\");\n/* harmony import */ var _sectionBox_index_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./sectionBox/index.js */ \"./src/viewer/scene/sectionBox/index.js\");\n/* harmony import */ var _skybox_index_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./skybox/index.js */ \"./src/viewer/scene/skybox/index.js\");\n/* harmony import */ var _utils_index_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./utils/index.js */ \"./src/viewer/scene/utils/index.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _stats_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./stats.js */ \"./src/viewer/scene/stats.js\");\n/* harmony import */ var _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./constants/constants.js */ \"./src/viewer/scene/constants/constants.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/index.js?");
2957
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AlphaFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.AlphaFormat),\n/* harmony export */ AmbientLight: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_6__.AmbientLight),\n/* harmony export */ Bitmap: () => (/* reexport safe */ _Bitmap_index_js__WEBPACK_IMPORTED_MODULE_4__.Bitmap),\n/* harmony export */ ByteType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.ByteType),\n/* harmony export */ CameraMemento: () => (/* reexport safe */ _mementos_index_js__WEBPACK_IMPORTED_MODULE_10__.CameraMemento),\n/* harmony export */ CameraPath: () => (/* reexport safe */ _camera_index_js__WEBPACK_IMPORTED_MODULE_0__.CameraPath),\n/* harmony export */ CameraPathAnimation: () => (/* reexport safe */ _camera_index_js__WEBPACK_IMPORTED_MODULE_0__.CameraPathAnimation),\n/* harmony export */ Canvas: () => (/* reexport safe */ _canvas_index_js__WEBPACK_IMPORTED_MODULE_1__.Canvas),\n/* harmony export */ ClampToEdgeWrapping: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.ClampToEdgeWrapping),\n/* harmony export */ Component: () => (/* reexport safe */ _Component_js__WEBPACK_IMPORTED_MODULE_19__.Component),\n/* harmony export */ CompressedMediaType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.CompressedMediaType),\n/* harmony export */ CubicBezierCurve: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_13__.CubicBezierCurve),\n/* harmony export */ Curve: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_13__.Curve),\n/* harmony export */ DefaultLoadingManager: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_18__.DefaultLoadingManager),\n/* harmony export */ DepthFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.DepthFormat),\n/* harmony export */ DepthStencilFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.DepthStencilFormat),\n/* harmony export */ DirLight: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_6__.DirLight),\n/* harmony export */ EdgeMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_8__.EdgeMaterial),\n/* harmony export */ EmphasisMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_8__.EmphasisMaterial),\n/* harmony export */ FloatType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.FloatType),\n/* harmony export */ Fresnel: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_8__.Fresnel),\n/* harmony export */ Frustum: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.Frustum),\n/* harmony export */ FrustumPlane: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.FrustumPlane),\n/* harmony export */ GIFMediaType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.GIFMediaType),\n/* harmony export */ HalfFloatType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.HalfFloatType),\n/* harmony export */ ImagePlane: () => (/* reexport safe */ _ImagePlane_index_js__WEBPACK_IMPORTED_MODULE_3__.ImagePlane),\n/* harmony export */ IntType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.IntType),\n/* harmony export */ JPEGMediaType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.JPEGMediaType),\n/* harmony export */ KTX2TextureTranscoder: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_18__.KTX2TextureTranscoder),\n/* harmony export */ LambertMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_8__.LambertMaterial),\n/* harmony export */ LightMap: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_6__.LightMap),\n/* harmony export */ LineSet: () => (/* reexport safe */ _LineSet_index_js__WEBPACK_IMPORTED_MODULE_5__.LineSet),\n/* harmony export */ LinearEncoding: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.LinearEncoding),\n/* harmony export */ LinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.LinearFilter),\n/* harmony export */ LinearMipMapLinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.LinearMipMapLinearFilter),\n/* harmony export */ LinearMipMapNearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.LinearMipMapNearestFilter),\n/* harmony export */ LinearMipmapLinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.LinearMipmapLinearFilter),\n/* harmony export */ LinearMipmapNearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.LinearMipmapNearestFilter),\n/* harmony export */ Loader: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_18__.Loader),\n/* harmony export */ LoadingManager: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_18__.LoadingManager),\n/* harmony export */ LuminanceAlphaFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.LuminanceAlphaFormat),\n/* harmony export */ LuminanceFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.LuminanceFormat),\n/* harmony export */ Map: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_18__.Map),\n/* harmony export */ Marker: () => (/* reexport safe */ _marker_index_js__WEBPACK_IMPORTED_MODULE_7__.Marker),\n/* harmony export */ Mesh: () => (/* reexport safe */ _mesh_index_js__WEBPACK_IMPORTED_MODULE_11__.Mesh),\n/* harmony export */ MetallicMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_8__.MetallicMaterial),\n/* harmony export */ MirroredRepeatWrapping: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.MirroredRepeatWrapping),\n/* harmony export */ ModelMemento: () => (/* reexport safe */ _mementos_index_js__WEBPACK_IMPORTED_MODULE_10__.ModelMemento),\n/* harmony export */ NearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.NearestFilter),\n/* harmony export */ NearestMipMapLinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.NearestMipMapLinearFilter),\n/* harmony export */ NearestMipMapNearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.NearestMipMapNearestFilter),\n/* harmony export */ NearestMipmapLinearFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.NearestMipmapLinearFilter),\n/* harmony export */ NearestMipmapNearestFilter: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.NearestMipmapNearestFilter),\n/* harmony export */ Node: () => (/* reexport safe */ _nodes_index_js__WEBPACK_IMPORTED_MODULE_12__.Node),\n/* harmony export */ ObjectsMemento: () => (/* reexport safe */ _mementos_index_js__WEBPACK_IMPORTED_MODULE_10__.ObjectsMemento),\n/* harmony export */ PNGMediaType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.PNGMediaType),\n/* harmony export */ Path: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_13__.Path),\n/* harmony export */ PerformanceModel: () => (/* reexport safe */ _model_index_js__WEBPACK_IMPORTED_MODULE_14__.PerformanceModel),\n/* harmony export */ PhongMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_8__.PhongMaterial),\n/* harmony export */ PointLight: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_6__.PointLight),\n/* harmony export */ QuadraticBezierCurve: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_13__.QuadraticBezierCurve),\n/* harmony export */ Queue: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_18__.Queue),\n/* harmony export */ RGBAFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBAFormat),\n/* harmony export */ RGBAIntegerFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBAIntegerFormat),\n/* harmony export */ RGBA_ASTC_10x10_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_10x10_Format),\n/* harmony export */ RGBA_ASTC_10x5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_10x5_Format),\n/* harmony export */ RGBA_ASTC_10x6_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_10x6_Format),\n/* harmony export */ RGBA_ASTC_10x8_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_10x8_Format),\n/* harmony export */ RGBA_ASTC_12x10_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_12x10_Format),\n/* harmony export */ RGBA_ASTC_12x12_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_12x12_Format),\n/* harmony export */ RGBA_ASTC_4x4_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_4x4_Format),\n/* harmony export */ RGBA_ASTC_5x4_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_5x4_Format),\n/* harmony export */ RGBA_ASTC_5x5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_5x5_Format),\n/* harmony export */ RGBA_ASTC_6x5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_6x5_Format),\n/* harmony export */ RGBA_ASTC_6x6_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_6x6_Format),\n/* harmony export */ RGBA_ASTC_8x5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_8x5_Format),\n/* harmony export */ RGBA_ASTC_8x6_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_8x6_Format),\n/* harmony export */ RGBA_ASTC_8x8_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ASTC_8x8_Format),\n/* harmony export */ RGBA_BPTC_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_BPTC_Format),\n/* harmony export */ RGBA_ETC2_EAC_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_ETC2_EAC_Format),\n/* harmony export */ RGBA_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_PVRTC_2BPPV1_Format),\n/* harmony export */ RGBA_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_PVRTC_4BPPV1_Format),\n/* harmony export */ RGBA_S3TC_DXT1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_S3TC_DXT1_Format),\n/* harmony export */ RGBA_S3TC_DXT3_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_S3TC_DXT3_Format),\n/* harmony export */ RGBA_S3TC_DXT5_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBA_S3TC_DXT5_Format),\n/* harmony export */ RGBFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGBFormat),\n/* harmony export */ RGB_ETC1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGB_ETC1_Format),\n/* harmony export */ RGB_ETC2_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGB_ETC2_Format),\n/* harmony export */ RGB_PVRTC_2BPPV1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGB_PVRTC_2BPPV1_Format),\n/* harmony export */ RGB_PVRTC_4BPPV1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGB_PVRTC_4BPPV1_Format),\n/* harmony export */ RGB_S3TC_DXT1_Format: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGB_S3TC_DXT1_Format),\n/* harmony export */ RGFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGFormat),\n/* harmony export */ RGIntegerFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RGIntegerFormat),\n/* harmony export */ ReadableGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.ReadableGeometry),\n/* harmony export */ RedFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RedFormat),\n/* harmony export */ RedIntegerFormat: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RedIntegerFormat),\n/* harmony export */ ReflectionMap: () => (/* reexport safe */ _lights_index_js__WEBPACK_IMPORTED_MODULE_6__.ReflectionMap),\n/* harmony export */ Renderer: () => (/* reexport safe */ _webgl_index_js__WEBPACK_IMPORTED_MODULE_23__.Renderer),\n/* harmony export */ RepeatWrapping: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.RepeatWrapping),\n/* harmony export */ Scene: () => (/* reexport safe */ _scene_Scene_js__WEBPACK_IMPORTED_MODULE_24__.Scene),\n/* harmony export */ SceneModel: () => (/* reexport safe */ _model_index_js__WEBPACK_IMPORTED_MODULE_14__.SceneModel),\n/* harmony export */ SceneModelMesh: () => (/* reexport safe */ _model_index_js__WEBPACK_IMPORTED_MODULE_14__.SceneModelMesh),\n/* harmony export */ SceneModelTransform: () => (/* reexport safe */ _model_index_js__WEBPACK_IMPORTED_MODULE_14__.SceneModelTransform),\n/* harmony export */ SectionBox: () => (/* reexport safe */ _sectionBox_index_js__WEBPACK_IMPORTED_MODULE_16__.SectionBox),\n/* harmony export */ SectionPlane: () => (/* reexport safe */ _sectionPlane_index_js__WEBPACK_IMPORTED_MODULE_15__.SectionPlane),\n/* harmony export */ ShortType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.ShortType),\n/* harmony export */ Skybox: () => (/* reexport safe */ _skybox_index_js__WEBPACK_IMPORTED_MODULE_17__.Skybox),\n/* harmony export */ SpecularMaterial: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_8__.SpecularMaterial),\n/* harmony export */ SplineCurve: () => (/* reexport safe */ _paths_index_js__WEBPACK_IMPORTED_MODULE_13__.SplineCurve),\n/* harmony export */ SpriteMarker: () => (/* reexport safe */ _marker_index_js__WEBPACK_IMPORTED_MODULE_7__.SpriteMarker),\n/* harmony export */ Texture: () => (/* reexport safe */ _materials_index_js__WEBPACK_IMPORTED_MODULE_8__.Texture),\n/* harmony export */ TextureTranscoder: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_18__.TextureTranscoder),\n/* harmony export */ UnsignedByteType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.UnsignedByteType),\n/* harmony export */ UnsignedInt248Type: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.UnsignedInt248Type),\n/* harmony export */ UnsignedIntType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.UnsignedIntType),\n/* harmony export */ UnsignedShort4444Type: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.UnsignedShort4444Type),\n/* harmony export */ UnsignedShort5551Type: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.UnsignedShort5551Type),\n/* harmony export */ UnsignedShortType: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.UnsignedShortType),\n/* harmony export */ VBOGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.VBOGeometry),\n/* harmony export */ WorkerPool: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_18__.WorkerPool),\n/* harmony export */ buildBoxGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.buildBoxGeometry),\n/* harmony export */ buildBoxLinesGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.buildBoxLinesGeometry),\n/* harmony export */ buildCylinderGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.buildCylinderGeometry),\n/* harmony export */ buildGridGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.buildGridGeometry),\n/* harmony export */ buildPlaneGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.buildPlaneGeometry),\n/* harmony export */ buildSphereGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.buildSphereGeometry),\n/* harmony export */ buildTorusGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.buildTorusGeometry),\n/* harmony export */ buildVectorTextGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.buildVectorTextGeometry),\n/* harmony export */ createRTCViewMat: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.createRTCViewMat),\n/* harmony export */ frustumIntersectsAABB3: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.frustumIntersectsAABB3),\n/* harmony export */ getKTX2TextureTranscoder: () => (/* reexport safe */ _utils_index_js__WEBPACK_IMPORTED_MODULE_18__.getKTX2TextureTranscoder),\n/* harmony export */ getPlaneRTCPos: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.getPlaneRTCPos),\n/* harmony export */ load3DSGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.load3DSGeometry),\n/* harmony export */ loadOBJGeometry: () => (/* reexport safe */ _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__.loadOBJGeometry),\n/* harmony export */ math: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.math),\n/* harmony export */ rtcToWorldPos: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.rtcToWorldPos),\n/* harmony export */ sRGBEncoding: () => (/* reexport safe */ _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__.sRGBEncoding),\n/* harmony export */ setFrustum: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.setFrustum),\n/* harmony export */ stats: () => (/* reexport safe */ _stats_js__WEBPACK_IMPORTED_MODULE_21__.stats),\n/* harmony export */ utils: () => (/* reexport safe */ _utils_js__WEBPACK_IMPORTED_MODULE_20__.utils),\n/* harmony export */ worldToRTCPos: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.worldToRTCPos),\n/* harmony export */ worldToRTCPositions: () => (/* reexport safe */ _math_index_js__WEBPACK_IMPORTED_MODULE_9__.worldToRTCPositions)\n/* harmony export */ });\n/* harmony import */ var _camera_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./camera/index.js */ \"./src/viewer/scene/camera/index.js\");\n/* harmony import */ var _canvas_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./canvas/index.js */ \"./src/viewer/scene/canvas/index.js\");\n/* harmony import */ var _geometry_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./geometry/index.js */ \"./src/viewer/scene/geometry/index.js\");\n/* harmony import */ var _ImagePlane_index_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ImagePlane/index.js */ \"./src/viewer/scene/ImagePlane/index.js\");\n/* harmony import */ var _Bitmap_index_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Bitmap/index.js */ \"./src/viewer/scene/Bitmap/index.js\");\n/* harmony import */ var _LineSet_index_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./LineSet/index.js */ \"./src/viewer/scene/LineSet/index.js\");\n/* harmony import */ var _lights_index_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./lights/index.js */ \"./src/viewer/scene/lights/index.js\");\n/* harmony import */ var _marker_index_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./marker/index.js */ \"./src/viewer/scene/marker/index.js\");\n/* harmony import */ var _materials_index_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./materials/index.js */ \"./src/viewer/scene/materials/index.js\");\n/* harmony import */ var _math_index_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./math/index.js */ \"./src/viewer/scene/math/index.js\");\n/* harmony import */ var _mementos_index_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./mementos/index.js */ \"./src/viewer/scene/mementos/index.js\");\n/* harmony import */ var _mesh_index_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./mesh/index.js */ \"./src/viewer/scene/mesh/index.js\");\n/* harmony import */ var _nodes_index_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./nodes/index.js */ \"./src/viewer/scene/nodes/index.js\");\n/* harmony import */ var _paths_index_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./paths/index.js */ \"./src/viewer/scene/paths/index.js\");\n/* harmony import */ var _model_index_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./model/index.js */ \"./src/viewer/scene/model/index.js\");\n/* harmony import */ var _sectionPlane_index_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./sectionPlane/index.js */ \"./src/viewer/scene/sectionPlane/index.js\");\n/* harmony import */ var _sectionBox_index_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./sectionBox/index.js */ \"./src/viewer/scene/sectionBox/index.js\");\n/* harmony import */ var _skybox_index_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./skybox/index.js */ \"./src/viewer/scene/skybox/index.js\");\n/* harmony import */ var _utils_index_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./utils/index.js */ \"./src/viewer/scene/utils/index.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _stats_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./stats.js */ \"./src/viewer/scene/stats.js\");\n/* harmony import */ var _constants_constants_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./constants/constants.js */ \"./src/viewer/scene/constants/constants.js\");\n/* harmony import */ var _webgl_index_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./webgl/index.js */ \"./src/viewer/scene/webgl/index.js\");\n/* harmony import */ var _scene_Scene_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./scene/Scene.js */ \"./src/viewer/scene/scene/Scene.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/index.js?");
2938
2958
 
2939
2959
  /***/ }),
2940
2960
 
@@ -3204,7 +3224,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3204
3224
  \***********************************************/
3205
3225
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3206
3226
 
3207
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Texture: () => (/* binding */ Texture)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../webgl/RenderState.js */ \"./src/viewer/scene/webgl/RenderState.js\");\n/* harmony import */ var _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../webgl/Texture2D.js */ \"./src/viewer/scene/webgl/Texture2D.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _stats_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../stats.js */ \"./src/viewer/scene/stats.js\");\n/* harmony import */ var _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../constants/constants.js */ \"./src/viewer/scene/constants/constants.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction ensureImageSizePowerOfTwo(image) {\r\n if (!isPowerOfTwo(image.width) || !isPowerOfTwo(image.height)) {\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.width = nextHighestPowerOfTwo(image.width);\r\n canvas.height = nextHighestPowerOfTwo(image.height);\r\n const ctx = canvas.getContext(\"2d\");\r\n ctx.drawImage(image,\r\n 0, 0, image.width, image.height,\r\n 0, 0, canvas.width, canvas.height);\r\n image = canvas;\r\n }\r\n return image;\r\n}\r\n\r\nfunction isPowerOfTwo(x) {\r\n return (x & (x - 1)) === 0;\r\n}\r\n\r\nfunction nextHighestPowerOfTwo(x) {\r\n --x;\r\n for (let i = 1; i < 32; i <<= 1) {\r\n x = x | x >> i;\r\n }\r\n return x + 1;\r\n}\r\n\r\n/**\r\n * @desc A 2D texture map.\r\n *\r\n * * Textures are attached to {@link Material}s, which are attached to {@link Mesh}es.\r\n * * To create a Texture from an image file, set {@link Texture#src} to the image file path.\r\n * * To create a Texture from an HTMLImageElement, set the Texture's {@link Texture#image} to the HTMLImageElement.\r\n *\r\n * ## Usage\r\n *\r\n * In this example we have a Mesh with a {@link PhongMaterial} which applies diffuse {@link Texture}, and a {@link buildTorusGeometry} which builds a {@link ReadableGeometry}.\r\n *\r\n * Note that xeokit will ignore {@link PhongMaterial#diffuse} and {@link PhongMaterial#specular}, since we override those\r\n * with {@link PhongMaterial#diffuseMap} and {@link PhongMaterial#specularMap}. The {@link Texture} pixel colors directly\r\n * provide the diffuse and specular components for each fragment across the {@link ReadableGeometry} surface.\r\n *\r\n * [[Run this example](/examples/#materials_Texture)]\r\n *\r\n * ```` javascript\r\n * import {Viewer, Mesh, buildTorusGeometry,\r\n * ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\r\n *\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\"\r\n * });\r\n *\r\n * viewer.camera.eye = [0, 0, 5];\r\n * viewer.camera.look = [0, 0, 0];\r\n * viewer.camera.up = [0, 1, 0];\r\n *\r\n * new Mesh(viewer.scene, {\r\n * geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry({\r\n * center: [0, 0, 0],\r\n * radius: 1.5,\r\n * tube: 0.5,\r\n * radialSegments: 32,\r\n * tubeSegments: 24,\r\n * arc: Math.PI * 2.0\r\n * }),\r\n * material: new PhongMaterial(viewer.scene, {\r\n * ambient: [0.9, 0.3, 0.9],\r\n * shininess: 30,\r\n * diffuseMap: new Texture(viewer.scene, {\r\n * src: \"textures/diffuse/uvGrid2.jpg\"\r\n * })\r\n * })\r\n * });\r\n *````\r\n */\r\nclass Texture extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\r\n\r\n /**\r\n @private\r\n */\r\n get type() {\r\n return \"Texture\";\r\n }\r\n\r\n /**\r\n * @constructor\r\n * @param {Component} owner Owner component. When destroyed, the owner will destroy this Texture as well.\r\n * @param {*} [cfg] Configs\r\n * @param {String} [cfg.id] Optional ID for this Texture, unique among all components in the parent scene, generated automatically when omitted.\r\n * @param {String} [cfg.src=null] Path to image file to load into this Texture. See the {@link Texture#src} property for more info.\r\n * @param {HTMLImageElement} [cfg.image=null] HTML Image object to load into this Texture. See the {@link Texture#image} property for more info.\r\n * @param {Number} [cfg.minFilter=LinearMipmapLinearFilter] How the texture is sampled when a texel covers less than one pixel.\r\n * Supported values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}.\r\n * @param {Number} [cfg.magFilter=LinearFilter] How the texture is sampled when a texel covers more than one pixel. Supported values are {@link LinearFilter} and {@link NearestFilter}.\r\n * @param {Number} [cfg.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\r\n * @param {Number} [cfg.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}..\r\n * @param {Boolean} [cfg.flipY=false] Flips this Texture's source data along its vertical axis when ````true````.\r\n * @param {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.\r\n * @param {Number[]} [cfg.translate=[0,0]] 2D translation vector that will be added to texture's *S* and *T* coordinates.\r\n * @param {Number[]} [cfg.scale=[1,1]] 2D scaling vector that will be applied to texture's *S* and *T* coordinates.\r\n * @param {Number} [cfg.rotate=0] Rotation, in degrees, that will be applied to texture's *S* and *T* coordinates.\r\n */\r\n constructor(owner, cfg = {}) {\r\n\r\n super(owner, cfg);\r\n\r\n this._state = new _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_1__.RenderState({\r\n texture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_2__.Texture2D({gl: this.scene.canvas.gl}),\r\n matrix: _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.identityMat4(),\r\n hasMatrix: (cfg.translate && (cfg.translate[0] !== 0 || cfg.translate[1] !== 0)) || (!!cfg.rotate) || (cfg.scale && (cfg.scale[0] !== 0 || cfg.scale[1] !== 0)),\r\n minFilter: this._checkMinFilter(cfg.minFilter),\r\n magFilter: this._checkMagFilter(cfg.magFilter),\r\n wrapS: this._checkWrapS(cfg.wrapS),\r\n wrapT: this._checkWrapT(cfg.wrapT),\r\n flipY: this._checkFlipY(cfg.flipY),\r\n encoding: this._checkEncoding(cfg.encoding)\r\n });\r\n\r\n // Data source\r\n\r\n this._src = null;\r\n this._image = null;\r\n\r\n // Transformation\r\n\r\n this._translate = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec2([0, 0]);\r\n this._scale = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec2([1, 1]);\r\n this._rotate = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec2([0, 0]);\r\n\r\n this._matrixDirty = false;\r\n\r\n // Transform\r\n\r\n this.translate = cfg.translate;\r\n this.scale = cfg.scale;\r\n this.rotate = cfg.rotate;\r\n\r\n // Data source\r\n\r\n if (cfg.src) {\r\n this.src = cfg.src; // Image file\r\n } else if (cfg.image) {\r\n this.image = cfg.image; // Image object\r\n }\r\n\r\n _stats_js__WEBPACK_IMPORTED_MODULE_4__.stats.memory.textures++;\r\n }\r\n\r\n _checkMinFilter(value) {\r\n value = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearMipMapLinearFilter;\r\n if (value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearFilter &&\r\n value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearMipMapNearestFilter &&\r\n value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearMipMapLinearFilter &&\r\n value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.NearestMipMapLinearFilter &&\r\n value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.NearestMipMapNearestFilter) {\r\n this.error(\"Unsupported value for 'minFilter' - supported values are LinearFilter, LinearMipMapNearestFilter, NearestMipMapNearestFilter, \" +\r\n \"NearestMipMapLinearFilter and LinearMipMapLinearFilter. Defaulting to LinearMipMapLinearFilter.\");\r\n value = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearMipMapLinearFilter;\r\n }\r\n return value;\r\n }\r\n\r\n _checkMagFilter(value) {\r\n value = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearFilter;\r\n if (value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearFilter && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.NearestFilter) {\r\n this.error(\"Unsupported value for 'magFilter' - supported values are LinearFilter and NearestFilter. Defaulting to LinearFilter.\");\r\n value = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearFilter;\r\n }\r\n return value;\r\n }\r\n\r\n _checkWrapS(value) {\r\n value = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping;\r\n if (value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.ClampToEdgeWrapping && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.MirroredRepeatWrapping && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping) {\r\n this.error(\"Unsupported value for 'wrapS' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.\");\r\n value = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping;\r\n }\r\n return value;\r\n }\r\n\r\n _checkWrapT(value) {\r\n value = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping;\r\n if (value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.ClampToEdgeWrapping && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.MirroredRepeatWrapping && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping) {\r\n this.error(\"Unsupported value for 'wrapT' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.\");\r\n value = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping;\r\n }\r\n return value;\r\n }\r\n\r\n _checkFlipY(value) {\r\n return !!value;\r\n }\r\n\r\n _checkEncoding(value) {\r\n value = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearEncoding;\r\n if (value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearEncoding && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.sRGBEncoding) {\r\n this.error(\"Unsupported value for 'encoding' - supported values are LinearEncoding and sRGBEncoding. Defaulting to LinearEncoding.\");\r\n value = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearEncoding;\r\n }\r\n return value;\r\n }\r\n\r\n _webglContextRestored() {\r\n this._state.texture = new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_2__.Texture2D({gl: this.scene.canvas.gl});\r\n if (this._image) {\r\n this.image = this._image;\r\n } else if (this._src) {\r\n this.src = this._src;\r\n }\r\n }\r\n\r\n _update() {\r\n const state = this._state;\r\n if (this._matrixDirty) {\r\n let matrix;\r\n let t;\r\n if (this._translate[0] !== 0 || this._translate[1] !== 0) {\r\n matrix = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.translationMat4v([this._translate[0], this._translate[1], 0], this._state.matrix);\r\n }\r\n if (this._scale[0] !== 1 || this._scale[1] !== 1) {\r\n t = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.scalingMat4v([this._scale[0], this._scale[1], 1]);\r\n matrix = matrix ? _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.mulMat4(matrix, t) : t;\r\n }\r\n if (this._rotate !== 0) {\r\n t = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.rotationMat4v(this._rotate * 0.0174532925, [0, 0, 1]);\r\n matrix = matrix ? _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.mulMat4(matrix, t) : t;\r\n }\r\n if (matrix) {\r\n state.matrix = matrix;\r\n }\r\n this._matrixDirty = false;\r\n }\r\n this.glRedraw();\r\n }\r\n\r\n\r\n /**\r\n * Sets an HTML DOM Image object to source this Texture from.\r\n *\r\n * Sets {@link Texture#src} null.\r\n *\r\n * @type {HTMLImageElement}\r\n */\r\n set image(value) {\r\n this._image = ensureImageSizePowerOfTwo(value);\r\n this._image.crossOrigin = \"Anonymous\";\r\n this._state.texture.setImage(this._image, this._state);\r\n this._src = null;\r\n this.glRedraw();\r\n }\r\n\r\n /**\r\n * Gets HTML DOM Image object this Texture is sourced from, if any.\r\n *\r\n * Returns null if not set.\r\n *\r\n * @type {HTMLImageElement}\r\n */\r\n get image() {\r\n return this._image;\r\n }\r\n\r\n /**\r\n * Sets path to an image file to source this Texture from.\r\n *\r\n * Sets {@link Texture#image} null.\r\n *\r\n * @type {String}\r\n */\r\n set src(src) {\r\n this.scene.loading++;\r\n this.scene.canvas.spinner.processes++;\r\n const self = this;\r\n let image = new Image();\r\n image.onload = function () {\r\n image = ensureImageSizePowerOfTwo(image);\r\n self._state.texture.setImage(image, self._state);\r\n self.scene.loading--;\r\n self.glRedraw();\r\n self.scene.canvas.spinner.processes--;\r\n };\r\n image.src = src;\r\n this._src = src;\r\n this._image = null;\r\n }\r\n\r\n /**\r\n * Gets path to the image file this Texture from, if any.\r\n *\r\n * Returns null if not set.\r\n *\r\n * @type {String}\r\n */\r\n get src() {\r\n return this._src;\r\n }\r\n\r\n /**\r\n * Sets the 2D translation vector added to this Texture's *S* and *T* UV coordinates.\r\n *\r\n * Default value is ````[0, 0]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n set translate(value) {\r\n this._translate.set(value || [0, 0]);\r\n this._matrixDirty = true;\r\n this._needUpdate();\r\n }\r\n\r\n /**\r\n * Gets the 2D translation vector added to this Texture's *S* and *T* UV coordinates.\r\n *\r\n * Default value is ````[0, 0]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n get translate() {\r\n return this._translate;\r\n }\r\n\r\n /**\r\n * Sets the 2D scaling vector that will be applied to this Texture's *S* and *T* UV coordinates.\r\n *\r\n * Default value is ````[1, 1]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n set scale(value) {\r\n this._scale.set(value || [1, 1]);\r\n this._matrixDirty = true;\r\n this._needUpdate();\r\n }\r\n\r\n /**\r\n * Gets the 2D scaling vector that will be applied to this Texture's *S* and *T* UV coordinates.\r\n *\r\n * Default value is ````[1, 1]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n get scale() {\r\n return this._scale;\r\n }\r\n\r\n /**\r\n * Sets the rotation angles, in degrees, that will be applied to this Texture's *S* and *T* UV coordinates.\r\n *\r\n * Default value is ````0````.\r\n *\r\n * @type {Number}\r\n */\r\n set rotate(value) {\r\n value = value || 0;\r\n if (this._rotate === value) {\r\n return;\r\n }\r\n this._rotate = value;\r\n this._matrixDirty = true;\r\n this._needUpdate();\r\n }\r\n\r\n /**\r\n * Gets the rotation angles, in degrees, that will be applied to this Texture's *S* and *T* UV coordinates.\r\n *\r\n * Default value is ````0````.\r\n *\r\n * @type {Number}\r\n */\r\n get rotate() {\r\n return this._rotate;\r\n }\r\n\r\n /**\r\n * Gets how this Texture is sampled when a texel covers less than one pixel.\r\n *\r\n * Options are:\r\n *\r\n * * NearestFilter - Uses the value of the texture element that is nearest\r\n * (in Manhattan distance) to the center of the pixel being textured.\r\n *\r\n * * LinearFilter - Uses the weighted average of the four texture elements that are\r\n * closest to the center of the pixel being textured.\r\n *\r\n * * NearestMipMapNearestFilter - Chooses the mipmap that most closely matches the\r\n * size of the pixel being textured and uses the \"nearest\" criterion (the texture\r\n * element nearest to the center of the pixel) to produce a texture value.\r\n *\r\n * * LinearMipMapNearestFilter - Chooses the mipmap that most closely matches the size of\r\n * the pixel being textured and uses the \"linear\" criterion (a weighted average of the\r\n * four texture elements that are closest to the center of the pixel) to produce a\r\n * texture value.\r\n *\r\n * * NearestMipMapLinearFilter - Chooses the two mipmaps that most closely\r\n * match the size of the pixel being textured and uses the \"nearest\" criterion\r\n * (the texture element nearest to the center of the pixel) to produce a texture\r\n * value from each mipmap. The final texture value is a weighted average of those two\r\n * values.\r\n *\r\n * * LinearMipMapLinearFilter - (default) - Chooses the two mipmaps that most closely match the size\r\n * of the pixel being textured and uses the \"linear\" criterion (a weighted average\r\n * of the four texture elements that are closest to the center of the pixel) to\r\n * produce a texture value from each mipmap. The final texture value is a weighted\r\n * average of those two values.\r\n *\r\n * Default value is LinearMipMapLinearFilter.\r\n *\r\n * @type {Number}\r\n */\r\n get minFilter() {\r\n return this._state.minFilter;\r\n }\r\n\r\n /**\r\n * Gets how this Texture is sampled when a texel covers more than one pixel.\r\n *\r\n * * NearestFilter - Uses the value of the texture element that is nearest\r\n * (in Manhattan distance) to the center of the pixel being textured.\r\n * * LinearFilter - (default) - Uses the weighted average of the four texture elements that are\r\n * closest to the center of the pixel being textured.\r\n *\r\n * Default value is LinearMipMapLinearFilter.\r\n *\r\n * @type {Number}\r\n */\r\n get magFilter() {\r\n return this._state.magFilter;\r\n }\r\n\r\n /**\r\n * Gets the wrap parameter for this Texture's *S* coordinate.\r\n *\r\n * Values can be:\r\n *\r\n * * ClampToEdgeWrapping - causes *S* coordinates to be clamped to the size of the texture.\r\n * * MirroredRepeatWrapping - causes the *S* coordinate to be set to the fractional part of the texture coordinate\r\n * if the integer part of *S* is even; if the integer part of *S* is odd, then the *S* texture coordinate is\r\n * set to *1 - frac ⁡ S* , where *frac ⁡ S* represents the fractional part of *S*.\r\n * * RepeatWrapping - (default) - causes the integer part of the *S* coordinate to be ignored; xeokit uses only the\r\n * fractional part, thereby creating a repeating pattern.\r\n *\r\n * Default value is RepeatWrapping.\r\n *\r\n * @type {Number}\r\n */\r\n get wrapS() {\r\n return this._state.wrapS;\r\n }\r\n\r\n /**\r\n * Gets the wrap parameter for this Texture's *T* coordinate.\r\n *\r\n * Values can be:\r\n *\r\n * * ClampToEdgeWrapping - causes *S* coordinates to be clamped to the size of the texture.\r\n * * MirroredRepeatWrapping - causes the *S* coordinate to be set to the fractional part of the texture coordinate\r\n * if the integer part of *S* is even; if the integer part of *S* is odd, then the *S* texture coordinate is\r\n * set to *1 - frac ⁡ S* , where *frac ⁡ S* represents the fractional part of *S*.\r\n * * RepeatWrapping - (default) - causes the integer part of the *S* coordinate to be ignored; xeokit uses only the\r\n * fractional part, thereby creating a repeating pattern.\r\n *\r\n * Default value is RepeatWrapping.\r\n *\r\n * @type {Number}\r\n */\r\n get wrapT() {\r\n return this._state.wrapT;\r\n }\r\n\r\n /**\r\n * Gets if this Texture's source data is flipped along its vertical axis.\r\n *\r\n * @type {Number}\r\n */\r\n get flipY() {\r\n return this._state.flipY;\r\n }\r\n\r\n /**\r\n * Gets the Texture's encoding format.\r\n *\r\n * @type {Number}\r\n */\r\n get encoding() {\r\n return this._state.encoding;\r\n }\r\n\r\n /**\r\n * Destroys this Texture\r\n */\r\n destroy() {\r\n super.destroy();\r\n if (this._state.texture) {\r\n this._state.texture.destroy();\r\n }\r\n this._state.destroy();\r\n _stats_js__WEBPACK_IMPORTED_MODULE_4__.stats.memory.textures--;\r\n }\r\n}\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/materials/Texture.js?");
3227
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Texture: () => (/* binding */ Texture)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../webgl/RenderState.js */ \"./src/viewer/scene/webgl/RenderState.js\");\n/* harmony import */ var _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../webgl/Texture2D.js */ \"./src/viewer/scene/webgl/Texture2D.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _stats_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../stats.js */ \"./src/viewer/scene/stats.js\");\n/* harmony import */ var _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../constants/constants.js */ \"./src/viewer/scene/constants/constants.js\");\n\n\n\n\n\n\n\nfunction ensureImageSizePowerOfTwo(image) {\n\tif (!isPowerOfTwo(image.width) || !isPowerOfTwo(image.height)) {\n\t\tconst canvas = document.createElement(\"canvas\");\n\t\tcanvas.width = nextHighestPowerOfTwo(image.width);\n\t\tcanvas.height = nextHighestPowerOfTwo(image.height);\n\t\tconst ctx = canvas.getContext(\"2d\");\n\t\tctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height);\n\t\timage = canvas;\n\t}\n\treturn image;\n}\n\nfunction isPowerOfTwo(x) {\n\treturn (x & (x - 1)) === 0;\n}\n\nfunction nextHighestPowerOfTwo(x) {\n\t--x;\n\tfor (let i = 1; i < 32; i <<= 1) {\n\t\tx = x | (x >> i);\n\t}\n\treturn x + 1;\n}\n\n/**\n * @desc A 2D texture map.\n *\n * * Textures are attached to {@link Material}s, which are attached to {@link Mesh}es.\n * * To create a Texture from an image file, set {@link Texture#src} to the image file path.\n * * To create a Texture from an HTMLImageElement, set the Texture's {@link Texture#image} to the HTMLImageElement.\n *\n * ## Usage\n *\n * In this example we have a Mesh with a {@link PhongMaterial} which applies diffuse {@link Texture}, and a {@link buildTorusGeometry} which builds a {@link ReadableGeometry}.\n *\n * Note that xeokit will ignore {@link PhongMaterial#diffuse} and {@link PhongMaterial#specular}, since we override those\n * with {@link PhongMaterial#diffuseMap} and {@link PhongMaterial#specularMap}. The {@link Texture} pixel colors directly\n * provide the diffuse and specular components for each fragment across the {@link ReadableGeometry} surface.\n *\n * [[Run this example](/examples/#materials_Texture)]\n *\n * ```` javascript\n * import {Viewer, Mesh, buildTorusGeometry,\n * ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [0, 0, 5];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n * geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry({\n * center: [0, 0, 0],\n * radius: 1.5,\n * tube: 0.5,\n * radialSegments: 32,\n * tubeSegments: 24,\n * arc: Math.PI * 2.0\n * }),\n * material: new PhongMaterial(viewer.scene, {\n * ambient: [0.9, 0.3, 0.9],\n * shininess: 30,\n * diffuseMap: new Texture(viewer.scene, {\n * src: \"textures/diffuse/uvGrid2.jpg\"\n * })\n * })\n * });\n *````\n */\nclass Texture extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\n\t/**\n @private\n */\n\tget type() {\n\t\treturn \"Texture\";\n\t}\n\n\t/**\n\t * @constructor\n\t * @param {Component} owner Owner component. When destroyed, the owner will destroy this Texture as well.\n\t * @param {*} [cfg] Configs\n\t * @param {String} [cfg.id] Optional ID for this Texture, unique among all components in the parent scene, generated automatically when omitted.\n\t * @param {String} [cfg.src=null] Path to image file to load into this Texture. See the {@link Texture#src} property for more info.\n\t * @param {HTMLImageElement} [cfg.image=null] HTML Image object to load into this Texture. See the {@link Texture#image} property for more info.\n\t * @param {Number} [cfg.minFilter=LinearMipmapLinearFilter] How the texture is sampled when a texel covers less than one pixel.\n\t * Supported values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}.\n\t * @param {Number} [cfg.magFilter=LinearFilter] How the texture is sampled when a texel covers more than one pixel. Supported values are {@link LinearFilter} and {@link NearestFilter}.\n\t * @param {Number} [cfg.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n\t * @param {Number} [cfg.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}..\n\t * @param {Boolean} [cfg.flipY=false] Flips this Texture's source data along its vertical axis when ````true````.\n\t * @param {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.\n\t * @param {Number[]} [cfg.translate=[0,0]] 2D translation vector that will be added to texture's *S* and *T* coordinates.\n\t * @param {Number[]} [cfg.scale=[1,1]] 2D scaling vector that will be applied to texture's *S* and *T* coordinates.\n\t * @param {Number} [cfg.rotate=0] Rotation, in degrees, that will be applied to texture's *S* and *T* coordinates.\n\t */\n\tconstructor(owner, cfg = {}) {\n\t\tsuper(owner, cfg);\n\n\t\tthis._state = new _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_1__.RenderState({\n\t\t\ttexture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_2__.Texture2D({ gl: this.scene.canvas.gl }),\n\t\t\tmatrix: _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.identityMat4(),\n\t\t\thasMatrix:\n\t\t\t\t(cfg.translate && (cfg.translate[0] !== 0 || cfg.translate[1] !== 0)) ||\n\t\t\t\t!!cfg.rotate ||\n\t\t\t\t(cfg.scale && (cfg.scale[0] !== 0 || cfg.scale[1] !== 0)),\n\t\t\tminFilter: this._checkMinFilter(cfg.minFilter || 1008),\n\t\t\tmagFilter: this._checkMagFilter(cfg.magFilter || 1006),\n\t\t\twrapS: this._checkWrapS(cfg.wrapS || 1000),\n\t\t\twrapT: this._checkWrapT(cfg.wrapT || 1000),\n\t\t\tflipY: this._checkFlipY(cfg.flipY || 1000),\n\t\t\tencoding: this._checkEncoding(cfg.encoding)\n\t\t});\n\n\t\t// Data source\n\n\t\tthis._src = null;\n\t\tthis._image = null;\n\n\t\t// Transformation\n\n\t\tthis._translate = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec2([0, 0]);\n\t\tthis._scale = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec2([1, 1]);\n\t\tthis._rotate = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec2([0, 0]);\n\n\t\tthis._matrixDirty = false;\n\n\t\t// Transform\n\n\t\tthis.translate = cfg.translate;\n\t\tthis.scale = cfg.scale;\n\t\tthis.rotate = cfg.rotate;\n\n\t\t// Data source\n\n\t\tif (cfg.src) {\n\t\t\tthis.src = cfg.src; // Image file\n\t\t} else if (cfg.image) {\n\t\t\tthis.image = cfg.image; // Image object\n\t\t}\n\n\t\t_stats_js__WEBPACK_IMPORTED_MODULE_4__.stats.memory.textures++;\n\t}\n\n\t_checkMinFilter(value) {\n\t\tvalue = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearMipMapLinearFilter;\n\t\tif (\n\t\t\tvalue !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearFilter &&\n\t\t\tvalue !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearMipMapNearestFilter &&\n\t\t\tvalue !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearMipMapLinearFilter &&\n\t\t\tvalue !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.NearestMipMapLinearFilter &&\n\t\t\tvalue !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.NearestMipMapNearestFilter\n\t\t) {\n\t\t\tthis.error(\n\t\t\t\t\"Unsupported value for 'minFilter' - supported values are LinearFilter, LinearMipMapNearestFilter, NearestMipMapNearestFilter, \" +\n\t\t\t\t\t\"NearestMipMapLinearFilter and LinearMipMapLinearFilter. Defaulting to LinearMipMapLinearFilter.\"\n\t\t\t);\n\t\t\tvalue = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearMipMapLinearFilter;\n\t\t}\n\t\treturn value;\n\t}\n\n\t_checkMagFilter(value) {\n\t\tvalue = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearFilter;\n\t\tif (value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearFilter && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.NearestFilter) {\n\t\t\tthis.error(\n\t\t\t\t\"Unsupported value for 'magFilter' - supported values are LinearFilter and NearestFilter. Defaulting to LinearFilter.\"\n\t\t\t);\n\t\t\tvalue = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearFilter;\n\t\t}\n\t\treturn value;\n\t}\n\n\t_checkWrapS(value) {\n\t\tvalue = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping;\n\t\tif (value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.ClampToEdgeWrapping && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.MirroredRepeatWrapping && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping) {\n\t\t\tthis.error(\n\t\t\t\t\"Unsupported value for 'wrapS' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.\"\n\t\t\t);\n\t\t\tvalue = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping;\n\t\t}\n\t\treturn value;\n\t}\n\n\t_checkWrapT(value) {\n\t\tvalue = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping;\n\t\tif (value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.ClampToEdgeWrapping && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.MirroredRepeatWrapping && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping) {\n\t\t\tthis.error(\n\t\t\t\t\"Unsupported value for 'wrapT' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.\"\n\t\t\t);\n\t\t\tvalue = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.RepeatWrapping;\n\t\t}\n\t\treturn value;\n\t}\n\n\t_checkFlipY(value) {\n\t\treturn !!value;\n\t}\n\n\t_checkEncoding(value) {\n\t\tvalue = value || _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearEncoding;\n\t\tif (value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearEncoding && value !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.sRGBEncoding) {\n\t\t\tthis.error(\n\t\t\t\t\"Unsupported value for 'encoding' - supported values are LinearEncoding and sRGBEncoding. Defaulting to LinearEncoding.\"\n\t\t\t);\n\t\t\tvalue = _constants_constants_js__WEBPACK_IMPORTED_MODULE_5__.LinearEncoding;\n\t\t}\n\t\treturn value;\n\t}\n\n\t_webglContextRestored() {\n\t\tthis._state.texture = new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_2__.Texture2D({ gl: this.scene.canvas.gl });\n\t\tif (this._image) {\n\t\t\tthis.image = this._image;\n\t\t} else if (this._src) {\n\t\t\tthis.src = this._src;\n\t\t}\n\t}\n\n\t_update() {\n\t\tconst state = this._state;\n\t\tif (this._matrixDirty) {\n\t\t\tlet matrix;\n\t\t\tlet t;\n\t\t\tif (this._translate[0] !== 0 || this._translate[1] !== 0) {\n\t\t\t\tmatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.translationMat4v([this._translate[0], this._translate[1], 0], this._state.matrix);\n\t\t\t}\n\t\t\tif (this._scale[0] !== 1 || this._scale[1] !== 1) {\n\t\t\t\tt = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.scalingMat4v([this._scale[0], this._scale[1], 1]);\n\t\t\t\tmatrix = matrix ? _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.mulMat4(matrix, t) : t;\n\t\t\t}\n\t\t\tif (this._rotate !== 0) {\n\t\t\t\tt = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.rotationMat4v(this._rotate * 0.0174532925, [0, 0, 1]);\n\t\t\t\tmatrix = matrix ? _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.mulMat4(matrix, t) : t;\n\t\t\t}\n\t\t\tif (matrix) {\n\t\t\t\tstate.matrix = matrix;\n\t\t\t}\n\t\t\tthis._matrixDirty = false;\n\t\t}\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Sets an HTML DOM Image object to source this Texture from.\n\t *\n\t * Sets {@link Texture#src} null.\n\t *\n\t * @type {HTMLImageElement}\n\t */\n\tset image(value) {\n\t\tthis._image = ensureImageSizePowerOfTwo(value);\n\t\tthis._image.crossOrigin = \"Anonymous\";\n\t\tthis._state.texture.setImage(this._image, this._state);\n\t\tthis._src = null;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets HTML DOM Image object this Texture is sourced from, if any.\n\t *\n\t * Returns null if not set.\n\t *\n\t * @type {HTMLImageElement}\n\t */\n\tget image() {\n\t\treturn this._image;\n\t}\n\n\t/**\n\t * Sets path to an image file to source this Texture from.\n\t *\n\t * Sets {@link Texture#image} null.\n\t *\n\t * @type {String}\n\t */\n\tset src(src) {\n\t\tthis.scene.loading++;\n\t\tthis.scene.canvas.spinner.processes++;\n\t\tconst self = this;\n\t\tlet image = new Image();\n\t\timage.onload = function () {\n\t\t\timage = ensureImageSizePowerOfTwo(image);\n\t\t\tself._state.texture.setImage(image, self._state);\n\t\t\tself.scene.loading--;\n\t\t\tself.glRedraw();\n\t\t\tself.scene.canvas.spinner.processes--;\n\t\t};\n\t\timage.src = src;\n\t\tthis._src = src;\n\t\tthis._image = null;\n\t}\n\n\t/**\n\t * Gets path to the image file this Texture from, if any.\n\t *\n\t * Returns null if not set.\n\t *\n\t * @type {String}\n\t */\n\tget src() {\n\t\treturn this._src;\n\t}\n\n\t/**\n\t * Sets the 2D translation vector added to this Texture's *S* and *T* UV coordinates.\n\t *\n\t * Default value is ````[0, 0]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tset translate(value) {\n\t\tthis._translate.set(value || [0, 0]);\n\t\tthis._matrixDirty = true;\n\t\tthis._needUpdate();\n\t}\n\n\t/**\n\t * Gets the 2D translation vector added to this Texture's *S* and *T* UV coordinates.\n\t *\n\t * Default value is ````[0, 0]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget translate() {\n\t\treturn this._translate;\n\t}\n\n\t/**\n\t * Sets the 2D scaling vector that will be applied to this Texture's *S* and *T* UV coordinates.\n\t *\n\t * Default value is ````[1, 1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tset scale(value) {\n\t\tthis._scale.set(value || [1, 1]);\n\t\tthis._matrixDirty = true;\n\t\tthis._needUpdate();\n\t}\n\n\t/**\n\t * Gets the 2D scaling vector that will be applied to this Texture's *S* and *T* UV coordinates.\n\t *\n\t * Default value is ````[1, 1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget scale() {\n\t\treturn this._scale;\n\t}\n\n\t/**\n\t * Sets the rotation angles, in degrees, that will be applied to this Texture's *S* and *T* UV coordinates.\n\t *\n\t * Default value is ````0````.\n\t *\n\t * @type {Number}\n\t */\n\tset rotate(value) {\n\t\tvalue = value || 0;\n\t\tif (this._rotate === value) {\n\t\t\treturn;\n\t\t}\n\t\tthis._rotate = value;\n\t\tthis._matrixDirty = true;\n\t\tthis._needUpdate();\n\t}\n\n\t/**\n\t * Gets the rotation angles, in degrees, that will be applied to this Texture's *S* and *T* UV coordinates.\n\t *\n\t * Default value is ````0````.\n\t *\n\t * @type {Number}\n\t */\n\tget rotate() {\n\t\treturn this._rotate;\n\t}\n\n\t/**\n\t * Gets how this Texture is sampled when a texel covers less than one pixel.\n\t *\n\t * Options are:\n\t *\n\t * * NearestFilter - Uses the value of the texture element that is nearest\n\t * (in Manhattan distance) to the center of the pixel being textured.\n\t *\n\t * * LinearFilter - Uses the weighted average of the four texture elements that are\n\t * closest to the center of the pixel being textured.\n\t *\n\t * * NearestMipMapNearestFilter - Chooses the mipmap that most closely matches the\n\t * size of the pixel being textured and uses the \"nearest\" criterion (the texture\n\t * element nearest to the center of the pixel) to produce a texture value.\n\t *\n\t * * LinearMipMapNearestFilter - Chooses the mipmap that most closely matches the size of\n\t * the pixel being textured and uses the \"linear\" criterion (a weighted average of the\n\t * four texture elements that are closest to the center of the pixel) to produce a\n\t * texture value.\n\t *\n\t * * NearestMipMapLinearFilter - Chooses the two mipmaps that most closely\n\t * match the size of the pixel being textured and uses the \"nearest\" criterion\n\t * (the texture element nearest to the center of the pixel) to produce a texture\n\t * value from each mipmap. The final texture value is a weighted average of those two\n\t * values.\n\t *\n\t * * LinearMipMapLinearFilter - (default) - Chooses the two mipmaps that most closely match the size\n\t * of the pixel being textured and uses the \"linear\" criterion (a weighted average\n\t * of the four texture elements that are closest to the center of the pixel) to\n\t * produce a texture value from each mipmap. The final texture value is a weighted\n\t * average of those two values.\n\t *\n\t * Default value is LinearMipMapLinearFilter.\n\t *\n\t * @type {Number}\n\t */\n\tget minFilter() {\n\t\treturn this._state.minFilter;\n\t}\n\n\t/**\n\t * Gets how this Texture is sampled when a texel covers more than one pixel.\n\t *\n\t * * NearestFilter - Uses the value of the texture element that is nearest\n\t * (in Manhattan distance) to the center of the pixel being textured.\n\t * * LinearFilter - (default) - Uses the weighted average of the four texture elements that are\n\t * closest to the center of the pixel being textured.\n\t *\n\t * Default value is LinearMipMapLinearFilter.\n\t *\n\t * @type {Number}\n\t */\n\tget magFilter() {\n\t\treturn this._state.magFilter;\n\t}\n\n\t/**\n\t * Gets the wrap parameter for this Texture's *S* coordinate.\n\t *\n\t * Values can be:\n\t *\n\t * * ClampToEdgeWrapping - causes *S* coordinates to be clamped to the size of the texture.\n\t * * MirroredRepeatWrapping - causes the *S* coordinate to be set to the fractional part of the texture coordinate\n\t * if the integer part of *S* is even; if the integer part of *S* is odd, then the *S* texture coordinate is\n\t * set to *1 - frac ⁡ S* , where *frac ⁡ S* represents the fractional part of *S*.\n\t * * RepeatWrapping - (default) - causes the integer part of the *S* coordinate to be ignored; xeokit uses only the\n\t * fractional part, thereby creating a repeating pattern.\n\t *\n\t * Default value is RepeatWrapping.\n\t *\n\t * @type {Number}\n\t */\n\tget wrapS() {\n\t\treturn this._state.wrapS;\n\t}\n\n\t/**\n\t * Gets the wrap parameter for this Texture's *T* coordinate.\n\t *\n\t * Values can be:\n\t *\n\t * * ClampToEdgeWrapping - causes *S* coordinates to be clamped to the size of the texture.\n\t * * MirroredRepeatWrapping - causes the *S* coordinate to be set to the fractional part of the texture coordinate\n\t * if the integer part of *S* is even; if the integer part of *S* is odd, then the *S* texture coordinate is\n\t * set to *1 - frac ⁡ S* , where *frac ⁡ S* represents the fractional part of *S*.\n\t * * RepeatWrapping - (default) - causes the integer part of the *S* coordinate to be ignored; xeokit uses only the\n\t * fractional part, thereby creating a repeating pattern.\n\t *\n\t * Default value is RepeatWrapping.\n\t *\n\t * @type {Number}\n\t */\n\tget wrapT() {\n\t\treturn this._state.wrapT;\n\t}\n\n\t/**\n\t * Gets if this Texture's source data is flipped along its vertical axis.\n\t *\n\t * @type {Number}\n\t */\n\tget flipY() {\n\t\treturn this._state.flipY;\n\t}\n\n\t/**\n\t * Gets the Texture's encoding format.\n\t *\n\t * @type {Number}\n\t */\n\tget encoding() {\n\t\treturn this._state.encoding;\n\t}\n\n\t/**\n\t * Destroys this Texture\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\t\tif (this._state.texture) {\n\t\t\tthis._state.texture.destroy();\n\t\t}\n\t\tthis._state.destroy();\n\t\t_stats_js__WEBPACK_IMPORTED_MODULE_4__.stats.memory.textures--;\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/materials/Texture.js?");
3208
3228
 
3209
3229
  /***/ }),
3210
3230
 
@@ -3524,7 +3544,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3524
3544
  \**********************************************/
3525
3545
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3526
3546
 
3527
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SceneModel: () => (/* binding */ SceneModel)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../math/buildEdgeIndices.js */ \"./src/viewer/scene/math/buildEdgeIndices.js\");\n/* harmony import */ var _SceneModelMesh_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./SceneModelMesh.js */ \"./src/viewer/scene/model/SceneModelMesh.js\");\n/* harmony import */ var _vbo_ScratchMemory_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./vbo/ScratchMemory.js */ \"./src/viewer/scene/model/vbo/ScratchMemory.js\");\n/* harmony import */ var _vbo_batching_triangles_VBOBatchingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./vbo/batching/triangles/VBOBatchingTrianglesLayer.js */ \"./src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js\");\n/* harmony import */ var _vbo_instancing_triangles_VBOInstancingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./vbo/instancing/triangles/VBOInstancingTrianglesLayer.js */ \"./src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js\");\n/* harmony import */ var _vbo_batching_lines_VBOBatchingLinesLayer_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./vbo/batching/lines/VBOBatchingLinesLayer.js */ \"./src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js\");\n/* harmony import */ var _vbo_instancing_lines_VBOInstancingLinesLayer_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./vbo/instancing/lines/VBOInstancingLinesLayer.js */ \"./src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js\");\n/* harmony import */ var _vbo_batching_points_VBOBatchingPointsLayer_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./vbo/batching/points/VBOBatchingPointsLayer.js */ \"./src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js\");\n/* harmony import */ var _vbo_instancing_points_VBOInstancingPointsLayer_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./vbo/instancing/points/VBOInstancingPointsLayer.js */ \"./src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js\");\n/* harmony import */ var _dtx_lines_DTXLinesLayer_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./dtx/lines/DTXLinesLayer.js */ \"./src/viewer/scene/model/dtx/lines/DTXLinesLayer.js\");\n/* harmony import */ var _dtx_triangles_DTXTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./dtx/triangles/DTXTrianglesLayer.js */ \"./src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js\");\n/* harmony import */ var _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ENTITY_FLAGS.js */ \"./src/viewer/scene/model/ENTITY_FLAGS.js\");\n/* harmony import */ var _webgl_RenderFlags_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../webgl/RenderFlags.js */ \"./src/viewer/scene/webgl/RenderFlags.js\");\n/* harmony import */ var _math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n/* harmony import */ var _SceneModelTextureSet_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./SceneModelTextureSet.js */ \"./src/viewer/scene/model/SceneModelTextureSet.js\");\n/* harmony import */ var _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./SceneModelTexture.js */ \"./src/viewer/scene/model/SceneModelTexture.js\");\n/* harmony import */ var _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../webgl/Texture2D.js */ \"./src/viewer/scene/webgl/Texture2D.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _utils_textureTranscoders_KTX2TextureTranscoder_KTX2TextureTranscoder_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/textureTranscoders/KTX2TextureTranscoder/KTX2TextureTranscoder.js */ \"./src/viewer/scene/utils/textureTranscoders/KTX2TextureTranscoder/KTX2TextureTranscoder.js\");\n/* harmony import */ var _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../constants/constants.js */ \"./src/viewer/scene/constants/constants.js\");\n/* harmony import */ var _compression_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./compression.js */ \"./src/viewer/scene/model/compression.js\");\n/* harmony import */ var _calculateUniquePositions_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./calculateUniquePositions.js */ \"./src/viewer/scene/model/calculateUniquePositions.js\");\n/* harmony import */ var _rebucketPositions_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./rebucketPositions.js */ \"./src/viewer/scene/model/rebucketPositions.js\");\n/* harmony import */ var _SceneModelEntity_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./SceneModelEntity.js */ \"./src/viewer/scene/model/SceneModelEntity.js\");\n/* harmony import */ var _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../math/geometryCompressionUtils.js */ \"./src/viewer/scene/math/geometryCompressionUtils.js\");\n/* harmony import */ var _SceneModelTransform_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./SceneModelTransform.js */ \"./src/viewer/scene/model/SceneModelTransform.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst tempVec3a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\nconst tempOBB3 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3();\n\nconst DEFAULT_SCALE = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3([1, 1, 1]);\nconst DEFAULT_POSITION = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3([0, 0, 0]);\nconst DEFAULT_ROTATION = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3([0, 0, 0]);\nconst DEFAULT_QUATERNION = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.identityQuaternion();\nconst DEFAULT_MATRIX = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.identityMat4();\n\nconst DEFAULT_COLOR_TEXTURE_ID = \"defaultColorTexture\";\nconst DEFAULT_METAL_ROUGH_TEXTURE_ID = \"defaultMetalRoughTexture\";\nconst DEFAULT_NORMALS_TEXTURE_ID = \"defaultNormalsTexture\";\nconst DEFAULT_EMISSIVE_TEXTURE_ID = \"defaultEmissiveTexture\";\nconst DEFAULT_OCCLUSION_TEXTURE_ID = \"defaultOcclusionTexture\";\nconst DEFAULT_TEXTURE_SET_ID = \"defaultTextureSet\";\n\nconst defaultCompressedColor = new Uint8Array([255, 255, 255]);\n\nconst VBO_INSTANCED = 0;\nconst VBO_BATCHED = 1;\nconst DTX = 2;\n\n/**\n * @desc A high-performance model representation for efficient rendering and low memory usage.\n *\n * # Examples\n *\n * Internally, SceneModel uses a combination of several different techniques to render and represent\n * the different parts of a typical model. Each of the live examples at these links is designed to \"unit test\" one of these\n * techniques, in isolation. If some bug occurs in SceneModel, we use these tests to debug, but they also\n * serve to demonstrate how to use the capabilities of SceneModel programmatically.\n *\n * * [Loading building models into SceneModels](/examples/buildings)\n * * [Loading city models into SceneModels](/examples/cities)\n * * [Loading LiDAR scans into SceneModels](/examples/lidar)\n * * [Loading CAD models into SceneModels](/examples/cad)\n * * [SceneModel feature tests](/examples/scenemodel)\n *\n * # Overview\n *\n * While xeokit's standard [scene graph](https://github.com/xeokit/xeokit-sdk/wiki/Scene-Graphs) is great for gizmos and medium-sized models, it doesn't scale up to millions of objects in terms of memory and rendering efficiency.\n *\n * For huge models, we have the ````SceneModel```` representation, which is optimized to pack large amounts of geometry into memory and render it efficiently using WebGL.\n *\n * ````SceneModel```` is the default model representation loaded by (at least) {@link GLTFLoaderPlugin}, {@link XKTLoaderPlugin} and {@link WebIFCLoaderPlugin}.\n *\n * In this tutorial you'll learn how to use ````SceneModel```` to create high-detail content programmatically. Ordinarily you'd be learning about ````SceneModel```` if you were writing your own model loader plugins.\n *\n * # Contents\n *\n * - [SceneModel](#DataTextureSceneModel)\n * - [GPU-Resident Geometry](#gpu-resident-geometry)\n * - [Picking](#picking)\n * - [Example 1: Geometry Instancing](#example-1--geometry-instancing)\n * - [Finalizing a SceneModel](#finalizing-a-DataTextureSceneModel)\n * - [Finding Entities](#finding-entities)\n * - [Example 2: Geometry Batching](#example-2--geometry-batching)\n * - [Classifying with Metadata](#classifying-with-metadata)\n * - [Querying Metadata](#querying-metadata)\n * - [Metadata Structure](#metadata-structure)\n * - [RTC Coordinates](#rtc-coordinates-for-double-precision)\n * - [Example 3: RTC Coordinates with Geometry Instancing](#example-2--rtc-coordinates-with-geometry-instancing)\n * - [Example 4: RTC Coordinates with Geometry Batching](#example-2--rtc-coordinates-with-geometry-batching)\n *\n * ## SceneModel\n *\n * ````SceneModel```` uses two rendering techniques internally:\n *\n * 1. ***Geometry batching*** for unique geometries, combining those into a single WebGL geometry buffer, to render in one draw call, and\n * 2. ***geometry instancing*** for geometries that are shared by multiple meshes, rendering all instances of each shared geometry in one draw call.\n *\n * <br>\n * These techniques come with certain limitations:\n *\n * * Non-realistic rendering - while scene graphs can use xeokit's full set of material workflows, ````SceneModel```` uses simple Lambertian shading without textures.\n * * Static transforms - transforms within a ````SceneModel```` are static and cannot be dynamically translated, rotated and scaled the way {@link Node}s and {@link Mesh}es in scene graphs can.\n * * Immutable model representation - while scene graph {@link Node}s and\n * {@link Mesh}es can be dynamically plugged together, ````SceneModel```` is immutable,\n * since it packs its geometries into buffers and instanced arrays.\n *\n * ````SceneModel````'s API allows us to exploit batching and instancing, while exposing its elements as\n * abstract {@link Entity} types.\n *\n * {@link Entity} is the abstract base class for\n * the various xeokit components that represent models, objects, or anonymous visible elements. An Entity has a unique ID and can be\n * individually shown, hidden, selected, highlighted, ghosted, culled, picked and clipped, and has its own World-space boundary.\n *\n * * A ````SceneModel```` is an {@link Entity} that represents a model.\n * * A ````SceneModel```` represents each of its objects with an {@link Entity}.\n * * Each {@link Entity} has one or more meshes that define its shape.\n * * Each mesh has either its own unique geometry, or shares a geometry with other meshes.\n *\n * ## GPU-Resident Geometry\n *\n * For a low memory footprint, ````SceneModel```` stores its geometries in GPU memory only, compressed (quantized) as integers. Unfortunately, GPU-resident geometry is\n * not readable by JavaScript.\n *\n *\n * ## Example 1: Geometry Instancing\n *\n * In the example below, we'll use a ````SceneModel````\n * to build a simple table model using geometry instancing.\n *\n * We'll start by adding a reusable box-shaped geometry to our ````SceneModel````.\n *\n * Then, for each object in our model we'll add an {@link Entity}\n * that has a mesh that instances our box geometry, transforming and coloring the instance.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_instancing)\n *\n * ````javascript\n * import {Viewer, SceneModel} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\",\n * transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * // Build a SceneModel representing a table\n * // with four legs, using geometry instancing\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"table\",\n * isModel: true, // <--- Registers SceneModel in viewer.scene.models\n * position: [0, 0, 0],\n * scale: [1, 1, 1],\n * rotation: [0, 0, 0]\n * });\n *\n * // Create a reusable geometry within the SceneModel\n * // We'll instance this geometry by five meshes\n *\n * sceneModel.createGeometry({\n *\n * id: \"myBoxGeometry\",\n *\n * // The primitive type - allowed values are \"points\", \"lines\" and \"triangles\".\n * // See the OpenGL/WebGL specification docs\n * // for how the coordinate arrays are supposed to be laid out.\n * primitive: \"triangles\",\n *\n * // The vertices - eight for our cube, each\n * // one spanning three array elements for X,Y and Z\n * positions: [\n * 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // v0-v1-v2-v3 front\n * 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // v0-v3-v4-v1 right\n * 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // v0-v1-v6-v1 top\n * -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // v1-v6-v7-v2 left\n * -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // v7-v4-v3-v2 bottom\n * 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1 // v4-v7-v6-v1 back\n * ],\n *\n * // Normal vectors, one for each vertex\n * normals: [\n * 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0-v1-v2-v3 front\n * 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4-v5 right\n * 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0-v5-v6-v1 top\n * -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1-v6-v7-v2 left\n * 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, // v7-v4-v3-v2 bottom\n * 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1 // v4-v7-v6-v5 back\n * ],\n *\n * // Indices - these organise the positions and and normals\n * // into geometric primitives in accordance with the \"primitive\" parameter,\n * // in this case a set of three indices for each triangle.\n * //\n * // Note that each triangle is specified in counter-clockwise winding order.\n * //\n * indices: [\n * 0, 1, 2, 0, 2, 3, // front\n * 4, 5, 6, 4, 6, 7, // right\n * 8, 9, 10, 8, 10, 11, // top\n * 12, 13, 14, 12, 14, 15, // left\n * 16, 17, 18, 16, 18, 19, // bottom\n * 20, 21, 22, 20, 22, 23\n * ]\n * });\n *\n * // Red table leg\n *\n * sceneModel.createMesh({\n * id: \"redLegMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * id: \"redLeg\",\n * meshIds: [\"redLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Green table leg\n *\n * sceneModel.createMesh({\n * id: \"greenLegMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * id: \"greenLeg\",\n * meshIds: [\"greenLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Blue table leg\n *\n * sceneModel.createMesh({\n * id: \"blueLegMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"blueLeg\",\n * meshIds: [\"blueLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Yellow table leg\n *\n * sceneModel.createMesh({\n * id: \"yellowLegMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"yellowLeg\",\n * meshIds: [\"yellowLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Purple table top\n *\n * sceneModel.createMesh({\n * id: \"purpleTableTopMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"purpleTableTop\",\n * meshIds: [\"purpleTableTopMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n * ````\n *\n * ## Finalizing a SceneModel\n *\n * Before we can view and interact with our ````SceneModel````, we need to **finalize** it. Internally, this causes the ````SceneModel```` to build the\n * vertex buffer objects (VBOs) that support our geometry instances. When using geometry batching (see next example),\n * this causes ````SceneModel```` to build the VBOs that combine the batched geometries. Note that you can do both instancing and\n * batching within the same ````SceneModel````.\n *\n * Once finalized, we can't add anything more to our ````SceneModel````.\n *\n * ```` javascript\n * SceneModel.finalize();\n * ````\n *\n * ## Finding Entities\n *\n * As mentioned earlier, {@link Entity} is\n * the abstract base class for components that represent models, objects, or just\n * anonymous visible elements.\n *\n * Since we created configured our ````SceneModel```` with ````isModel: true````,\n * we're able to find it as an Entity by ID in ````viewer.scene.models````. Likewise, since\n * we configured each of its Entities with ````isObject: true````, we're able to\n * find them in ````viewer.scene.objects````.\n *\n *\n * ````javascript\n * // Get the whole table model Entity\n * const table = viewer.scene.models[\"table\"];\n *\n * // Get some leg object Entities\n * const redLeg = viewer.scene.objects[\"redLeg\"];\n * const greenLeg = viewer.scene.objects[\"greenLeg\"];\n * const blueLeg = viewer.scene.objects[\"blueLeg\"];\n * ````\n *\n * ## Example 2: Geometry Batching\n *\n * Let's once more use a ````SceneModel````\n * to build the simple table model, this time exploiting geometry batching.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_batching)\n *\n * ````javascript\n * import {Viewer, SceneModel} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\",\n * transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * // Create a SceneModel representing a table with four legs, using geometry batching\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"table\",\n * isModel: true, // <--- Registers SceneModel in viewer.scene.models\n * position: [0, 0, 0],\n * scale: [1, 1, 1],\n * rotation: [0, 0, 0]\n * });\n *\n * // Red table leg\n *\n * sceneModel.createMesh({\n * id: \"redLegMesh\",\n *\n * // Geometry arrays are same as for the earlier batching example\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * id: \"redLeg\",\n * meshIds: [\"redLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Green table leg\n *\n * sceneModel.createMesh({\n * id: \"greenLegMesh\",\n * primitive: \"triangles\",\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * id: \"greenLeg\",\n * meshIds: [\"greenLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Blue table leg\n *\n * sceneModel.createMesh({\n * id: \"blueLegMesh\",\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"blueLeg\",\n * meshIds: [\"blueLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Yellow table leg object\n *\n * sceneModel.createMesh({\n * id: \"yellowLegMesh\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"yellowLeg\",\n * meshIds: [\"yellowLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Purple table top\n *\n * sceneModel.createMesh({\n * id: \"purpleTableTopMesh\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"purpleTableTop\",\n * meshIds: [\"purpleTableTopMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Finalize the SceneModel.\n *\n * SceneModel.finalize();\n *\n * // Find BigModelNodes by their model and object IDs\n *\n * // Get the whole table model\n * const table = viewer.scene.models[\"table\"];\n *\n * // Get some leg objects\n * const redLeg = viewer.scene.objects[\"redLeg\"];\n * const greenLeg = viewer.scene.objects[\"greenLeg\"];\n * const blueLeg = viewer.scene.objects[\"blueLeg\"];\n * ````\n *\n * ## Classifying with Metadata\n *\n * In the previous examples, we used ````SceneModel```` to build\n * two versions of the same table model, to demonstrate geometry batching and geometry instancing.\n *\n * We'll now classify our {@link Entity}s with metadata. This metadata\n * will work the same for both our examples, since they create the exact same structure of {@link Entity}s\n * to represent their models and objects. The abstract Entity type is, after all, intended to provide an abstract interface through which differently-implemented scene content can be accessed uniformly.\n *\n * To create the metadata, we'll create a {@link MetaModel} for our model,\n * with a {@link MetaObject} for each of it's objects. The MetaModel and MetaObjects\n * get the same IDs as the {@link Entity}s that represent their model and objects within our scene.\n *\n * ```` javascript\n * const furnitureMetaModel = viewer.metaScene.createMetaModel(\"furniture\", { // Creates a MetaModel in the MetaScene\n *\n * \"projectId\": \"myTableProject\",\n * \"revisionId\": \"V1.0\",\n *\n * \"metaObjects\": [\n * { // Creates a MetaObject in the MetaModel\n * \"id\": \"table\",\n * \"name\": \"Table\", // Same ID as an object Entity\n * \"type\": \"furniture\", // Arbitrary type, could be IFC type\n * \"properties\": { // Arbitrary properties, could be IfcPropertySet\n * \"cost\": \"200\"\n * }\n * },\n * {\n * \"id\": \"redLeg\",\n * \"name\": \"Red table Leg\",\n * \"type\": \"leg\",\n * \"parent\": \"table\", // References first MetaObject as parent\n * \"properties\": {\n * \"material\": \"wood\"\n * }\n * },\n * {\n * \"id\": \"greenLeg\", // Node with corresponding id does not need to exist\n * \"name\": \"Green table leg\", // and MetaObject does not need to exist for Node with an id\n * \"type\": \"leg\",\n * \"parent\": \"table\",\n * \"properties\": {\n * \"material\": \"wood\"\n * }\n * },\n * {\n * \"id\": \"blueLeg\",\n * \"name\": \"Blue table leg\",\n * \"type\": \"leg\",\n * \"parent\": \"table\",\n * \"properties\": {\n * \"material\": \"wood\"\n * }\n * },\n * {\n * \"id\": \"yellowLeg\",\n * \"name\": \"Yellow table leg\",\n * \"type\": \"leg\",\n * \"parent\": \"table\",\n * \"properties\": {\n * \"material\": \"wood\"\n * }\n * },\n * {\n * \"id\": \"tableTop\",\n * \"name\": \"Purple table top\",\n * \"type\": \"surface\",\n * \"parent\": \"table\",\n * \"properties\": {\n * \"material\": \"formica\",\n * \"width\": \"60\",\n * \"depth\": \"60\",\n * \"thickness\": \"5\"\n * }\n * }\n * ]\n * });\n * ````\n *\n * ## Querying Metadata\n *\n * Having created and classified our model (either the instancing or batching example), we can now find the {@link MetaModel}\n * and {@link MetaObject}s using the IDs of their\n * corresponding {@link Entity}s.\n *\n * ````JavaScript\n * const furnitureMetaModel = scene.metaScene.metaModels[\"furniture\"];\n *\n * const redLegMetaObject = scene.metaScene.metaObjects[\"redLeg\"];\n * ````\n *\n * In the snippet below, we'll log metadata on each {@link Entity} we click on:\n *\n * ````JavaScript\n * viewer.scene.input.on(\"mouseclicked\", function (coords) {\n *\n * const hit = viewer.scene.pick({\n * canvasPos: coords\n * });\n *\n * if (hit) {\n * const entity = hit.entity;\n * const metaObject = viewer.metaScene.metaObjects[entity.id];\n * if (metaObject) {\n * console.log(JSON.stringify(metaObject.getJSON(), null, \"\\t\"));\n * }\n * }\n * });\n * ````\n *\n * ## Metadata Structure\n *\n * The {@link MetaModel}\n * organizes its {@link MetaObject}s in\n * a tree that describes their structural composition:\n *\n * ````JavaScript\n * // Get metadata on the root object\n * const tableMetaObject = furnitureMetaModel.rootMetaObject;\n *\n * // Get metadata on the leg objects\n * const redLegMetaObject = tableMetaObject.children[0];\n * const greenLegMetaObject = tableMetaObject.children[1];\n * const blueLegMetaObject = tableMetaObject.children[2];\n * const yellowLegMetaObject = tableMetaObject.children[3];\n * ````\n *\n * Given an {@link Entity}, we can find the object or model of which it is a part, or the objects that comprise it. We can also generate UI\n * components from the metadata, such as the tree view demonstrated in [this demo](https://xeokit.github.io/xeokit-sdk/examples/#BIMOffline_glTF_OTCConferenceCenter).\n *\n * This hierarchy allows us to express the hierarchical structure of a model while representing it in\n * various ways in the 3D scene (such as with ````SceneModel````, which\n * has a non-hierarchical scene representation).\n *\n * Note also that a {@link MetaObject} does not need to have a corresponding\n * {@link Entity} and vice-versa.\n *\n * # RTC Coordinates for Double Precision\n *\n * ````SceneModel```` can emulate 64-bit precision on GPUs using relative-to-center (RTC) coordinates.\n *\n * Consider a model that contains many small objects, but with such large spatial extents that 32 bits of GPU precision (accurate to ~7 digits) will not be sufficient to render all of the the objects without jittering.\n *\n * To prevent jittering, we could spatially subdivide the objects into \"tiles\". Each tile would have a center position, and the positions of the objects within the tile would be relative to that center (\"RTC coordinates\").\n *\n * While the center positions of the tiles would be 64-bit values, the object positions only need to be 32-bit.\n *\n * Internally, when rendering an object with RTC coordinates, xeokit first temporarily translates the camera viewing matrix by the object's tile's RTC center, on the CPU, using 64-bit math.\n *\n * Then xeokit loads the viewing matrix into its WebGL shaders, where math happens at 32-bit precision. Within the shaders, the matrix is effectively down-cast to 32-bit precision, and the object's 32-bit vertex positions are transformed by the matrix.\n *\n * We see no jittering, because with RTC a detectable loss of GPU accuracy only starts happening to objects as they become very distant from the camera viewpoint, at which point they are too small to be discernible anyway.\n *\n * ## RTC Coordinates with Geometry Instancing\n *\n * To use RTC with ````SceneModel```` geometry instancing, we specify an RTC center for the geometry via its ````origin```` parameter. Then ````SceneModel```` assumes that all meshes that instance that geometry are within the same RTC coordinate system, ie. the meshes ````position```` and ````rotation```` properties are assumed to be relative to the geometry's ````origin````.\n *\n * For simplicity, our example's meshes all instance the same geometry. Therefore, our example model has only one RTC center.\n *\n * Note that the axis-aligned World-space boundary (AABB) of our model is ````[ -6, -9, -6, 1000000006, -2.5, 1000000006]````.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_batching)\n *\n * ````javascript\n * const origin = [100000000, 0, 100000000];\n *\n * sceneModel.createGeometry({\n * id: \"box\",\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg1\",\n * geometryId: \"box\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg1\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg2\",\n * geometryId: \"box\",\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg2\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg3\",\n * geometryId: \"box\",\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg3\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg4\",\n * geometryId: \"box\",\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg4\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"top\",\n * geometryId: \"box\",\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"top\"],\n * isObject: true\n * });\n * ````\n *\n * ## RTC Coordinates with Geometry Batching\n *\n * To use RTC with ````SceneModel```` geometry batching, we specify an RTC center (````origin````) for each mesh. For performance, we try to have as many meshes share the same value for ````origin```` as possible. Each mesh's ````positions````, ````position```` and ````rotation```` properties are assumed to be relative to ````origin````.\n *\n * For simplicity, the meshes in our example all share the same RTC center.\n *\n * The axis-aligned World-space boundary (AABB) of our model is ````[ -6, -9, -6, 1000000006, -2.5, 1000000006]````.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_batching)\n *\n * ````javascript\n * const origin = [100000000, 0, 100000000];\n *\n * sceneModel.createMesh({\n * id: \"leg1\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg1\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg2\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg2\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg3\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg3\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg4\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg4\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"top\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"top\"],\n * isObject: true\n * });\n * ````\n *\n * ## Positioning at World-space coordinates\n *\n * To position a SceneModel at given double-precision World coordinates, we can\n * configure the ````origin```` of the SceneModel itself. The ````origin```` is a double-precision\n * 3D World-space position at which the SceneModel will be located.\n *\n * Note that ````position```` is a single-precision offset relative to ````origin````.\n *\n * ````javascript\n * const origin = [100000000, 0, 100000000];\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"table\",\n * isModel: true,\n * origin: origin, // Everything in this SceneModel is relative to this RTC center\n * position: [0, 0, 0],\n * scale: [1, 1, 1],\n * rotation: [0, 0, 0]\n * });\n *\n * sceneModel.createGeometry({\n * id: \"box\",\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg1\",\n * geometryId: \"box\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg1\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg2\",\n * geometryId: \"box\",\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg2\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg3\",\n * geometryId: \"box\",\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg3\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg4\",\n * geometryId: \"box\",\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg4\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"top\",\n * geometryId: \"box\",\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"top\"],\n * isObject: true\n * });\n * ````\n *\n * # Textures\n *\n * ## Loading KTX2 Texture Files into a SceneModel\n *\n * A {@link SceneModel} that is configured with a {@link KTX2TextureTranscoder} will\n * allow us to load textures into it from KTX2 buffers or files.\n *\n * In the example below, we'll create a {@link Viewer}, containing a {@link SceneModel} configured with a\n * {@link KTX2TextureTranscoder}. We'll then programmatically create a simple object within the SceneModel, consisting of\n * a single mesh with a texture loaded from a KTX2 file, which our SceneModel internally transcodes, using\n * its {@link KTX2TextureTranscoder}. Note how we configure our {@link KTX2TextureTranscoder} with a path to the Basis Universal\n * transcoder WASM module.\n *\n * ````javascript\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\",\n * transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n * viewer,\n * transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to BasisU transcoder module\n * });\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"myModel\",\n * textureTranscoder // <<-------------------- Configure model with our transcoder\n * });\n *\n * sceneModel.createTexture({\n * id: \"myColorTexture\",\n * src: \"../assets/textures/compressed/sample_uastc_zstd.ktx2\" // <<----- KTX2 texture asset\n * });\n *\n * sceneModel.createTexture({\n * id: \"myMetallicRoughnessTexture\",\n * src: \"../assets/textures/alpha/crosshatchAlphaMap.jpg\" // <<----- JPEG texture asset\n * });\n *\n * sceneModel.createTextureSet({\n * id: \"myTextureSet\",\n * colorTextureId: \"myColorTexture\",\n * metallicRoughnessTextureId: \"myMetallicRoughnessTexture\"\n * });\n *\n * sceneModel.createMesh({\n * id: \"myMesh\",\n * textureSetId: \"myTextureSet\",\n * primitive: \"triangles\",\n * positions: [1, 1, 1, ...],\n * normals: [0, 0, 1, 0, ...],\n * uv: [1, 0, 0, ...],\n * indices: [0, 1, 2, ...],\n * });\n *\n * sceneModel.createEntity({\n * id: \"myEntity\",\n * meshIds: [\"myMesh\"]\n * });\n *\n * sceneModel.finalize();\n * ````\n *\n * ## Loading KTX2 Textures from ArrayBuffers into a SceneModel\n *\n * A SceneModel that is configured with a {@link KTX2TextureTranscoder} will allow us to load textures into\n * it from KTX2 ArrayBuffers.\n *\n * In the example below, we'll create a {@link Viewer}, containing a {@link SceneModel} configured with a\n * {@link KTX2TextureTranscoder}. We'll then programmatically create a simple object within the SceneModel, consisting of\n * a single mesh with a texture loaded from a KTX2 ArrayBuffer, which our SceneModel internally transcodes, using\n * its {@link KTX2TextureTranscoder}.\n *\n * ````javascript\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\",\n * transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n * viewer,\n * transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to BasisU transcoder module\n * });\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"myModel\",\n * textureTranscoder // <<-------------------- Configure model with our transcoder\n * });\n *\n * utils.loadArraybuffer(\"../assets/textures/compressed/sample_uastc_zstd.ktx2\",(arrayBuffer) => {\n *\n * sceneModel.createTexture({\n * id: \"myColorTexture\",\n * buffers: [arrayBuffer] // <<----- KTX2 texture asset\n * });\n *\n * sceneModel.createTexture({\n * id: \"myMetallicRoughnessTexture\",\n * src: \"../assets/textures/alpha/crosshatchAlphaMap.jpg\" // <<----- JPEG texture asset\n * });\n *\n * sceneModel.createTextureSet({\n * id: \"myTextureSet\",\n * colorTextureId: \"myColorTexture\",\n * metallicRoughnessTextureId: \"myMetallicRoughnessTexture\"\n * });\n *\n * sceneModel.createMesh({\n * id: \"myMesh\",\n * textureSetId: \"myTextureSet\",\n * primitive: \"triangles\",\n * positions: [1, 1, 1, ...],\n * normals: [0, 0, 1, 0, ...],\n * uv: [1, 0, 0, ...],\n * indices: [0, 1, 2, ...],\n * });\n *\n * sceneModel.createEntity({\n * id: \"myEntity\",\n * meshIds: [\"myMesh\"]\n * });\n *\n * sceneModel.finalize();\n * });\n * ````\n *\n * @implements {Entity}\n */\nclass SceneModel extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\n\n /**\n * @constructor\n * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent scene, generated automatically when omitted.\n * @param {Boolean} [cfg.isModel] Specify ````true```` if this SceneModel represents a model, in which case the SceneModel will be registered by {@link SceneModel#id} in {@link Scene#models} and may also have a corresponding {@link MetaModel} with matching {@link MetaModel#id}, registered by that ID in {@link MetaScene#metaModels}.\n * @param {Number[]} [cfg.origin=[0,0,0]] World-space double-precision 3D origin.\n * @param {Number[]} [cfg.position=[0,0,0]] Local, single-precision 3D position, relative to the origin parameter.\n * @param {Number[]} [cfg.scale=[1,1,1]] Local scale.\n * @param {Number[]} [cfg.rotation=[0,0,0]] Local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] Local modelling transform matrix. Overrides the position, scale and rotation parameters.\n * @param {Boolean} [cfg.visible=true] Indicates if the SceneModel is initially visible.\n * @param {Boolean} [cfg.culled=false] Indicates if the SceneModel is initially culled from view.\n * @param {Boolean} [cfg.pickable=true] Indicates if the SceneModel is initially pickable.\n * @param {Boolean} [cfg.clippable=true] Indicates if the SceneModel is initially clippable.\n * @param {Boolean} [cfg.collidable=true] Indicates if the SceneModel is initially included in boundary calculations.\n * @param {Boolean} [cfg.xrayed=false] Indicates if the SceneModel is initially xrayed.\n * @param {Boolean} [cfg.highlighted=false] Indicates if the SceneModel is initially highlighted.\n * @param {Boolean} [cfg.selected=false] Indicates if the SceneModel is initially selected.\n * @param {Boolean} [cfg.edges=false] Indicates if the SceneModel's edges are initially emphasized.\n * @param {Number[]} [cfg.colorize=[1.0,1.0,1.0]] SceneModel's initial RGB colorize color, multiplies by the rendered fragment colors.\n * @param {Number} [cfg.opacity=1.0] SceneModel's initial opacity factor, multiplies by the rendered fragment alpha.\n * @param {Number} [cfg.backfaces=false] When we set this ````true````, then we force rendering of backfaces for this SceneModel. When\n * we leave this ````false````, then we allow the Viewer to decide when to render backfaces. In that case, the\n * Viewer will hide backfaces on watertight meshes, show backfaces on open meshes, and always show backfaces on meshes when we slice them open with {@link SectionPlane}s.\n * @param {Boolean} [cfg.saoEnabled=true] Indicates if Scalable Ambient Obscurance (SAO) will apply to this SceneModel. SAO is configured by the Scene's {@link SAO} component.\n * @param {Boolean} [cfg.pbrEnabled=true] Indicates if physically-based rendering (PBR) will apply to the SceneModel when {@link Scene#pbrEnabled} is ````true````.\n * @param {Boolean} [cfg.colorTextureEnabled=true] Indicates if base color textures will be rendered for the SceneModel when {@link Scene#colorTextureEnabled} is ````true````.\n * @param {Number} [cfg.edgeThreshold=10] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n * @param {Number} [cfg.maxGeometryBatchSize=50000000] Maximum geometry batch size, as number of vertices. This is optionally supplied\n * to limit the size of the batched geometry arrays that SceneModel internally creates for batched geometries.\n * A lower value means less heap allocation/de-allocation while creating/loading batched geometries, but more draw calls and\n * slower rendering speed. A high value means larger heap allocation/de-allocation while creating/loading, but less draw calls\n * and faster rendering speed. It's recommended to keep this somewhere roughly between ````50000```` and ````50000000```.\n * @param {TextureTranscoder} [cfg.textureTranscoder] Transcoder that will be used internally by {@link SceneModel#createTexture}\n * to convert transcoded texture data. Only required when we'll be providing transcoded data\n * to {@link SceneModel#createTexture}. We assume that all transcoded texture data added to a ````SceneModel````\n * will then in a format supported by this transcoder.\n * @param {Boolean} [cfg.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to\n * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable\n * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point\n * primitives. Only works while {@link DTX#enabled} is also ````true````.\n */\n constructor(owner, cfg = {}) {\n\n super(owner, cfg);\n\n this._dtxEnabled = this.scene.dtxEnabled && (cfg.dtxEnabled !== false);\n\n this._enableVertexWelding = false; // Not needed for most objects, and very expensive, so disabled\n this._enableIndexBucketing = false; // Until fixed: https://github.com/xeokit/xeokit-sdk/issues/1204\n\n this._vboBatchingLayerScratchMemory = (0,_vbo_ScratchMemory_js__WEBPACK_IMPORTED_MODULE_4__.getScratchMemory)();\n this._textureTranscoder = cfg.textureTranscoder || (0,_utils_textureTranscoders_KTX2TextureTranscoder_KTX2TextureTranscoder_js__WEBPACK_IMPORTED_MODULE_20__.getKTX2TextureTranscoder)(this.scene.viewer);\n\n this._maxGeometryBatchSize = cfg.maxGeometryBatchSize;\n\n this._aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n this._aabbDirty = true;\n\n this._quantizationRanges = {};\n\n this._vboInstancingLayers = {};\n this._vboBatchingLayers = {};\n this._dtxLayers = {};\n\n this.layerList = []; // For GL state efficiency when drawing, InstancingLayers are in first part, BatchingLayers are in second\n this._entityList = [];\n\n this._geometries = {};\n this._dtxBuckets = {}; // Geometries with optimizations used for data texture representation\n this._textures = {};\n this._textureSets = {};\n this._transforms = {};\n this._meshes = {};\n this._entities = {};\n\n this._scheduledMeshes = {};\n this._meshesCfgsBeforeMeshCreation = {};\n\n /** @private **/\n this.renderFlags = new _webgl_RenderFlags_js__WEBPACK_IMPORTED_MODULE_14__.RenderFlags();\n\n /**\n * @private\n */\n this.numGeometries = 0; // Number of geometries created with createGeometry()\n\n // These counts are used to avoid unnecessary render passes\n // They are incremented or decremented exclusively by BatchingLayer and InstancingLayer\n\n /**\n * @private\n */\n this.numPortions = 0;\n\n /**\n * @private\n */\n this.numVisibleLayerPortions = 0;\n\n /**\n * @private\n */\n this.numTransparentLayerPortions = 0;\n\n /**\n * @private\n */\n this.numXRayedLayerPortions = 0;\n\n /**\n * @private\n */\n this.numHighlightedLayerPortions = 0;\n\n /**\n * @private\n */\n this.numSelectedLayerPortions = 0;\n\n /**\n * @private\n */\n this.numEdgesLayerPortions = 0;\n\n /**\n * @private\n */\n this.numPickableLayerPortions = 0;\n\n /**\n * @private\n */\n this.numClippableLayerPortions = 0;\n\n /**\n * @private\n */\n this.numCulledLayerPortions = 0;\n\n this.numEntities = 0;\n this._numTriangles = 0;\n this._numLines = 0;\n this._numPoints = 0;\n\n this._edgeThreshold = cfg.edgeThreshold || 10;\n\n // Build static matrix\n\n this._origin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.origin || [0, 0, 0]);\n this._position = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.position || [0, 0, 0]);\n this._rotation = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.rotation || [0, 0, 0]);\n this._quaternion = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4(cfg.quaternion || [0, 0, 0, 1]);\n this._conjugateQuaternion = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4(cfg.quaternion || [0, 0, 0, 1]);\n\n if (cfg.rotation) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n }\n this._scale = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.scale || [1, 1, 1]);\n\n this._worldRotationMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n this._worldRotationMatrixConjugate = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n this._matrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n this._matrixDirty = true;\n\n this._rebuildMatrices();\n\n this._worldNormalMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(this._matrix, this._worldNormalMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transposeMat4(this._worldNormalMatrix);\n\n if (cfg.matrix || cfg.position || cfg.rotation || cfg.scale || cfg.quaternion) {\n this._viewMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n this._viewNormalMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n this._viewMatrixDirty = true;\n this._matrixNonIdentity = true;\n }\n\n this._opacity = 1.0;\n this._colorize = [1, 1, 1];\n\n this._saoEnabled = (cfg.saoEnabled !== false);\n this._pbrEnabled = (cfg.pbrEnabled !== false);\n this._colorTextureEnabled = (cfg.colorTextureEnabled !== false);\n\n this._isModel = cfg.isModel;\n if (this._isModel) {\n this.scene._registerModel(this);\n }\n\n this._onCameraViewMatrix = this.scene.camera.on(\"matrix\", () => {\n this._viewMatrixDirty = true;\n });\n\n this._meshesWithDirtyMatrices = [];\n this._numMeshesWithDirtyMatrices = 0;\n\n this._onTick = this.scene.on(\"tick\", () => {\n while (this._numMeshesWithDirtyMatrices > 0) {\n this._meshesWithDirtyMatrices[--this._numMeshesWithDirtyMatrices]._updateMatrix();\n }\n });\n\n this._createDefaultTextureSet();\n\n this.visible = cfg.visible;\n this.culled = cfg.culled;\n this.pickable = cfg.pickable;\n this.clippable = cfg.clippable;\n this.collidable = cfg.collidable;\n this.castsShadow = cfg.castsShadow;\n this.receivesShadow = cfg.receivesShadow;\n this.xrayed = cfg.xrayed;\n this.highlighted = cfg.highlighted;\n this.selected = cfg.selected;\n this.edges = cfg.edges;\n this.colorize = cfg.colorize;\n this.opacity = cfg.opacity;\n this.backfaces = cfg.backfaces;\n }\n\n _meshMatrixDirty(mesh) {\n this._meshesWithDirtyMatrices[this._numMeshesWithDirtyMatrices++] = mesh;\n }\n\n _createDefaultTextureSet() {\n // Every SceneModelMesh gets at least the default TextureSet,\n // which contains empty default textures filled with color\n const defaultColorTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n id: DEFAULT_COLOR_TEXTURE_ID,\n texture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n gl: this.scene.canvas.gl,\n preloadColor: [1, 1, 1, 1] // [r, g, b, a]})\n })\n });\n const defaultMetalRoughTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n id: DEFAULT_METAL_ROUGH_TEXTURE_ID,\n texture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n gl: this.scene.canvas.gl,\n preloadColor: [0, 1, 1, 1] // [unused, roughness, metalness, unused]\n })\n });\n const defaultNormalsTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n id: DEFAULT_NORMALS_TEXTURE_ID,\n texture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n gl: this.scene.canvas.gl,\n preloadColor: [0, 0, 0, 0] // [x, y, z, unused] - these must be zeros\n })\n });\n const defaultEmissiveTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n id: DEFAULT_EMISSIVE_TEXTURE_ID,\n texture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n gl: this.scene.canvas.gl,\n preloadColor: [0, 0, 0, 1] // [x, y, z, unused]\n })\n });\n const defaultOcclusionTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n id: DEFAULT_OCCLUSION_TEXTURE_ID,\n texture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n gl: this.scene.canvas.gl,\n preloadColor: [1, 1, 1, 1] // [x, y, z, unused]\n })\n });\n this._textures[DEFAULT_COLOR_TEXTURE_ID] = defaultColorTexture;\n this._textures[DEFAULT_METAL_ROUGH_TEXTURE_ID] = defaultMetalRoughTexture;\n this._textures[DEFAULT_NORMALS_TEXTURE_ID] = defaultNormalsTexture;\n this._textures[DEFAULT_EMISSIVE_TEXTURE_ID] = defaultEmissiveTexture;\n this._textures[DEFAULT_OCCLUSION_TEXTURE_ID] = defaultOcclusionTexture;\n this._textureSets[DEFAULT_TEXTURE_SET_ID] = new _SceneModelTextureSet_js__WEBPACK_IMPORTED_MODULE_16__.SceneModelTextureSet({\n id: DEFAULT_TEXTURE_SET_ID,\n model: this,\n colorTexture: defaultColorTexture,\n metallicRoughnessTexture: defaultMetalRoughTexture,\n normalsTexture: defaultNormalsTexture,\n emissiveTexture: defaultEmissiveTexture,\n occlusionTexture: defaultOcclusionTexture\n });\n }\n\n //------------------------------------------------------------------------------------------------------------------\n // SceneModel members\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Returns true to indicate that this Component is a SceneModel.\n * @type {Boolean}\n */\n get isPerformanceModel() {\n return true;\n }\n\n /**\n * The {@link SceneModelTransform}s in this SceneModel.\n *\n * Each {#link SceneModelTransform} is stored here against its {@link SceneModelTransform.id}.\n *\n * @returns {*|{}}\n */\n get transforms() {\n return this._transforms;\n }\n\n /**\n * The {@link SceneModelTexture}s in this SceneModel.\n *\n * * Each {@link SceneModelTexture} is created with {@link SceneModel.createTexture}.\n * * Each {@link SceneModelTexture} is stored here against its {@link SceneModelTexture.id}.\n *\n * @returns {*|{}}\n */\n get textures() {\n return this._textures;\n }\n\n /**\n * The {@link SceneModelTextureSet}s in this SceneModel.\n *\n * Each {@link SceneModelTextureSet} is stored here against its {@link SceneModelTextureSet.id}.\n *\n * @returns {*|{}}\n */\n get textureSets() {\n return this._textureSets;\n }\n\n /**\n * The {@link SceneModelMesh}es in this SceneModel.\n *\n * Each {@SceneModelMesh} is stored here against its {@link SceneModelMesh.id}.\n *\n * @returns {*|{}}\n */\n get meshes() {\n return this._meshes;\n }\n\n /**\n * The {@link SceneModelEntity}s in this SceneModel.\n *\n * Each {#link SceneModelEntity} in this SceneModel that represents an object is\n * stored here against its {@link SceneModelTransform.id}.\n *\n * @returns {*|{}}\n */\n get objects() {\n return this._entities;\n }\n\n /**\n * Gets the 3D World-space origin for this SceneModel.\n *\n * Each {@link SceneModelMesh.origin}, if supplied, is relative to this origin.\n *\n * Default value is ````[0,0,0]````.\n *\n * @type {Float64Array}\n */\n get origin() {\n return this._origin;\n }\n\n /**\n * Sets the SceneModel's local translation.\n *\n * Default value is ````[0,0,0]````.\n *\n * @type {Number[]}\n */\n set position(value) {\n this._position.set(value || [0, 0, 0]);\n this._setWorldMatrixDirty();\n this._sceneModelDirty();\n this.glRedraw();\n }\n\n /**\n * Gets the SceneModel's local translation.\n *\n * Default value is ````[0,0,0]````.\n *\n * @type {Number[]}\n */\n get position() {\n return this._position;\n }\n\n /**\n * Sets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n *\n * Default value is ````[0,0,0]````.\n *\n * @type {Number[]}\n */\n set rotation(value) {\n this._rotation.set(value || [0, 0, 0]);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n this._setWorldMatrixDirty();\n this._sceneModelDirty();\n this.glRedraw();\n }\n\n /**\n * Gets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n *\n * Default value is ````[0,0,0]````.\n *\n * @type {Number[]}\n */\n get rotation() {\n return this._rotation;\n }\n\n /**\n * Sets the SceneModel's local rotation quaternion.\n *\n * Default value is ````[0,0,0,1]````.\n *\n * @type {Number[]}\n */\n set quaternion(value) {\n this._quaternion.set(value || [0, 0, 0, 1]);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToEuler(this._quaternion, \"XYZ\", this._rotation);\n this._setWorldMatrixDirty();\n this._sceneModelDirty();\n this.glRedraw();\n }\n\n /**\n * Gets the SceneModel's local rotation quaternion.\n *\n * Default value is ````[0,0,0,1]````.\n *\n * @type {Number[]}\n */\n get quaternion() {\n return this._quaternion;\n }\n\n /**\n * Sets the SceneModel's local scale.\n *\n * Default value is ````[1,1,1]````.\n *\n * @type {Number[]}\n * @deprecated\n */\n set scale(value) {\n // NOP - deprecated\n }\n\n /**\n * Gets the SceneModel's local scale.\n *\n * Default value is ````[1,1,1]````.\n *\n * @type {Number[]}\n * @deprecated\n */\n get scale() {\n return this._scale;\n }\n\n /**\n * Sets the SceneModel's local modeling transform matrix.\n *\n * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n *\n * @type {Number[]}\n */\n set matrix(value) {\n this._matrix.set(value || DEFAULT_MATRIX);\n\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.conjugateQuaternion(this._quaternion, this._conjugateQuaternion);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrixConjugate);\n this._matrix.set(this._worldRotationMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.translateMat4v(this._position, this._matrix);\n\n this._matrixDirty = false;\n this._setWorldMatrixDirty();\n this._sceneModelDirty();\n this.glRedraw();\n }\n\n /**\n * Gets the SceneModel's local modeling transform matrix.\n *\n * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n *\n * @type {Number[]}\n */\n get matrix() {\n if (this._matrixDirty) {\n this._rebuildMatrices();\n }\n return this._matrix;\n }\n\n /**\n * Gets the SceneModel's local modeling rotation transform matrix.\n *\n * @type {Number[]}\n */\n get rotationMatrix() {\n if (this._matrixDirty) {\n this._rebuildMatrices();\n }\n return this._worldRotationMatrix;\n }\n\n _rebuildMatrices() {\n if (this._matrixDirty) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.conjugateQuaternion(this._quaternion, this._conjugateQuaternion);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrixConjugate);\n this._matrix.set(this._worldRotationMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.translateMat4v(this._position, this._matrix);\n this._matrixDirty = false;\n }\n }\n\n /**\n * Gets the conjugate of the SceneModel's local modeling rotation transform matrix.\n *\n * This is used for RTC view matrix management in renderers.\n *\n * @type {Number[]}\n */\n get rotationMatrixConjugate() {\n if (this._matrixDirty) {\n this._rebuildMatrices();\n }\n return this._worldRotationMatrixConjugate;\n }\n\n _setWorldMatrixDirty() {\n this._matrixDirty = true;\n this._aabbDirty = true;\n }\n\n _transformDirty() {\n this._matrixDirty = true;\n this._aabbDirty = true;\n this.scene._aabbDirty = true;\n }\n\n _sceneModelDirty() {\n this.scene._aabbDirty = true;\n this._aabbDirty = true;\n this.scene._aabbDirty = true;\n this._matrixDirty = true;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i]._sceneModelDirty(); // Entities need to retransform their World AABBs by SceneModel's worldMatrix\n }\n }\n\n /**\n * Gets the SceneModel's World matrix.\n *\n * @property worldMatrix\n * @type {Number[]}\n */\n get worldMatrix() {\n return this.matrix;\n }\n\n /**\n * Gets the SceneModel's World normal matrix.\n *\n * @type {Number[]}\n */\n get worldNormalMatrix() {\n return this._worldNormalMatrix;\n }\n\n /**\n * Called by private renderers in ./lib, returns the view matrix with which to\n * render this SceneModel. The view matrix is the concatenation of the\n * Camera view matrix with the Performance model's world (modeling) matrix.\n *\n * @private\n */\n get viewMatrix() {\n if (!this._viewMatrix) {\n return this.scene.camera.viewMatrix;\n }\n if (this._matrixDirty) {\n this._rebuildMatrices();\n this._viewMatrixDirty = true;\n }\n if (this._viewMatrixDirty) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulMat4(this.scene.camera.viewMatrix, this._matrix, this._viewMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transposeMat4(this._viewNormalMatrix);\n this._viewMatrixDirty = false;\n }\n return this._viewMatrix;\n }\n\n /**\n * Called by private renderers in ./lib, returns the view normal matrix with which to render this SceneModel.\n *\n * @private\n */\n get viewNormalMatrix() {\n if (!this._viewNormalMatrix) {\n return this.scene.camera.viewNormalMatrix;\n }\n if (this._matrixDirty) {\n this._rebuildMatrices();\n this._viewMatrixDirty = true;\n }\n if (this._viewMatrixDirty) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulMat4(this.scene.camera.viewMatrix, this._matrix, this._viewMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transposeMat4(this._viewNormalMatrix);\n this._viewMatrixDirty = false;\n }\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transposeMat4(this._viewNormalMatrix);\n return this._viewNormalMatrix;\n }\n\n /**\n * Sets if backfaces are rendered for this SceneModel.\n *\n * Default is ````false````.\n *\n * @type {Boolean}\n */\n get backfaces() {\n return this._backfaces;\n }\n\n /**\n * Sets if backfaces are rendered for this SceneModel.\n *\n * Default is ````false````.\n *\n * When we set this ````true````, then backfaces are always rendered for this SceneModel.\n *\n * When we set this ````false````, then we allow the Viewer to decide whether to render backfaces. In this case,\n * the Viewer will:\n *\n * * hide backfaces on watertight meshes,\n * * show backfaces on open meshes, and\n * * always show backfaces on meshes when we slice them open with {@link SectionPlane}s.\n *\n * @type {Boolean}\n */\n set backfaces(backfaces) {\n backfaces = !!backfaces;\n this._backfaces = backfaces;\n this.glRedraw();\n }\n\n /**\n * Gets the list of {@link SceneModelEntity}s within this SceneModel.\n *\n * @returns {SceneModelEntity[]}\n */\n get entityList() {\n return this._entityList;\n }\n\n /**\n * Returns true to indicate that SceneModel is an {@link Entity}.\n * @type {Boolean}\n */\n get isEntity() {\n return true;\n }\n\n /**\n * Returns ````true```` if this SceneModel represents a model.\n *\n * When ````true```` the SceneModel will be registered by {@link SceneModel#id} in\n * {@link Scene#models} and may also have a {@link MetaObject} with matching {@link MetaObject#id}.\n *\n * @type {Boolean}\n */\n get isModel() {\n return this._isModel;\n }\n\n //------------------------------------------------------------------------------------------------------------------\n // SceneModel members\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Returns ````false```` to indicate that SceneModel never represents an object.\n *\n * @type {Boolean}\n */\n get isObject() {\n return false;\n }\n\n /**\n * Gets the SceneModel's World-space 3D axis-aligned bounding box.\n *\n * Represented by a six-element Float64Array containing the min/max extents of the\n * axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n *\n * @type {Number[]}\n */\n get aabb() {\n if (this._aabbDirty) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3(this._aabb);\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3(this._aabb, this._entityList[i].aabb);\n }\n this._aabbDirty = false;\n }\n return this._aabb;\n }\n\n /**\n * The approximate number of triangle primitives in this SceneModel.\n *\n * @type {Number}\n */\n get numTriangles() {\n return this._numTriangles;\n }\n\n //------------------------------------------------------------------------------------------------------------------\n // Entity members\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * The approximate number of line primitives in this SceneModel.\n *\n * @type {Number}\n */\n get numLines() {\n return this._numLines;\n }\n\n /**\n * The approximate number of point primitives in this SceneModel.\n *\n * @type {Number}\n */\n get numPoints() {\n return this._numPoints;\n }\n\n /**\n * Gets if any {@link SceneModelEntity}s in this SceneModel are visible.\n *\n * The SceneModel is only rendered when {@link SceneModel#visible} is ````true```` and {@link SceneModel#culled} is ````false````.\n *\n * @type {Boolean}\n */\n get visible() {\n return (this.numVisibleLayerPortions > 0);\n }\n\n /**\n * Sets if this SceneModel is visible.\n *\n * The SceneModel is only rendered when {@link SceneModel#visible} is ````true```` and {@link SceneModel#culled} is ````false````.\n **\n * @type {Boolean}\n */\n set visible(visible) {\n visible = visible !== false;\n this._visible = visible;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].visible = visible;\n }\n this.glRedraw();\n }\n\n /**\n * Gets if any {@link SceneModelEntity}s in this SceneModel are xrayed.\n *\n * @type {Boolean}\n */\n get xrayed() {\n return (this.numXRayedLayerPortions > 0);\n }\n\n /**\n * Sets if all {@link SceneModelEntity}s in this SceneModel are xrayed.\n *\n * @type {Boolean}\n */\n set xrayed(xrayed) {\n xrayed = !!xrayed;\n this._xrayed = xrayed;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].xrayed = xrayed;\n }\n this.glRedraw();\n }\n\n /**\n * Gets if any {@link SceneModelEntity}s in this SceneModel are highlighted.\n *\n * @type {Boolean}\n */\n get highlighted() {\n return (this.numHighlightedLayerPortions > 0);\n }\n\n /**\n * Sets if all {@link SceneModelEntity}s in this SceneModel are highlighted.\n *\n * @type {Boolean}\n */\n set highlighted(highlighted) {\n highlighted = !!highlighted;\n this._highlighted = highlighted;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].highlighted = highlighted;\n }\n this.glRedraw();\n }\n\n /**\n * Gets if any {@link SceneModelEntity}s in this SceneModel are selected.\n *\n * @type {Boolean}\n */\n get selected() {\n return (this.numSelectedLayerPortions > 0);\n }\n\n /**\n * Sets if all {@link SceneModelEntity}s in this SceneModel are selected.\n *\n * @type {Boolean}\n */\n set selected(selected) {\n selected = !!selected;\n this._selected = selected;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].selected = selected;\n }\n this.glRedraw();\n }\n\n /**\n * Gets if any {@link SceneModelEntity}s in this SceneModel have edges emphasised.\n *\n * @type {Boolean}\n */\n get edges() {\n return (this.numEdgesLayerPortions > 0);\n }\n\n /**\n * Sets if all {@link SceneModelEntity}s in this SceneModel have edges emphasised.\n *\n * @type {Boolean}\n */\n set edges(edges) {\n edges = !!edges;\n this._edges = edges;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].edges = edges;\n }\n this.glRedraw();\n }\n\n /**\n * Gets if this SceneModel is culled from view.\n *\n * The SceneModel is only rendered when {@link SceneModel#visible} is true and {@link SceneModel#culled} is false.\n *\n * @type {Boolean}\n */\n get culled() {\n return this._culled;\n }\n\n /**\n * Sets if this SceneModel is culled from view.\n *\n * The SceneModel is only rendered when {@link SceneModel#visible} is true and {@link SceneModel#culled} is false.\n *\n * @type {Boolean}\n */\n set culled(culled) {\n culled = !!culled;\n this._culled = culled;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].culled = culled;\n }\n this.glRedraw();\n }\n\n /**\n * Gets if {@link SceneModelEntity}s in this SceneModel are clippable.\n *\n * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n *\n * @type {Boolean}\n */\n get clippable() {\n return this._clippable;\n }\n\n /**\n * Sets if {@link SceneModelEntity}s in this SceneModel are clippable.\n *\n * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n *\n * @type {Boolean}\n */\n set clippable(clippable) {\n clippable = clippable !== false;\n this._clippable = clippable;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].clippable = clippable;\n }\n this.glRedraw();\n }\n\n /**\n * Gets if this SceneModel is collidable.\n *\n * @type {Boolean}\n */\n get collidable() {\n return this._collidable;\n }\n\n /**\n * Sets if {@link SceneModelEntity}s in this SceneModel are collidable.\n *\n * @type {Boolean}\n */\n set collidable(collidable) {\n collidable = collidable !== false;\n this._collidable = collidable;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].collidable = collidable;\n }\n }\n\n /**\n * Gets if this SceneModel is pickable.\n *\n * Picking is done via calls to {@link Scene#pick}.\n *\n * @type {Boolean}\n */\n get pickable() {\n return (this.numPickableLayerPortions > 0);\n }\n\n /**\n * Sets if {@link SceneModelEntity}s in this SceneModel are pickable.\n *\n * Picking is done via calls to {@link Scene#pick}.\n *\n * @type {Boolean}\n */\n set pickable(pickable) {\n pickable = pickable !== false;\n this._pickable = pickable;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].pickable = pickable;\n }\n }\n\n /**\n * Gets the RGB colorize color for this SceneModel.\n *\n * Each element of the color is in range ````[0..1]````.\n *\n * @type {Number[]}\n */\n get colorize() {\n return this._colorize;\n }\n\n /**\n * Sets the RGB colorize color for this SceneModel.\n *\n * Multiplies by rendered fragment colors.\n *\n * Each element of the color is in range ````[0..1]````.\n *\n * @type {Number[]}\n */\n set colorize(colorize) {\n this._colorize = colorize;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].colorize = colorize;\n }\n }\n\n /**\n * Gets this SceneModel's opacity factor.\n *\n * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n *\n * @type {Number}\n */\n get opacity() {\n return this._opacity;\n }\n\n /**\n * Sets the opacity factor for this SceneModel.\n *\n * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n *\n * @type {Number}\n */\n set opacity(opacity) {\n this._opacity = opacity;\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i].opacity = opacity;\n }\n }\n\n /**\n * Gets if this SceneModel casts a shadow.\n *\n * @type {Boolean}\n */\n get castsShadow() {\n return this._castsShadow;\n }\n\n /**\n * Sets if this SceneModel casts a shadow.\n *\n * @type {Boolean}\n */\n set castsShadow(castsShadow) {\n castsShadow = (castsShadow !== false);\n if (castsShadow !== this._castsShadow) {\n this._castsShadow = castsShadow;\n this.glRedraw();\n }\n }\n\n /**\n * Sets if this SceneModel can have shadow cast upon it.\n *\n * @type {Boolean}\n */\n get receivesShadow() {\n return this._receivesShadow;\n }\n\n /**\n * Sets if this SceneModel can have shadow cast upon it.\n *\n * @type {Boolean}\n */\n set receivesShadow(receivesShadow) {\n receivesShadow = (receivesShadow !== false);\n if (receivesShadow !== this._receivesShadow) {\n this._receivesShadow = receivesShadow;\n this.glRedraw();\n }\n }\n\n /**\n * Gets if Scalable Ambient Obscurance (SAO) will apply to this SceneModel.\n *\n * SAO is configured by the Scene's {@link SAO} component.\n *\n * Only works when {@link SAO#enabled} is also true.\n *\n * @type {Boolean}\n */\n get saoEnabled() {\n return this._saoEnabled;\n }\n\n /**\n * Gets if physically-based rendering (PBR) is enabled for this SceneModel.\n *\n * Only works when {@link Scene#pbrEnabled} is also true.\n *\n * @type {Boolean}\n */\n get pbrEnabled() {\n return this._pbrEnabled;\n }\n\n /**\n * Gets if color textures are enabled for this SceneModel.\n *\n * Only works when {@link Scene#colorTextureEnabled} is also true.\n *\n * @type {Boolean}\n */\n get colorTextureEnabled() {\n return this._colorTextureEnabled;\n }\n\n /**\n * Returns true to indicate that SceneModel is implements {@link Drawable}.\n *\n * @type {Boolean}\n */\n get isDrawable() {\n return true;\n }\n\n /** @private */\n get isStateSortable() {\n return false\n }\n\n /**\n * Configures the appearance of xrayed {@link SceneModelEntity}s within this SceneModel.\n *\n * This is the {@link Scene#xrayMaterial}.\n *\n * @type {EmphasisMaterial}\n */\n get xrayMaterial() {\n return this.scene.xrayMaterial;\n }\n\n /**\n * Configures the appearance of highlighted {@link SceneModelEntity}s within this SceneModel.\n *\n * This is the {@link Scene#highlightMaterial}.\n *\n * @type {EmphasisMaterial}\n */\n get highlightMaterial() {\n return this.scene.highlightMaterial;\n }\n\n /**\n * Configures the appearance of selected {@link SceneModelEntity}s within this SceneModel.\n *\n * This is the {@link Scene#selectedMaterial}.\n *\n * @type {EmphasisMaterial}\n */\n get selectedMaterial() {\n return this.scene.selectedMaterial;\n }\n\n /**\n * Configures the appearance of edges of {@link SceneModelEntity}s within this SceneModel.\n *\n * This is the {@link Scene#edgeMaterial}.\n *\n * @type {EdgeMaterial}\n */\n get edgeMaterial() {\n return this.scene.edgeMaterial;\n }\n\n //------------------------------------------------------------------------------------------------------------------\n // Drawable members\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Called by private renderers in ./lib, returns the picking view matrix with which to\n * ray-pick on this SceneModel.\n *\n * @private\n */\n getPickViewMatrix(pickViewMatrix) {\n if (!this._viewMatrix) {\n return pickViewMatrix;\n }\n return this._viewMatrix;\n }\n\n /**\n *\n * @param cfg\n */\n createQuantizationRange(cfg) {\n if (cfg.id === undefined || cfg.id === null) {\n this.error(\"[createQuantizationRange] Config missing: id\");\n return;\n }\n if (cfg.aabb) {\n this.error(\"[createQuantizationRange] Config missing: aabb\");\n return;\n }\n if (this._quantizationRanges[cfg.id]) {\n this.error(\"[createQuantizationRange] QuantizationRange already created: \" + cfg.id);\n return;\n }\n this._quantizationRanges[cfg.id] = {\n id: cfg.id,\n aabb: cfg.aabb,\n matrix: (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.createPositionsDecodeMatrix)(cfg.aabb, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4())\n }\n }\n\n /**\n * Creates a reusable geometry within this SceneModel.\n *\n * We can then supply the geometry ID to {@link SceneModel#createMesh} when we want to create meshes that\n * instance the geometry.\n *\n * @param {*} cfg Geometry properties.\n * @param {String|Number} cfg.id Mandatory ID for the geometry, to refer to with {@link SceneModel#createMesh}.\n * @param {String} cfg.primitive The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'.\n * @param {Number[]} [cfg.positions] Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by ````positionsCompressed````.\n * @param {Number[]} [cfg.positionsCompressed] Flat array of quantized 3D vertex positions. Overrides ````positions````, and must be accompanied by ````positionsDecodeMatrix````.\n * @param {Number[]} [cfg.positionsDecodeMatrix] A 4x4 matrix for decompressing ````positionsCompressed````. Must be accompanied by ````positionsCompressed````.\n * @param {Number[]} [cfg.normals] Flat array of normal vectors. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n * @param {Number[]} [cfg.normalsCompressed] Flat array of oct-encoded normal vectors. Overrides ````normals````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n * @param {Number[]} [cfg.colors] Flat array of uncompressed RGBA vertex colors, as float values in range ````[0..1]````. Ignored when ````geometryId```` is given. Overridden by ````color```` and ````colorsCompressed````.\n * @param {Number[]} [cfg.colorsCompressed] Flat array of compressed RGBA vertex colors, as unsigned short integers in range ````[0..255]````. Ignored when ````geometryId```` is given. Overrides ````colors```` and is overridden by ````color````.\n * @param {Number[]} [cfg.uv] Flat array of uncompressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n * @param {Number[]} [cfg.uvCompressed] Flat array of compressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Overrides ````uv````. Must be accompanied by ````uvDecodeMatrix````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n * @param {Number[]} [cfg.uvDecodeMatrix] A 3x3 matrix for decompressing ````uvCompressed````.\n * @param {Number[]} [cfg.indices] Array of primitive connectivity indices. Not required for `points` primitives.\n * @param {Number[]} [cfg.edgeIndices] Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional ````edgeThreshold```` given to the ````SceneModel```` constructor.\n */\n createGeometry(cfg) {\n if (cfg.id === undefined || cfg.id === null) {\n this.error(\"[createGeometry] Config missing: id\");\n return;\n }\n if (this._geometries[cfg.id]) {\n this.error(\"[createGeometry] Geometry already created: \" + cfg.id);\n return;\n }\n if (cfg.primitive === undefined || cfg.primitive === null) {\n cfg.primitive = \"triangles\";\n }\n if (cfg.primitive !== \"points\" && cfg.primitive !== \"lines\" && cfg.primitive !== \"triangles\" && cfg.primitive !== \"solid\" && cfg.primitive !== \"surface\") {\n this.error(`[createGeometry] Unsupported value for 'primitive': '${cfg.primitive}' - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'. Defaulting to 'triangles'.`);\n return;\n }\n if (!cfg.positions && !cfg.positionsCompressed && !cfg.buckets) {\n this.error(\"[createGeometry] Param expected: `positions`, `positionsCompressed' or 'buckets\");\n return null;\n }\n if (cfg.positionsCompressed && !cfg.positionsDecodeMatrix && !cfg.positionsDecodeBoundary) {\n this.error(\"[createGeometry] Param expected: `positionsDecodeMatrix` or 'positionsDecodeBoundary' (required for `positionsCompressed')\");\n return null;\n }\n if (cfg.positionsDecodeMatrix && cfg.positionsDecodeBoundary) {\n this.error(\"[createGeometry] Only one of these params expected: `positionsDecodeMatrix` or 'positionsDecodeBoundary' (required for `positionsCompressed')\");\n return null;\n }\n if (cfg.uvCompressed && !cfg.uvDecodeMatrix) {\n this.error(\"[createGeometry] Param expected: `uvDecodeMatrix` (required for `uvCompressed')\");\n return null;\n }\n if (!cfg.buckets && !cfg.indices && cfg.primitive !== \"points\") {\n this.error(`[createGeometry] Param expected: indices (required for '${cfg.primitive}' primitive type)`);\n return null;\n }\n if (cfg.positionsDecodeBoundary) {\n cfg.positionsDecodeMatrix = (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.createPositionsDecodeMatrix)(cfg.positionsDecodeBoundary, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4());\n }\n if (cfg.positions) {\n const aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n cfg.positionsDecodeMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positions);\n cfg.positionsCompressed = (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.quantizePositions)(cfg.positions, aabb, cfg.positionsDecodeMatrix);\n cfg.aabb = aabb;\n } else if (cfg.positionsCompressed) {\n const aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n cfg.positionsDecodeMatrix = new Float64Array(cfg.positionsDecodeMatrix);\n cfg.positionsCompressed = new Uint16Array(cfg.positionsCompressed);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positionsCompressed);\n _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n cfg.aabb = aabb;\n } else if (cfg.buckets) {\n const aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n this._dtxBuckets[cfg.id] = cfg.buckets;\n for (let i = 0, len = cfg.buckets.length; i < len; i++) {\n const bucket = cfg.buckets[i];\n if (bucket.positions) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, bucket.positions);\n } else if (bucket.positionsCompressed) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, bucket.positionsCompressed);\n }\n }\n if (cfg.positionsDecodeMatrix) {\n _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n }\n cfg.aabb = aabb;\n }\n if (cfg.colorsCompressed && cfg.colorsCompressed.length > 0) {\n cfg.colorsCompressed = new Uint8Array(cfg.colorsCompressed);\n } else if (cfg.colors && cfg.colors.length > 0) {\n const colors = cfg.colors;\n const colorsCompressed = new Uint8Array(colors.length);\n for (let i = 0, len = colors.length; i < len; i++) {\n colorsCompressed[i] = colors[i] * 255;\n }\n cfg.colorsCompressed = colorsCompressed;\n }\n if (!cfg.buckets && !cfg.edgeIndices && (cfg.primitive === \"triangles\" || cfg.primitive === \"solid\" || cfg.primitive === \"surface\")) {\n if (cfg.positions) {\n cfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positions, cfg.indices, null, 5.0);\n } else {\n cfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);\n }\n }\n if (cfg.uv) {\n const bounds = _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.getUVBounds(cfg.uv);\n const result = _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.compressUVs(cfg.uv, bounds.min, bounds.max);\n cfg.uvCompressed = result.quantized;\n cfg.uvDecodeMatrix = result.decodeMatrix;\n } else if (cfg.uvCompressed) {\n cfg.uvCompressed = new Uint16Array(cfg.uvCompressed);\n cfg.uvDecodeMatrix = new Float64Array(cfg.uvDecodeMatrix);\n }\n if (cfg.normals) { // HACK\n cfg.normals = null;\n }\n this._geometries [cfg.id] = cfg;\n this._numTriangles += (cfg.indices ? Math.round(cfg.indices.length / 3) : 0);\n this.numGeometries++;\n }\n\n /**\n * Creates a texture within this SceneModel.\n *\n * We can then supply the texture ID to {@link SceneModel#createTextureSet} when we want to create texture sets that use the texture.\n *\n * @param {*} cfg Texture properties.\n * @param {String|Number} cfg.id Mandatory ID for the texture, to refer to with {@link SceneModel#createTextureSet}.\n * @param {String} [cfg.src] Image file for the texture. Assumed to be transcoded if not having a recognized image file\n * extension (jpg, jpeg, png etc.). If transcoded, then assumes ````SceneModel```` is configured with a {@link TextureTranscoder}.\n * @param {ArrayBuffer[]} [cfg.buffers] Transcoded texture data. Assumes ````SceneModel```` is\n * configured with a {@link TextureTranscoder}. This parameter is given as an array of buffers so we can potentially support multi-image textures, such as cube maps.\n * @param {HTMLImageElement} [cfg.image] HTML Image object to load into this texture. Overrides ````src```` and ````buffers````. Never transcoded.\n * @param {Number} [cfg.minFilter=LinearMipmapLinearFilter] How the texture is sampled when a texel covers less than one pixel.\n * Supported values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}.\n * @param {Number} [cfg.magFilter=LinearFilter] How the texture is sampled when a texel covers more than one pixel. Supported values are {@link LinearFilter} and {@link NearestFilter}.\n * @param {Number} [cfg.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n * @param {Number} [cfg.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}..\n * @param {Number} [cfg.wrapR=RepeatWrapping] Wrap parameter for texture coordinate *R*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n * @param {Boolean} [cfg.flipY=false] Flips this Texture's source data along its vertical axis when ````true````.\n * @param {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.\n */\n createTexture(cfg) {\n const textureId = cfg.id;\n if (textureId === undefined || textureId === null) {\n this.error(\"[createTexture] Config missing: id\");\n return;\n }\n if (this._textures[textureId]) {\n this.error(\"[createTexture] Texture already created: \" + textureId);\n return;\n }\n if (!cfg.src && !cfg.image && !cfg.buffers) {\n this.error(\"[createTexture] Param expected: `src`, `image' or 'buffers'\");\n return null;\n }\n let minFilter = cfg.minFilter || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipmapLinearFilter;\n if (minFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearFilter &&\n minFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipMapNearestFilter &&\n minFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipmapLinearFilter &&\n minFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestMipMapLinearFilter &&\n minFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestMipMapNearestFilter) {\n this.error(`[createTexture] Unsupported value for 'minFilter' - \n supported values are LinearFilter, LinearMipMapNearestFilter, NearestMipMapNearestFilter, \n NearestMipMapLinearFilter and LinearMipmapLinearFilter. Defaulting to LinearMipmapLinearFilter.`);\n minFilter = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipmapLinearFilter;\n }\n let magFilter = cfg.magFilter || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearFilter;\n if (magFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearFilter && magFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestFilter) {\n this.error(`[createTexture] Unsupported value for 'magFilter' - supported values are LinearFilter and NearestFilter. Defaulting to LinearFilter.`);\n magFilter = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearFilter;\n }\n let wrapS = cfg.wrapS || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n if (wrapS !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.ClampToEdgeWrapping && wrapS !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.MirroredRepeatWrapping && wrapS !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping) {\n this.error(`[createTexture] Unsupported value for 'wrapS' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`);\n wrapS = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n }\n let wrapT = cfg.wrapT || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n if (wrapT !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.ClampToEdgeWrapping && wrapT !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.MirroredRepeatWrapping && wrapT !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping) {\n this.error(`[createTexture] Unsupported value for 'wrapT' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`);\n wrapT = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n }\n let wrapR = cfg.wrapR || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n if (wrapR !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.ClampToEdgeWrapping && wrapR !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.MirroredRepeatWrapping && wrapR !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping) {\n this.error(`[createTexture] Unsupported value for 'wrapR' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`);\n wrapR = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n }\n let encoding = cfg.encoding || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearEncoding;\n if (encoding !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearEncoding && encoding !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.sRGBEncoding) {\n this.error(\"[createTexture] Unsupported value for 'encoding' - supported values are LinearEncoding and sRGBEncoding. Defaulting to LinearEncoding.\");\n encoding = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearEncoding;\n }\n const texture = new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n gl: this.scene.canvas.gl,\n minFilter,\n magFilter,\n wrapS,\n wrapT,\n wrapR,\n // flipY: cfg.flipY,\n encoding\n });\n if (cfg.preloadColor) {\n texture.setPreloadColor(cfg.preloadColor);\n }\n if (cfg.image) { // Ignore transcoder for Images\n const image = cfg.image;\n image.crossOrigin = \"Anonymous\";\n texture.setImage(image, {minFilter, magFilter, wrapS, wrapT, wrapR, flipY: cfg.flipY, encoding});\n } else if (cfg.src) {\n const ext = cfg.src.split('.').pop();\n switch (ext) { // Don't transcode recognized image file types\n case \"jpeg\":\n case \"jpg\":\n case \"png\":\n case \"gif\":\n const image = new Image();\n image.onload = () => {\n texture.setImage(image, {\n minFilter,\n magFilter,\n wrapS,\n wrapT,\n wrapR,\n flipY: cfg.flipY,\n encoding\n });\n this.glRedraw();\n };\n image.src = cfg.src; // URL or Base64 string\n break;\n default: // Assume other file types need transcoding\n if (!this._textureTranscoder) {\n this.error(`[createTexture] Can't create texture from 'src' - SceneModel needs to be configured with a TextureTranscoder for this file type ('${ext}')`);\n } else {\n _utils_js__WEBPACK_IMPORTED_MODULE_19__.utils.loadArraybuffer(cfg.src, (arrayBuffer) => {\n if (!arrayBuffer.byteLength) {\n this.error(`[createTexture] Can't create texture from 'src': file data is zero length`);\n return;\n }\n this._textureTranscoder.transcode([arrayBuffer], texture).then(() => {\n this.glRedraw();\n });\n },\n function (errMsg) {\n this.error(`[createTexture] Can't create texture from 'src': ${errMsg}`);\n });\n }\n break;\n }\n } else if (cfg.buffers) { // Buffers implicitly require transcoding\n if (!this._textureTranscoder) {\n this.error(`[createTexture] Can't create texture from 'buffers' - SceneModel needs to be configured with a TextureTranscoder for this option`);\n } else {\n this._textureTranscoder.transcode(cfg.buffers, texture).then(() => {\n this.glRedraw();\n });\n }\n }\n this._textures[textureId] = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({id: textureId, texture});\n }\n\n /**\n * Creates a texture set within this SceneModel.\n *\n * * Stores the new {@link SceneModelTextureSet} in {@link SceneModel#textureSets}.\n *\n * A texture set is a collection of textures that can be shared among meshes. We can then supply the texture set\n * ID to {@link SceneModel#createMesh} when we want to create meshes that use the texture set.\n *\n * The textures can work as a texture atlas, where each mesh can have geometry UVs that index\n * a different part of the textures. This allows us to minimize the number of textures in our models, which\n * means faster rendering.\n *\n * @param {*} cfg Texture set properties.\n * @param {String|Number} cfg.id Mandatory ID for the texture set, to refer to with {@link SceneModel#createMesh}.\n * @param {*} [cfg.colorTextureId] ID of *RGBA* base color texture, with color in *RGB* and alpha in *A*.\n * @param {*} [cfg.metallicRoughnessTextureId] ID of *RGBA* metal-roughness texture, with the metallic factor in *R*, and roughness factor in *G*.\n * @param {*} [cfg.normalsTextureId] ID of *RGBA* normal map texture, with normal map vectors in *RGB*.\n * @param {*} [cfg.emissiveTextureId] ID of *RGBA* emissive map texture, with emissive color in *RGB*.\n * @param {*} [cfg.occlusionTextureId] ID of *RGBA* occlusion map texture, with occlusion factor in *R*.\n * @returns {SceneModelTransform} The new texture set.\n */\n createTextureSet(cfg) {\n const textureSetId = cfg.id;\n if (textureSetId === undefined || textureSetId === null) {\n this.error(\"[createTextureSet] Config missing: id\");\n return;\n }\n if (this._textureSets[textureSetId]) {\n this.error(`[createTextureSet] Texture set already created: ${textureSetId}`);\n return;\n }\n let colorTexture;\n if (cfg.colorTextureId !== undefined && cfg.colorTextureId !== null) {\n colorTexture = this._textures[cfg.colorTextureId];\n if (!colorTexture) {\n this.error(`[createTextureSet] Texture not found: ${cfg.colorTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n } else {\n colorTexture = this._textures[DEFAULT_COLOR_TEXTURE_ID];\n }\n let metallicRoughnessTexture;\n if (cfg.metallicRoughnessTextureId !== undefined && cfg.metallicRoughnessTextureId !== null) {\n metallicRoughnessTexture = this._textures[cfg.metallicRoughnessTextureId];\n if (!metallicRoughnessTexture) {\n this.error(`[createTextureSet] Texture not found: ${cfg.metallicRoughnessTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n } else {\n metallicRoughnessTexture = this._textures[DEFAULT_METAL_ROUGH_TEXTURE_ID];\n }\n let normalsTexture;\n if (cfg.normalsTextureId !== undefined && cfg.normalsTextureId !== null) {\n normalsTexture = this._textures[cfg.normalsTextureId];\n if (!normalsTexture) {\n this.error(`[createTextureSet] Texture not found: ${cfg.normalsTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n } else {\n normalsTexture = this._textures[DEFAULT_NORMALS_TEXTURE_ID];\n }\n let emissiveTexture;\n if (cfg.emissiveTextureId !== undefined && cfg.emissiveTextureId !== null) {\n emissiveTexture = this._textures[cfg.emissiveTextureId];\n if (!emissiveTexture) {\n this.error(`[createTextureSet] Texture not found: ${cfg.emissiveTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n } else {\n emissiveTexture = this._textures[DEFAULT_EMISSIVE_TEXTURE_ID];\n }\n let occlusionTexture;\n if (cfg.occlusionTextureId !== undefined && cfg.occlusionTextureId !== null) {\n occlusionTexture = this._textures[cfg.occlusionTextureId];\n if (!occlusionTexture) {\n this.error(`[createTextureSet] Texture not found: ${cfg.occlusionTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n } else {\n occlusionTexture = this._textures[DEFAULT_OCCLUSION_TEXTURE_ID];\n }\n const textureSet = new _SceneModelTextureSet_js__WEBPACK_IMPORTED_MODULE_16__.SceneModelTextureSet({\n id: textureSetId,\n model: this,\n colorTexture,\n metallicRoughnessTexture,\n normalsTexture,\n emissiveTexture,\n occlusionTexture\n });\n this._textureSets[textureSetId] = textureSet;\n return textureSet;\n }\n\n /**\n * Creates a new {@link SceneModelTransform} within this SceneModel.\n *\n * * Stores the new {@link SceneModelTransform} in {@link SceneModel#transforms}.\n * * Can be connected into hierarchies\n * * Each {@link SceneModelTransform} can be used by unlimited {@link SceneModelMesh}es\n *\n * @param {*} cfg Transform creation parameters.\n * @param {String} cfg.id Mandatory ID for the new transform. Must not clash with any existing components within the {@link Scene}.\n * @param {String} [cfg.parentTransformId] ID of a parent transform, previously created with {@link SceneModel#createTextureSet}.\n * @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.\n * @param {Number[]} [cfg.scale=[1,1,1]] Scale of the transform.\n * @param {Number[]} [cfg.rotation=[0,0,0]] Rotation of the transform as Euler angles given in degrees, for each of the X, Y and Z axis.\n * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Modelling transform matrix. Overrides the ````position````, ````scale```` and ````rotation```` parameters.\n * @returns {SceneModelTransform} The new transform.\n */\n createTransform(cfg) {\n if (cfg.id === undefined || cfg.id === null) {\n this.error(\"[createTransform] SceneModel.createTransform() config missing: id\");\n return;\n }\n if (this._transforms[cfg.id]) {\n this.error(`[createTransform] SceneModel already has a transform with this ID: ${cfg.id}`);\n return;\n }\n let parentTransform;\n if (this.parentTransformId) {\n parentTransform = this._transforms[cfg.parentTransformId];\n if (!parentTransform) {\n this.error(\"[createTransform] SceneModel.createTransform() config missing: id\");\n return;\n }\n }\n const transform = new _SceneModelTransform_js__WEBPACK_IMPORTED_MODULE_27__.SceneModelTransform({\n id: cfg.id,\n model: this,\n parentTransform,\n matrix: cfg.matrix,\n position: cfg.position,\n scale: cfg.scale,\n rotation: cfg.rotation,\n quaternion: cfg.quaternion\n });\n this._transforms[transform.id] = transform;\n return transform;\n }\n\n /**\n * Creates a new {@link SceneModelMesh} within this SceneModel.\n *\n * * It prepares and saves data for a SceneModelMesh {@link SceneModel#meshes} creation. SceneModelMesh will be created only once the SceneModelEntity (which references this particular SceneModelMesh) will be created.\n * * The SceneModelMesh can either define its own geometry or share it with other SceneModelMeshes. To define own geometry, provide the\n * various geometry arrays to this method. To share a geometry, provide the ID of a geometry created earlier\n * with {@link SceneModel#createGeometry}.\n * * If you accompany the arrays with an ````origin````, then ````createMesh()```` will assume\n * that the geometry ````positions```` are in relative-to-center (RTC) coordinates, with ````origin```` being the\n * origin of their RTC coordinate system.\n *\n * @param {object} cfg Object properties.\n * @param {String} cfg.id Mandatory ID for the new mesh. Must not clash with any existing components within the {@link Scene}.\n * @param {String|Number} [cfg.textureSetId] ID of a {@link SceneModelTextureSet} previously created with {@link SceneModel#createTextureSet}.\n * @param {String|Number} [cfg.transformId] ID of a {@link SceneModelTransform} to instance, previously created with {@link SceneModel#createTransform}. Overrides all other transform parameters given to this method.\n * @param {String|Number} [cfg.geometryId] ID of a geometry to instance, previously created with {@link SceneModel#createGeometry}. Overrides all other geometry parameters given to this method.\n * @param {String} cfg.primitive The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'.\n * @param {Number[]} [cfg.positions] Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by ````positionsCompressed````.\n * @param {Number[]} [cfg.positionsCompressed] Flat array of quantized 3D vertex positions. Overrides ````positions````, and must be accompanied by ````positionsDecodeMatrix````.\n * @param {Number[]} [cfg.positionsDecodeMatrix] A 4x4 matrix for decompressing ````positionsCompressed````. Must be accompanied by ````positionsCompressed````.\n * @param {Number[]} [cfg.normals] Flat array of normal vectors. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n * @param {Number[]} [cfg.normalsCompressed] Flat array of oct-encoded normal vectors. Overrides ````normals````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n * @param {Number[]} [cfg.colors] Flat array of uncompressed RGBA vertex colors, as float values in range ````[0..1]````. Ignored when ````geometryId```` is given. Overridden by ````color```` and ````colorsCompressed````.\n * @param {Number[]} [cfg.colorsCompressed] Flat array of compressed RGBA vertex colors, as unsigned short integers in range ````[0..255]````. Ignored when ````geometryId```` is given. Overrides ````colors```` and is overridden by ````color````.\n * @param {Number[]} [cfg.uv] Flat array of uncompressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n * @param {Number[]} [cfg.uvCompressed] Flat array of compressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Overrides ````uv````. Must be accompanied by ````uvDecodeMatrix````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n * @param {Number[]} [cfg.uvDecodeMatrix] A 3x3 matrix for decompressing ````uvCompressed````.\n * @param {Number[]} [cfg.indices] Array of primitive connectivity indices. Not required for `points` primitives.\n * @param {Number[]} [cfg.edgeIndices] Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional ````edgeThreshold```` given to the ````SceneModel```` constructor.\n * @param {Number[]} [cfg.origin] Optional geometry origin, relative to {@link SceneModel#origin}. When this is given, then ````positions```` are assumed to be relative to this.\n * @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.\n * @param {Number[]} [cfg.scale=[1,1,1]] Scale of the mesh. Overridden by ````transformId````.\n * @param {Number[]} [cfg.rotation=[0,0,0]] Rotation of the mesh as Euler angles given in degrees, for each of the X, Y and Z axis. Overridden by ````transformId````.\n * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Mesh modelling transform matrix. Overrides the ````position````, ````scale```` and ````rotation```` parameters. Also overridden by ````transformId````.\n * @param {Number[]} [cfg.color=[1,1,1]] RGB color in range ````[0..1, 0..1, 0..1]````. Overridden by texture set ````colorTexture````. Overrides ````colors```` and ````colorsCompressed````.\n * @param {Number} [cfg.opacity=1] Opacity in range ````[0..1]````. Overridden by texture set ````colorTexture````.\n * @param {Number} [cfg.metallic=0] Metallic factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.\n * @param {Number} [cfg.roughness=1] Roughness factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.\n * @returns {Boolean} True = successfully mesh was created. False = error during creation of a mesh.\n */\n createMesh(cfg) {\n\n if (cfg.id === undefined || cfg.id === null) {\n this.error(\"[createMesh] SceneModel.createMesh() config missing: id\");\n return false;\n }\n\n if (this._scheduledMeshes[cfg.id]) {\n this.error(`[createMesh] SceneModel already has a mesh with this ID: ${cfg.id}`);\n return false;\n }\n\n const instancing = (cfg.geometryId !== undefined);\n const batching = !instancing;\n\n if (batching) {\n\n // Batched geometry\n\n if (cfg.primitive === undefined || cfg.primitive === null) {\n cfg.primitive = \"triangles\";\n }\n if (cfg.primitive !== \"points\" && cfg.primitive !== \"lines\" && cfg.primitive !== \"triangles\" && cfg.primitive !== \"solid\" && cfg.primitive !== \"surface\") {\n this.error(`Unsupported value for 'primitive': '${primitive}' ('geometryId' is absent) - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'.`);\n return false;\n }\n if (!cfg.positions && !cfg.positionsCompressed && !cfg.buckets) {\n this.error(\"Param expected: 'positions', 'positionsCompressed' or `buckets` ('geometryId' is absent)\");\n return false;\n }\n if (cfg.positions && (cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary)) {\n this.error(\"Illegal params: 'positions' not expected with 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)\");\n return false;\n }\n if (cfg.positionsCompressed && !cfg.positionsDecodeMatrix && !cfg.positionsDecodeBoundary) {\n this.error(\"Param expected: 'positionsCompressed' should be accompanied by 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)\");\n return false;\n }\n if (cfg.uvCompressed && !cfg.uvDecodeMatrix) {\n this.error(\"Param expected: 'uvCompressed' should be accompanied by `uvDecodeMatrix` ('geometryId' is absent)\");\n return false;\n }\n if (!cfg.buckets && !cfg.indices && cfg.primitive !== \"points\") {\n this.error(`Param expected: indices (required for '${cfg.primitive}' primitive type)`);\n return false;\n }\n if ((cfg.matrix || cfg.position || cfg.rotation || cfg.scale) && (cfg.positionsCompressed || cfg.positionsDecodeBoundary)) {\n this.error(\"Unexpected params: 'matrix', 'rotation', 'scale', 'position' not allowed with 'positionsCompressed'\");\n return false;\n }\n\n const useDTX = (!!this._dtxEnabled && (cfg.primitive === \"triangles\"\n || cfg.primitive === \"solid\"\n || cfg.primitive === \"surface\"));\n\n cfg.origin = cfg.origin ? _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(this._origin, cfg.origin, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3()) : this._origin;\n\n // MATRIX - optional for batching\n\n if (cfg.matrix) {\n cfg.meshMatrix = cfg.matrix;\n } else if (cfg.scale || cfg.rotation || cfg.position) {\n const scale = cfg.scale || DEFAULT_SCALE;\n const position = cfg.position || DEFAULT_POSITION;\n const rotation = cfg.rotation || DEFAULT_ROTATION;\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.eulerToQuaternion(rotation, \"XYZ\", DEFAULT_QUATERNION);\n cfg.meshMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.composeMat4(position, DEFAULT_QUATERNION, scale, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4());\n }\n\n if (cfg.positionsDecodeBoundary) {\n cfg.positionsDecodeMatrix = (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.createPositionsDecodeMatrix)(cfg.positionsDecodeBoundary, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4());\n }\n\n if (useDTX) {\n\n // DTX\n\n cfg.type = DTX;\n\n // NPR\n\n cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : defaultCompressedColor;\n cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;\n\n // RTC\n\n if (cfg.positions) {\n const rtcCenter = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n const rtcPositions = [];\n const rtcNeeded = (0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_15__.worldToRTCPositions)(cfg.positions, rtcPositions, rtcCenter);\n if (rtcNeeded) {\n cfg.positions = rtcPositions;\n cfg.origin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(cfg.origin, rtcCenter, rtcCenter);\n }\n }\n\n // COMPRESSION\n\n if (cfg.positions) {\n const aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n cfg.positionsDecodeMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positions);\n cfg.positionsCompressed = (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.quantizePositions)(cfg.positions, aabb, cfg.positionsDecodeMatrix);\n cfg.aabb = aabb;\n\n } else if (cfg.positionsCompressed) {\n const aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positionsCompressed);\n _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n cfg.aabb = aabb;\n\n }\n if (cfg.buckets) {\n const aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n for (let i = 0, len = cfg.buckets.length; i < len; i++) {\n const bucket = cfg.buckets[i];\n if (bucket.positions) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, bucket.positions);\n } else if (bucket.positionsCompressed) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, bucket.positionsCompressed);\n }\n }\n if (cfg.positionsDecodeMatrix) {\n _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n }\n cfg.aabb = aabb;\n }\n\n if (cfg.meshMatrix) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(cfg.aabb, tempOBB3);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformOBB3(cfg.meshMatrix, tempOBB3);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3ToAABB3(tempOBB3, cfg.aabb);\n }\n\n // EDGES\n\n if (!cfg.buckets && !cfg.edgeIndices && (cfg.primitive === \"triangles\" || cfg.primitive === \"solid\" || cfg.primitive === \"surface\")) {\n if (cfg.positions) { // Faster\n cfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positions, cfg.indices, null, 2.0);\n } else {\n cfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);\n }\n }\n\n // BUCKETING\n\n if (!cfg.buckets) {\n cfg.buckets = createDTXBuckets(cfg, this._enableVertexWelding && this._enableIndexBucketing);\n }\n\n } else {\n\n // VBO\n\n cfg.type = VBO_BATCHED;\n\n // PBR\n\n cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : [255, 255, 255];\n cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;\n cfg.metallic = (cfg.metallic !== undefined && cfg.metallic !== null) ? Math.floor(cfg.metallic * 255) : 0;\n cfg.roughness = (cfg.roughness !== undefined && cfg.roughness !== null) ? Math.floor(cfg.roughness * 255) : 255;\n\n // RTC\n\n if (cfg.positions) {\n const rtcPositions = [];\n const rtcNeeded = (0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_15__.worldToRTCPositions)(cfg.positions, rtcPositions, tempVec3a);\n if (rtcNeeded) {\n cfg.positions = rtcPositions;\n cfg.origin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(cfg.origin, tempVec3a, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3());\n }\n }\n\n if (cfg.positions) {\n const aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n if (cfg.meshMatrix) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformPositions3(cfg.meshMatrix, cfg.positions, cfg.positions);\n cfg.meshMatrix = null; // Positions now baked, don't need any more\n }\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positions);\n cfg.aabb = aabb;\n\n } else {\n const aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positionsCompressed);\n _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n cfg.aabb = aabb;\n }\n\n if (cfg.meshMatrix) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(cfg.aabb, tempOBB3);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformOBB3(cfg.meshMatrix, tempOBB3);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3ToAABB3(tempOBB3, cfg.aabb);\n }\n\n // EDGES\n\n if (!cfg.buckets && !cfg.edgeIndices && (cfg.primitive === \"triangles\" || cfg.primitive === \"solid\" || cfg.primitive === \"surface\")) {\n if (cfg.positions) {\n cfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positions, cfg.indices, null, 2.0);\n } else {\n cfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);\n }\n }\n\n // TEXTURE\n\n // cfg.textureSetId = cfg.textureSetId || DEFAULT_TEXTURE_SET_ID;\n if (cfg.textureSetId) {\n cfg.textureSet = this._textureSets[cfg.textureSetId];\n if (!cfg.textureSet) {\n this.error(`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`);\n return false;\n }\n }\n }\n\n } else {\n\n // INSTANCING\n\n if (cfg.positions || cfg.positionsCompressed || cfg.indices || cfg.edgeIndices || cfg.normals || cfg.normalsCompressed || cfg.uv || cfg.uvCompressed || cfg.positionsDecodeMatrix) {\n this.error(`Mesh geometry parameters not expected when instancing a geometry (not expected: positions, positionsCompressed, indices, edgeIndices, normals, normalsCompressed, uv, uvCompressed, positionsDecodeMatrix)`);\n return false;\n }\n\n cfg.geometry = this._geometries[cfg.geometryId];\n if (!cfg.geometry) {\n this.error(`[createMesh] Geometry not found: ${cfg.geometryId} - ensure that you create it first with createGeometry()`);\n return false;\n }\n\n cfg.origin = cfg.origin ? _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(this._origin, cfg.origin, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3()) : this._origin;\n cfg.positionsDecodeMatrix = cfg.geometry.positionsDecodeMatrix;\n\n if (cfg.transformId) {\n\n // TRANSFORM\n\n cfg.transform = this._transforms[cfg.transformId];\n\n if (!cfg.transform) {\n this.error(`[createMesh] Transform not found: ${cfg.transformId} - ensure that you create it first with createTransform()`);\n return false;\n }\n\n cfg.aabb = cfg.geometry.aabb;\n\n } else {\n\n // MATRIX\n\n if (cfg.matrix) {\n cfg.meshMatrix = cfg.matrix.slice();\n } else {\n const scale = cfg.scale || DEFAULT_SCALE;\n const position = cfg.position || DEFAULT_POSITION;\n const rotation = cfg.rotation || DEFAULT_ROTATION;\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.eulerToQuaternion(rotation, \"XYZ\", DEFAULT_QUATERNION);\n cfg.meshMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.composeMat4(position, DEFAULT_QUATERNION, scale, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4());\n }\n\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(cfg.geometry.aabb, tempOBB3);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformOBB3(cfg.meshMatrix, tempOBB3);\n cfg.aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3ToAABB3(tempOBB3, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3());\n }\n\n const useDTX = (!!this._dtxEnabled\n && (cfg.geometry.primitive === \"triangles\"\n || cfg.geometry.primitive === \"solid\"\n || cfg.geometry.primitive === \"surface\"));\n\n if (useDTX) {\n\n // DTX\n\n cfg.type = DTX;\n\n // NPR\n\n cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : defaultCompressedColor;\n cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;\n\n // BUCKETING - lazy generated, reused\n\n let buckets = this._dtxBuckets[cfg.geometryId];\n if (!buckets) {\n buckets = createDTXBuckets(cfg.geometry, this._enableVertexWelding, this._enableIndexBucketing);\n this._dtxBuckets[cfg.geometryId] = buckets;\n }\n cfg.buckets = buckets;\n\n } else {\n\n // VBO\n\n cfg.type = VBO_INSTANCED;\n\n // PBR\n\n cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : defaultCompressedColor;\n cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;\n cfg.metallic = (cfg.metallic !== undefined && cfg.metallic !== null) ? Math.floor(cfg.metallic * 255) : 0;\n cfg.roughness = (cfg.roughness !== undefined && cfg.roughness !== null) ? Math.floor(cfg.roughness * 255) : 255;\n\n // TEXTURE\n\n if (cfg.textureSetId) {\n cfg.textureSet = this._textureSets[cfg.textureSetId];\n // if (!cfg.textureSet) {\n // this.error(`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`);\n // return false;\n // }\n }\n }\n }\n\n cfg.numPrimitives = this._getNumPrimitives(cfg);\n\n this._meshesCfgsBeforeMeshCreation[cfg.id] = cfg;\n\n return true;\n }\n\n _createMesh(cfg) {\n const mesh = new _SceneModelMesh_js__WEBPACK_IMPORTED_MODULE_3__.SceneModelMesh(this, cfg.id, cfg.color, cfg.opacity, cfg.transform, cfg.textureSet);\n mesh.pickId = this.scene._renderer.getPickID(mesh);\n const pickId = mesh.pickId;\n const a = pickId >> 24 & 0xFF;\n const b = pickId >> 16 & 0xFF;\n const g = pickId >> 8 & 0xFF;\n const r = pickId & 0xFF;\n cfg.pickColor = new Uint8Array([r, g, b, a]); // Quantized pick color\n cfg.solid = (cfg.primitive === \"solid\");\n mesh.origin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.origin);\n switch (cfg.type) {\n case DTX:\n mesh.layer = this._getDTXLayer(cfg);\n mesh.aabb = cfg.aabb;\n break;\n case VBO_BATCHED:\n mesh.layer = this._getVBOBatchingLayer(cfg);\n mesh.aabb = cfg.aabb;\n break;\n case VBO_INSTANCED:\n mesh.layer = this._getVBOInstancingLayer(cfg);\n mesh.aabb = cfg.aabb;\n break;\n }\n if (cfg.transform) {\n cfg.meshMatrix = cfg.transform.worldMatrix;\n }\n mesh.portionId = mesh.layer.createPortion(mesh, cfg);\n return mesh;\n }\n\n _getNumPrimitives(cfg) {\n let countIndices = 0;\n const primitive = cfg.geometry ? cfg.geometry.primitive : cfg.primitive;\n switch (primitive) {\n case \"triangles\":\n case \"solid\":\n case \"surface\":\n switch (cfg.type) {\n case DTX:\n for (let i = 0, len = cfg.buckets.length; i < len; i++) {\n countIndices += cfg.buckets[i].indices.length;\n }\n break;\n case VBO_BATCHED:\n countIndices += cfg.indices.length;\n break;\n case VBO_INSTANCED:\n countIndices += cfg.geometry.indices.length;\n break;\n }\n return Math.round(countIndices / 3);\n case \"points\":\n switch (cfg.type) {\n case DTX:\n for (let i = 0, len = cfg.buckets.length; i < len; i++) {\n countIndices += cfg.buckets[i].positionsCompressed.length;\n }\n break;\n case VBO_BATCHED:\n countIndices += cfg.positions ? cfg.positions.length : cfg.positionsCompressed.length;\n break;\n case VBO_INSTANCED:\n const geometry = cfg.geometry;\n countIndices += geometry.positions ? geometry.positions.length : geometry.positionsCompressed.length;\n break;\n }\n return Math.round(countIndices);\n case \"lines\":\n case \"line-strip\":\n switch (cfg.type) {\n case DTX:\n for (let i = 0, len = cfg.buckets.length; i < len; i++) {\n countIndices += cfg.buckets[i].indices.length;\n }\n break;\n case VBO_BATCHED:\n countIndices += cfg.indices.length;\n break;\n case VBO_INSTANCED:\n countIndices += cfg.geometry.indices.length;\n break;\n }\n return Math.round(countIndices / 2);\n }\n return 0;\n }\n\n _getDTXLayer(cfg) {\n const origin = cfg.origin;\n const primitive = cfg.geometry ? cfg.geometry.primitive : cfg.primitive;\n const layerId = `.${primitive}.${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}`;\n let dtxLayer = this._dtxLayers[layerId];\n if (dtxLayer) {\n if (!dtxLayer.canCreatePortion(cfg)) {\n dtxLayer.finalize();\n delete this._dtxLayers[layerId];\n dtxLayer = null;\n } else {\n return dtxLayer;\n }\n }\n switch (primitive) {\n case \"triangles\":\n case \"solid\":\n case \"surface\":\n dtxLayer = new _dtx_triangles_DTXTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_12__.DTXTrianglesLayer(this, {layerIndex: 0, origin}); // layerIndex is set in #finalize()\n break;\n case \"lines\":\n dtxLayer = new _dtx_lines_DTXLinesLayer_js__WEBPACK_IMPORTED_MODULE_11__.DTXLinesLayer(this, {layerIndex: 0, origin}); // layerIndex is set in #finalize()\n break;\n default:\n return;\n }\n this._dtxLayers[layerId] = dtxLayer;\n this.layerList.push(dtxLayer);\n return dtxLayer;\n }\n\n _getVBOBatchingLayer(cfg) {\n const model = this;\n const origin = cfg.origin;\n const positionsDecodeHash = cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary ?\n this._createHashStringFromMatrix(cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary)\n : \"-\";\n const textureSetId = cfg.textureSetId || \"-\";\n const layerId = `${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}.${cfg.primitive}.${positionsDecodeHash}.${textureSetId}`;\n let vboBatchingLayer = this._vboBatchingLayers[layerId];\n if (vboBatchingLayer) {\n return vboBatchingLayer;\n }\n let textureSet = cfg.textureSet;\n while (!vboBatchingLayer) {\n switch (cfg.primitive) {\n case \"triangles\":\n // console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);\n vboBatchingLayer = new _vbo_batching_triangles_VBOBatchingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_5__.VBOBatchingTrianglesLayer({\n model,\n textureSet,\n layerIndex: 0, // This is set in #finalize()\n scratchMemory: this._vboBatchingLayerScratchMemory,\n positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n origin,\n maxGeometryBatchSize: this._maxGeometryBatchSize,\n solid: (cfg.primitive === \"solid\"),\n autoNormals: true\n });\n break;\n case \"solid\":\n // console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);\n vboBatchingLayer = new _vbo_batching_triangles_VBOBatchingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_5__.VBOBatchingTrianglesLayer({\n model,\n textureSet,\n layerIndex: 0, // This is set in #finalize()\n scratchMemory: this._vboBatchingLayerScratchMemory,\n positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n origin,\n maxGeometryBatchSize: this._maxGeometryBatchSize,\n solid: (cfg.primitive === \"solid\"),\n autoNormals: true\n });\n break;\n case \"surface\":\n // console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);\n vboBatchingLayer = new _vbo_batching_triangles_VBOBatchingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_5__.VBOBatchingTrianglesLayer({\n model,\n textureSet,\n layerIndex: 0, // This is set in #finalize()\n scratchMemory: this._vboBatchingLayerScratchMemory,\n positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n origin,\n maxGeometryBatchSize: this._maxGeometryBatchSize,\n solid: (cfg.primitive === \"solid\"),\n autoNormals: true\n });\n break;\n case \"lines\":\n // console.info(`[SceneModel ${this.id}]: creating VBOBatchingLinesLayer`);\n vboBatchingLayer = new _vbo_batching_lines_VBOBatchingLinesLayer_js__WEBPACK_IMPORTED_MODULE_7__.VBOBatchingLinesLayer({\n model,\n layerIndex: 0, // This is set in #finalize()\n scratchMemory: this._vboBatchingLayerScratchMemory,\n positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n origin,\n maxGeometryBatchSize: this._maxGeometryBatchSize\n });\n break;\n case \"points\":\n // console.info(`[SceneModel ${this.id}]: creating VBOBatchingPointsLayer`);\n vboBatchingLayer = new _vbo_batching_points_VBOBatchingPointsLayer_js__WEBPACK_IMPORTED_MODULE_9__.VBOBatchingPointsLayer({\n model,\n layerIndex: 0, // This is set in #finalize()\n scratchMemory: this._vboBatchingLayerScratchMemory,\n positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n origin,\n maxGeometryBatchSize: this._maxGeometryBatchSize\n });\n break;\n }\n const lenPositions = cfg.positionsCompressed ? cfg.positionsCompressed.length : cfg.positions.length;\n const canCreatePortion = (cfg.primitive === \"points\")\n ? vboBatchingLayer.canCreatePortion(lenPositions)\n : vboBatchingLayer.canCreatePortion(lenPositions, cfg.indices.length);\n if (!canCreatePortion) {\n vboBatchingLayer.finalize();\n delete this._vboBatchingLayers[layerId];\n vboBatchingLayer = null;\n }\n }\n this._vboBatchingLayers[layerId] = vboBatchingLayer;\n this.layerList.push(vboBatchingLayer);\n return vboBatchingLayer;\n }\n\n _createHashStringFromMatrix(matrix) {\n const matrixString = matrix.join('');\n let hash = 0;\n for (let i = 0; i < matrixString.length; i++) {\n const char = matrixString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash |= 0; // Convert to 32-bit integer\n }\n const hashString = (hash >>> 0).toString(16);\n return hashString;\n }\n\n _getVBOInstancingLayer(cfg) {\n const model = this;\n const origin = cfg.origin;\n const textureSetId = cfg.textureSetId || \"-\";\n const geometryId = cfg.geometryId;\n const layerId = `${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}.${textureSetId}.${geometryId}`;\n let vboInstancingLayer = this._vboInstancingLayers[layerId];\n if (vboInstancingLayer) {\n return vboInstancingLayer;\n }\n let textureSet = cfg.textureSet;\n const geometry = cfg.geometry;\n while (!vboInstancingLayer) {\n switch (geometry.primitive) {\n case \"triangles\":\n // console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);\n vboInstancingLayer = new _vbo_instancing_triangles_VBOInstancingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_6__.VBOInstancingTrianglesLayer({\n model,\n textureSet,\n geometry,\n origin,\n layerIndex: 0,\n solid: false\n });\n break;\n case \"solid\":\n // console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);\n vboInstancingLayer = new _vbo_instancing_triangles_VBOInstancingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_6__.VBOInstancingTrianglesLayer({\n model,\n textureSet,\n geometry,\n origin,\n layerIndex: 0,\n solid: true\n });\n break;\n case \"surface\":\n // console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);\n vboInstancingLayer = new _vbo_instancing_triangles_VBOInstancingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_6__.VBOInstancingTrianglesLayer({\n model,\n textureSet,\n geometry,\n origin,\n layerIndex: 0,\n solid: false\n });\n break;\n case \"lines\":\n // console.info(`[SceneModel ${this.id}]: creating VBOInstancingLinesLayer`);\n vboInstancingLayer = new _vbo_instancing_lines_VBOInstancingLinesLayer_js__WEBPACK_IMPORTED_MODULE_8__.VBOInstancingLinesLayer({\n model,\n textureSet,\n geometry,\n origin,\n layerIndex: 0\n });\n break;\n case \"points\":\n // console.info(`[SceneModel ${this.id}]: creating PointsInstancingLayer`);\n vboInstancingLayer = new _vbo_instancing_points_VBOInstancingPointsLayer_js__WEBPACK_IMPORTED_MODULE_10__.VBOInstancingPointsLayer({\n model,\n textureSet,\n geometry,\n origin,\n layerIndex: 0\n });\n break;\n }\n // const lenPositions = geometry.positionsCompressed.length;\n // if (!vboInstancingLayer.canCreatePortion(lenPositions, geometry.indices.length)) { // FIXME: indices should be optional\n // vboInstancingLayer.finalize();\n // delete this._vboInstancingLayers[layerId];\n // vboInstancingLayer = null;\n // }\n }\n this._vboInstancingLayers[layerId] = vboInstancingLayer;\n this.layerList.push(vboInstancingLayer);\n return vboInstancingLayer;\n }\n\n /**\n * Creates a {@link SceneModelEntity} within this SceneModel.\n *\n * * Gives the SceneModelEntity one or more {@link SceneModelMesh}es previously created with\n * {@link SceneModel#createMesh}. A SceneModelMesh can only belong to one SceneModelEntity, so you'll get an\n * error if you try to reuse a mesh among multiple SceneModelEntitys.\n * * The SceneModelEntity can have a {@link SceneModelTextureSet}, previously created with\n * {@link SceneModel#createTextureSet}. A SceneModelTextureSet can belong to multiple SceneModelEntitys.\n * * The SceneModelEntity can have a geometry, previously created with\n * {@link SceneModel#createTextureSet}. A geometry is a \"virtual component\" and can belong to multiple SceneModelEntitys.\n *\n * @param {Object} cfg SceneModelEntity configuration.\n * @param {String} cfg.id Optional ID for the new SceneModelEntity. Must not clash with any existing components within the {@link Scene}.\n * @param {String[]} cfg.meshIds IDs of one or more meshes created previously with {@link SceneModel@createMesh}.\n * @param {Boolean} [cfg.isObject] Set ````true```` if the {@link SceneModelEntity} represents an object, in which case it will be registered by {@link SceneModelEntity#id} in {@link Scene#objects} and can also have a corresponding {@link MetaObject} with matching {@link MetaObject#id}, registered by that ID in {@link MetaScene#metaObjects}.\n * @param {Boolean} [cfg.visible=true] Indicates if the SceneModelEntity is initially visible.\n * @param {Boolean} [cfg.culled=false] Indicates if the SceneModelEntity is initially culled from view.\n * @param {Boolean} [cfg.pickable=true] Indicates if the SceneModelEntity is initially pickable.\n * @param {Boolean} [cfg.clippable=true] Indicates if the SceneModelEntity is initially clippable.\n * @param {Boolean} [cfg.collidable=true] Indicates if the SceneModelEntity is initially included in boundary calculations.\n * @param {Boolean} [cfg.castsShadow=true] Indicates if the SceneModelEntity initially casts shadows.\n * @param {Boolean} [cfg.receivesShadow=true] Indicates if the SceneModelEntity initially receives shadows.\n * @param {Boolean} [cfg.xrayed=false] Indicates if the SceneModelEntity is initially xrayed. XRayed appearance is configured by {@link SceneModel#xrayMaterial}.\n * @param {Boolean} [cfg.highlighted=false] Indicates if the SceneModelEntity is initially highlighted. Highlighted appearance is configured by {@link SceneModel#highlightMaterial}.\n * @param {Boolean} [cfg.selected=false] Indicates if the SceneModelEntity is initially selected. Selected appearance is configured by {@link SceneModel#selectedMaterial}.\n * @param {Boolean} [cfg.edges=false] Indicates if the SceneModelEntity's edges are initially emphasized. Edges appearance is configured by {@link SceneModel#edgeMaterial}.\n * @returns {SceneModelEntity} The new SceneModelEntity.\n */\n createEntity(cfg) {\n if (cfg.id === undefined) {\n cfg.id = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.createUUID();\n } else if (this.scene.components[cfg.id]) {\n this.error(`Scene already has a Component with this ID: ${cfg.id} - will assign random ID`);\n cfg.id = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.createUUID();\n }\n if (cfg.meshIds === undefined) {\n this.error(\"Config missing: meshIds\");\n return;\n }\n let flags = 0;\n if (this._visible && cfg.visible !== false) {\n flags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.VISIBLE;\n }\n if (this._pickable && cfg.pickable !== false) {\n flags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.PICKABLE;\n }\n if (this._culled && cfg.culled !== false) {\n flags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.CULLED;\n }\n if (this._clippable && cfg.clippable !== false) {\n flags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.CLIPPABLE;\n }\n if (this._collidable && cfg.collidable !== false) {\n flags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.COLLIDABLE;\n }\n if (this._edges && cfg.edges !== false) {\n flags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.EDGES;\n }\n if (this._xrayed && cfg.xrayed !== false) {\n flags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.XRAYED;\n }\n if (this._highlighted && cfg.highlighted !== false) {\n flags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.HIGHLIGHTED;\n }\n if (this._selected && cfg.selected !== false) {\n flags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.SELECTED;\n }\n cfg.flags = flags;\n this._createEntity(cfg);\n }\n\n _createEntity(cfg) {\n let meshes = [];\n for (let i = 0, len = cfg.meshIds.length; i < len; i++) {\n const meshId = cfg.meshIds[i];\n let mesh = this._meshes[meshId]; // Trying to get already created mesh\n if (!mesh) { // Checks if there is already created mesh for this meshId\n let meshCfg = this._meshesCfgsBeforeMeshCreation[meshId]; // Trying to get already created cfg\n if (!meshCfg) { // Checks if there is already created cfg for this meshId\n this.error(`Mesh with this ID not found: \"${meshId}\" - ignoring this mesh`); // There is no such cfg\n continue;\n }\n mesh = this._createMesh(meshCfg) // There is no such mesh yet, but there is already created cfg, so it creates this mesh\n this._meshes[cfg.id] = mesh; // Now it will also add this mesh to dictionary of created meshes\n }\n if (mesh.parent) {\n this.error(`Mesh with ID \"${meshId}\" already belongs to object with ID \"${mesh.parent.id}\" - ignoring this mesh`);\n continue;\n }\n meshes.push(mesh);\n }\n const lodCullable = true;\n const entity = new _SceneModelEntity_js__WEBPACK_IMPORTED_MODULE_25__.SceneModelEntity(\n this,\n cfg.isObject,\n cfg.id,\n meshes,\n cfg.flags,\n lodCullable); // Internally sets SceneModelEntity#parent to this SceneModel\n this._entityList.push(entity);\n this._entities[cfg.id] = entity;\n this.numEntities++;\n }\n\n /**\n * Finalizes this SceneModel.\n *\n * Once finalized, you can't add anything more to this SceneModel.\n */\n finalize() {\n if (this.destroyed) {\n return;\n }\n for (let i = 0, len = this.layerList.length; i < len; i++) {\n const layer = this.layerList[i];\n layer.finalize();\n }\n this._geometries = {};\n this._dtxBuckets = {};\n this._textures = {};\n this._textureSets = {};\n this._dtxLayers = {};\n this._vboInstancingLayers = {};\n this._vboBatchingLayers = {};\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n const entity = this._entityList[i];\n entity._finalize();\n }\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n const entity = this._entityList[i];\n entity._finalize2();\n }\n // Sort layers to reduce WebGL shader switching when rendering them\n this.layerList.sort((a, b) => {\n if (a.sortId < b.sortId) {\n return -1;\n }\n if (a.sortId > b.sortId) {\n return 1;\n }\n return 0;\n });\n for (let i = 0, len = this.layerList.length; i < len; i++) {\n const layer = this.layerList[i];\n layer.layerIndex = i;\n }\n this.glRedraw();\n this.scene._aabbDirty = true;\n this._viewMatrixDirty = true;\n this._matrixDirty = true;\n this._aabbDirty = true;\n\n this._setWorldMatrixDirty();\n this._sceneModelDirty();\n\n this.position = this._position;\n }\n\n /** @private */\n stateSortCompare(drawable1, drawable2) {\n }\n\n /** @private */\n rebuildRenderFlags() {\n this.renderFlags.reset();\n this._updateRenderFlagsVisibleLayers();\n if (this.renderFlags.numLayers > 0 && this.renderFlags.numVisibleLayers === 0) {\n this.renderFlags.culled = true;\n return;\n }\n this._updateRenderFlags();\n }\n\n /**\n * @private\n */\n _updateRenderFlagsVisibleLayers() {\n const renderFlags = this.renderFlags;\n renderFlags.numLayers = this.layerList.length;\n renderFlags.numVisibleLayers = 0;\n for (let layerIndex = 0, len = this.layerList.length; layerIndex < len; layerIndex++) {\n const layer = this.layerList[layerIndex];\n const layerVisible = this._getActiveSectionPlanesForLayer(layer);\n if (layerVisible) {\n renderFlags.visibleLayers[renderFlags.numVisibleLayers++] = layerIndex;\n }\n }\n }\n\n _getActiveSectionPlanesForLayer(layer) {\n const renderFlags = this.renderFlags;\n const sectionPlanes = this.scene._sectionPlanesState.sectionPlanes;\n const numSectionPlanes = sectionPlanes.length;\n const baseIndex = layer.layerIndex * numSectionPlanes;\n if (numSectionPlanes > 0) {\n for (let i = 0; i < numSectionPlanes; i++) {\n const sectionPlane = sectionPlanes[i];\n if (!sectionPlane.active) {\n renderFlags.sectionPlanesActivePerLayer[baseIndex + i] = false;\n } else {\n renderFlags.sectionPlanesActivePerLayer[baseIndex + i] = true;\n renderFlags.sectioned = true;\n }\n }\n }\n return true;\n }\n\n _updateRenderFlags() {\n if (this.numVisibleLayerPortions === 0) {\n return;\n }\n if (this.numCulledLayerPortions === this.numPortions) {\n return;\n }\n const renderFlags = this.renderFlags;\n renderFlags.colorOpaque = (this.numTransparentLayerPortions < this.numPortions);\n if (this.numTransparentLayerPortions > 0) {\n renderFlags.colorTransparent = true;\n }\n if (this.numXRayedLayerPortions > 0) {\n const xrayMaterial = this.scene.xrayMaterial._state;\n if (xrayMaterial.fill) {\n if (xrayMaterial.fillAlpha < 1.0) {\n renderFlags.xrayedSilhouetteTransparent = true;\n } else {\n renderFlags.xrayedSilhouetteOpaque = true;\n }\n }\n if (xrayMaterial.edges) {\n if (xrayMaterial.edgeAlpha < 1.0) {\n renderFlags.xrayedEdgesTransparent = true;\n } else {\n renderFlags.xrayedEdgesOpaque = true;\n }\n }\n }\n if (this.numEdgesLayerPortions > 0) {\n const edgeMaterial = this.scene.edgeMaterial._state;\n if (edgeMaterial.edges) {\n renderFlags.edgesOpaque = (this.numTransparentLayerPortions < this.numPortions);\n if (this.numTransparentLayerPortions > 0) {\n renderFlags.edgesTransparent = true;\n }\n }\n }\n if (this.numSelectedLayerPortions > 0) {\n const selectedMaterial = this.scene.selectedMaterial._state;\n if (selectedMaterial.fill) {\n if (selectedMaterial.fillAlpha < 1.0) {\n renderFlags.selectedSilhouetteTransparent = true;\n } else {\n renderFlags.selectedSilhouetteOpaque = true;\n }\n }\n if (selectedMaterial.edges) {\n if (selectedMaterial.edgeAlpha < 1.0) {\n renderFlags.selectedEdgesTransparent = true;\n } else {\n renderFlags.selectedEdgesOpaque = true;\n }\n }\n }\n if (this.numHighlightedLayerPortions > 0) {\n const highlightMaterial = this.scene.highlightMaterial._state;\n if (highlightMaterial.fill) {\n if (highlightMaterial.fillAlpha < 1.0) {\n renderFlags.highlightedSilhouetteTransparent = true;\n } else {\n renderFlags.highlightedSilhouetteOpaque = true;\n }\n }\n if (highlightMaterial.edges) {\n if (highlightMaterial.edgeAlpha < 1.0) {\n renderFlags.highlightedEdgesTransparent = true;\n } else {\n renderFlags.highlightedEdgesOpaque = true;\n }\n }\n }\n }\n\n // -------------- RENDERING ---------------------------------------------------------------------------------------\n\n /** @private */\n drawColorOpaque(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawColorOpaque(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawColorTransparent(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawColorTransparent(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawDepth(frameCtx) { // Dedicated to SAO because it skips transparent objects\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawDepth(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawNormals(frameCtx) { // Dedicated to SAO because it skips transparent objects\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawNormals(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawSilhouetteXRayed(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawSilhouetteXRayed(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawSilhouetteHighlighted(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawSilhouetteHighlighted(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawSilhouetteSelected(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawSilhouetteSelected(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawEdgesColorOpaque(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawEdgesColorOpaque(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawEdgesColorTransparent(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawEdgesColorTransparent(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawEdgesXRayed(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawEdgesXRayed(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawEdgesHighlighted(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawEdgesHighlighted(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n drawEdgesSelected(frameCtx) {\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawEdgesSelected(renderFlags, frameCtx);\n }\n }\n\n /**\n * @private\n */\n drawOcclusion(frameCtx) {\n if (this.numVisibleLayerPortions === 0) {\n return;\n }\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawOcclusion(renderFlags, frameCtx);\n }\n }\n\n /**\n * @private\n */\n drawShadow(frameCtx) {\n if (this.numVisibleLayerPortions === 0) {\n return;\n }\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawShadow(renderFlags, frameCtx);\n }\n }\n\n /** @private */\n setPickMatrices(pickViewMatrix, pickProjMatrix) {\n if (this._numVisibleLayerPortions === 0) {\n return;\n }\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n const layer = this.layerList[layerIndex];\n if (layer.setPickMatrices) {\n layer.setPickMatrices(pickViewMatrix, pickProjMatrix);\n }\n }\n }\n\n /** @private */\n drawPickMesh(frameCtx) {\n if (this.numVisibleLayerPortions === 0) {\n return;\n }\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawPickMesh(renderFlags, frameCtx);\n }\n }\n\n /**\n * Called by SceneModelMesh.drawPickDepths()\n * @private\n */\n drawPickDepths(frameCtx) {\n if (this.numVisibleLayerPortions === 0) {\n return;\n }\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawPickDepths(renderFlags, frameCtx);\n }\n }\n\n /**\n * Called by SceneModelMesh.drawPickNormals()\n * @private\n */\n drawPickNormals(frameCtx) {\n if (this.numVisibleLayerPortions === 0) {\n return;\n }\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n this.layerList[layerIndex].drawPickNormals(renderFlags, frameCtx);\n }\n }\n\n /**\n * @private\n */\n drawSnapInit(frameCtx) {\n if (this.numVisibleLayerPortions === 0) {\n return;\n }\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n const layer = this.layerList[layerIndex];\n if (layer.drawSnapInit) {\n frameCtx.snapPickOrigin = [0, 0, 0];\n frameCtx.snapPickCoordinateScale = [1, 1, 1];\n frameCtx.snapPickLayerNumber++;\n layer.drawSnapInit(renderFlags, frameCtx);\n frameCtx.snapPickLayerParams[frameCtx.snapPickLayerNumber] = {\n origin: frameCtx.snapPickOrigin.slice(),\n coordinateScale: frameCtx.snapPickCoordinateScale.slice(),\n };\n }\n }\n }\n\n /**\n * @private\n */\n drawSnap(frameCtx) {\n if (this.numVisibleLayerPortions === 0) {\n return;\n }\n const renderFlags = this.renderFlags;\n for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n const layerIndex = renderFlags.visibleLayers[i];\n const layer = this.layerList[layerIndex];\n if (layer.drawSnap) {\n frameCtx.snapPickOrigin = [0, 0, 0];\n frameCtx.snapPickCoordinateScale = [1, 1, 1];\n frameCtx.snapPickLayerNumber++;\n layer.drawSnap(renderFlags, frameCtx);\n frameCtx.snapPickLayerParams[frameCtx.snapPickLayerNumber] = {\n origin: frameCtx.snapPickOrigin.slice(),\n coordinateScale: frameCtx.snapPickCoordinateScale.slice(),\n };\n }\n }\n }\n\n /**\n * Destroys this SceneModel.\n */\n destroy() {\n for (let layerId in this._vboBatchingLayers) {\n if (this._vboBatchingLayers.hasOwnProperty(layerId)) {\n this._vboBatchingLayers[layerId].destroy();\n }\n }\n this._vboBatchingLayers = {};\n for (let layerId in this._vboInstancingLayers) {\n if (this._vboInstancingLayers.hasOwnProperty(layerId)) {\n this._vboInstancingLayers[layerId].destroy();\n }\n }\n this._vboInstancingLayers = {};\n this.scene.camera.off(this._onCameraViewMatrix);\n this.scene.off(this._onTick);\n for (let i = 0, len = this.layerList.length; i < len; i++) {\n this.layerList[i].destroy();\n }\n this.layerList = [];\n for (let i = 0, len = this._entityList.length; i < len; i++) {\n this._entityList[i]._destroy();\n }\n // Object.entries(this._geometries).forEach(([id, geometry]) => {\n // geometry.destroy();\n // });\n this._geometries = {};\n this._dtxBuckets = {};\n this._textures = {};\n this._textureSets = {};\n this._meshes = {};\n this._entities = {};\n this.scene._aabbDirty = true;\n if (this._isModel) {\n this.scene._deregisterModel(this);\n }\n (0,_vbo_ScratchMemory_js__WEBPACK_IMPORTED_MODULE_4__.putScratchMemory)();\n super.destroy();\n }\n}\n\n\n/**\n * This function applies two steps to the provided mesh geometry data:\n *\n * - 1st, it reduces its `.positions` to unique positions, thus removing duplicate vertices. It will adjust the `.indices` and `.edgeIndices` array accordingly to the unique `.positions`.\n *\n * - 2nd, it tries to do an optimization called `index rebucketting`\n *\n * _Rebucketting minimizes the amount of RAM usage for a given mesh geometry by trying do demote its needed index bitness._\n *\n * - _for 32 bit indices, will try to demote them to 16 bit indices_\n * - _for 16 bit indices, will try to demote them to 8 bits indices_\n * - _8 bits indices are kept as-is_\n *\n * The fact that 32/16/8 bits are needed for indices, depends on the number of maximumm indexable vertices within the mesh geometry: this is, the number of vertices in the mesh geometry.\n *\n * The function returns the same provided input `geometry`, enrichened with the additional key `.preparedBukets`.\n *\n * @param {object} geometry The mesh information containing `.positions`, `.indices`, `.edgeIndices` arrays.\n *\n * @param enableVertexWelding\n * @param enableIndexBucketing\n * @returns {object} The mesh information enrichened with `.buckets` key.\n */\nfunction createDTXBuckets(geometry, enableVertexWelding, enableIndexBucketing) {\n let uniquePositionsCompressed, uniqueIndices, uniqueEdgeIndices;\n if (enableVertexWelding || enableIndexBucketing) { // Expensive - careful!\n [\n uniquePositionsCompressed,\n uniqueIndices,\n uniqueEdgeIndices,\n ] = (0,_calculateUniquePositions_js__WEBPACK_IMPORTED_MODULE_23__.uniquifyPositions)({\n positionsCompressed: geometry.positionsCompressed,\n indices: geometry.indices,\n edgeIndices: geometry.edgeIndices\n });\n } else {\n uniquePositionsCompressed = geometry.positionsCompressed;\n uniqueIndices = geometry.indices;\n uniqueEdgeIndices = geometry.edgeIndices;\n }\n let buckets;\n if (enableIndexBucketing) {\n let numUniquePositions = uniquePositionsCompressed.length / 3;\n buckets = (0,_rebucketPositions_js__WEBPACK_IMPORTED_MODULE_24__.rebucketPositions)({\n positionsCompressed: uniquePositionsCompressed,\n indices: uniqueIndices,\n edgeIndices: uniqueEdgeIndices,\n },\n (numUniquePositions > (1 << 16)) ? 16 : 8,\n // true\n );\n } else {\n buckets = [{\n positionsCompressed: uniquePositionsCompressed,\n indices: uniqueIndices,\n edgeIndices: uniqueEdgeIndices,\n }];\n }\n return buckets;\n}\n\nfunction\n\ncreateGeometryOBB(geometry) {\n geometry.obb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3();\n if (geometry.positionsCompressed && geometry.positionsCompressed.length > 0) {\n const localAABB = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(localAABB, geometry.positionsCompressed);\n _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(localAABB, geometry.positionsDecodeMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(localAABB, geometry.obb);\n } else if (geometry.positions && geometry.positions.length > 0) {\n const localAABB = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(localAABB, geometry.positions);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(localAABB, geometry.obb);\n } else if (geometry.buckets) {\n const localAABB = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n for (let i = 0, len = geometry.buckets.length; i < len; i++) {\n const bucket = geometry.buckets[i];\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(localAABB, bucket.positionsCompressed);\n }\n _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(localAABB, geometry.positionsDecodeMatrix);\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(localAABB, geometry.obb);\n }\n}\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/model/SceneModel.js?");
3547
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SceneModel: () => (/* binding */ SceneModel)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../math/buildEdgeIndices.js */ \"./src/viewer/scene/math/buildEdgeIndices.js\");\n/* harmony import */ var _SceneModelMesh_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./SceneModelMesh.js */ \"./src/viewer/scene/model/SceneModelMesh.js\");\n/* harmony import */ var _vbo_ScratchMemory_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./vbo/ScratchMemory.js */ \"./src/viewer/scene/model/vbo/ScratchMemory.js\");\n/* harmony import */ var _vbo_batching_triangles_VBOBatchingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./vbo/batching/triangles/VBOBatchingTrianglesLayer.js */ \"./src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js\");\n/* harmony import */ var _vbo_instancing_triangles_VBOInstancingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./vbo/instancing/triangles/VBOInstancingTrianglesLayer.js */ \"./src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js\");\n/* harmony import */ var _vbo_batching_lines_VBOBatchingLinesLayer_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./vbo/batching/lines/VBOBatchingLinesLayer.js */ \"./src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js\");\n/* harmony import */ var _vbo_instancing_lines_VBOInstancingLinesLayer_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./vbo/instancing/lines/VBOInstancingLinesLayer.js */ \"./src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js\");\n/* harmony import */ var _vbo_batching_points_VBOBatchingPointsLayer_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./vbo/batching/points/VBOBatchingPointsLayer.js */ \"./src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js\");\n/* harmony import */ var _vbo_instancing_points_VBOInstancingPointsLayer_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./vbo/instancing/points/VBOInstancingPointsLayer.js */ \"./src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js\");\n/* harmony import */ var _dtx_lines_DTXLinesLayer_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./dtx/lines/DTXLinesLayer.js */ \"./src/viewer/scene/model/dtx/lines/DTXLinesLayer.js\");\n/* harmony import */ var _dtx_triangles_DTXTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./dtx/triangles/DTXTrianglesLayer.js */ \"./src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js\");\n/* harmony import */ var _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ENTITY_FLAGS.js */ \"./src/viewer/scene/model/ENTITY_FLAGS.js\");\n/* harmony import */ var _webgl_RenderFlags_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../webgl/RenderFlags.js */ \"./src/viewer/scene/webgl/RenderFlags.js\");\n/* harmony import */ var _math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n/* harmony import */ var _SceneModelTextureSet_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./SceneModelTextureSet.js */ \"./src/viewer/scene/model/SceneModelTextureSet.js\");\n/* harmony import */ var _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./SceneModelTexture.js */ \"./src/viewer/scene/model/SceneModelTexture.js\");\n/* harmony import */ var _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../webgl/Texture2D.js */ \"./src/viewer/scene/webgl/Texture2D.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _utils_textureTranscoders_KTX2TextureTranscoder_KTX2TextureTranscoder_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/textureTranscoders/KTX2TextureTranscoder/KTX2TextureTranscoder.js */ \"./src/viewer/scene/utils/textureTranscoders/KTX2TextureTranscoder/KTX2TextureTranscoder.js\");\n/* harmony import */ var _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../constants/constants.js */ \"./src/viewer/scene/constants/constants.js\");\n/* harmony import */ var _compression_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./compression.js */ \"./src/viewer/scene/model/compression.js\");\n/* harmony import */ var _calculateUniquePositions_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./calculateUniquePositions.js */ \"./src/viewer/scene/model/calculateUniquePositions.js\");\n/* harmony import */ var _rebucketPositions_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./rebucketPositions.js */ \"./src/viewer/scene/model/rebucketPositions.js\");\n/* harmony import */ var _SceneModelEntity_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./SceneModelEntity.js */ \"./src/viewer/scene/model/SceneModelEntity.js\");\n/* harmony import */ var _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../math/geometryCompressionUtils.js */ \"./src/viewer/scene/math/geometryCompressionUtils.js\");\n/* harmony import */ var _SceneModelTransform_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./SceneModelTransform.js */ \"./src/viewer/scene/model/SceneModelTransform.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst tempVec3a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\nconst tempOBB3 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3();\n\nconst DEFAULT_SCALE = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3([1, 1, 1]);\nconst DEFAULT_POSITION = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3([0, 0, 0]);\nconst DEFAULT_ROTATION = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3([0, 0, 0]);\nconst DEFAULT_QUATERNION = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.identityQuaternion();\nconst DEFAULT_MATRIX = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.identityMat4();\n\nconst DEFAULT_COLOR_TEXTURE_ID = \"defaultColorTexture\";\nconst DEFAULT_METAL_ROUGH_TEXTURE_ID = \"defaultMetalRoughTexture\";\nconst DEFAULT_NORMALS_TEXTURE_ID = \"defaultNormalsTexture\";\nconst DEFAULT_EMISSIVE_TEXTURE_ID = \"defaultEmissiveTexture\";\nconst DEFAULT_OCCLUSION_TEXTURE_ID = \"defaultOcclusionTexture\";\nconst DEFAULT_TEXTURE_SET_ID = \"defaultTextureSet\";\n\nconst defaultCompressedColor = new Uint8Array([255, 255, 255]);\n\nconst VBO_INSTANCED = 0;\nconst VBO_BATCHED = 1;\nconst DTX = 2;\n\n/**\n * @desc A high-performance model representation for efficient rendering and low memory usage.\n *\n * # Examples\n *\n * Internally, SceneModel uses a combination of several different techniques to render and represent\n * the different parts of a typical model. Each of the live examples at these links is designed to \"unit test\" one of these\n * techniques, in isolation. If some bug occurs in SceneModel, we use these tests to debug, but they also\n * serve to demonstrate how to use the capabilities of SceneModel programmatically.\n *\n * * [Loading building models into SceneModels](/examples/buildings)\n * * [Loading city models into SceneModels](/examples/cities)\n * * [Loading LiDAR scans into SceneModels](/examples/lidar)\n * * [Loading CAD models into SceneModels](/examples/cad)\n * * [SceneModel feature tests](/examples/scenemodel)\n *\n * # Overview\n *\n * While xeokit's standard [scene graph](https://github.com/xeokit/xeokit-sdk/wiki/Scene-Graphs) is great for gizmos and medium-sized models, it doesn't scale up to millions of objects in terms of memory and rendering efficiency.\n *\n * For huge models, we have the ````SceneModel```` representation, which is optimized to pack large amounts of geometry into memory and render it efficiently using WebGL.\n *\n * ````SceneModel```` is the default model representation loaded by (at least) {@link GLTFLoaderPlugin}, {@link XKTLoaderPlugin} and {@link WebIFCLoaderPlugin}.\n *\n * In this tutorial you'll learn how to use ````SceneModel```` to create high-detail content programmatically. Ordinarily you'd be learning about ````SceneModel```` if you were writing your own model loader plugins.\n *\n * # Contents\n *\n * - [SceneModel](#DataTextureSceneModel)\n * - [GPU-Resident Geometry](#gpu-resident-geometry)\n * - [Picking](#picking)\n * - [Example 1: Geometry Instancing](#example-1--geometry-instancing)\n * - [Finalizing a SceneModel](#finalizing-a-DataTextureSceneModel)\n * - [Finding Entities](#finding-entities)\n * - [Example 2: Geometry Batching](#example-2--geometry-batching)\n * - [Classifying with Metadata](#classifying-with-metadata)\n * - [Querying Metadata](#querying-metadata)\n * - [Metadata Structure](#metadata-structure)\n * - [RTC Coordinates](#rtc-coordinates-for-double-precision)\n * - [Example 3: RTC Coordinates with Geometry Instancing](#example-2--rtc-coordinates-with-geometry-instancing)\n * - [Example 4: RTC Coordinates with Geometry Batching](#example-2--rtc-coordinates-with-geometry-batching)\n *\n * ## SceneModel\n *\n * ````SceneModel```` uses two rendering techniques internally:\n *\n * 1. ***Geometry batching*** for unique geometries, combining those into a single WebGL geometry buffer, to render in one draw call, and\n * 2. ***geometry instancing*** for geometries that are shared by multiple meshes, rendering all instances of each shared geometry in one draw call.\n *\n * <br>\n * These techniques come with certain limitations:\n *\n * * Non-realistic rendering - while scene graphs can use xeokit's full set of material workflows, ````SceneModel```` uses simple Lambertian shading without textures.\n * * Static transforms - transforms within a ````SceneModel```` are static and cannot be dynamically translated, rotated and scaled the way {@link Node}s and {@link Mesh}es in scene graphs can.\n * * Immutable model representation - while scene graph {@link Node}s and\n * {@link Mesh}es can be dynamically plugged together, ````SceneModel```` is immutable,\n * since it packs its geometries into buffers and instanced arrays.\n *\n * ````SceneModel````'s API allows us to exploit batching and instancing, while exposing its elements as\n * abstract {@link Entity} types.\n *\n * {@link Entity} is the abstract base class for\n * the various xeokit components that represent models, objects, or anonymous visible elements. An Entity has a unique ID and can be\n * individually shown, hidden, selected, highlighted, ghosted, culled, picked and clipped, and has its own World-space boundary.\n *\n * * A ````SceneModel```` is an {@link Entity} that represents a model.\n * * A ````SceneModel```` represents each of its objects with an {@link Entity}.\n * * Each {@link Entity} has one or more meshes that define its shape.\n * * Each mesh has either its own unique geometry, or shares a geometry with other meshes.\n *\n * ## GPU-Resident Geometry\n *\n * For a low memory footprint, ````SceneModel```` stores its geometries in GPU memory only, compressed (quantized) as integers. Unfortunately, GPU-resident geometry is\n * not readable by JavaScript.\n *\n *\n * ## Example 1: Geometry Instancing\n *\n * In the example below, we'll use a ````SceneModel````\n * to build a simple table model using geometry instancing.\n *\n * We'll start by adding a reusable box-shaped geometry to our ````SceneModel````.\n *\n * Then, for each object in our model we'll add an {@link Entity}\n * that has a mesh that instances our box geometry, transforming and coloring the instance.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_instancing)\n *\n * ````javascript\n * import {Viewer, SceneModel} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\",\n * transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * // Build a SceneModel representing a table\n * // with four legs, using geometry instancing\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"table\",\n * isModel: true, // <--- Registers SceneModel in viewer.scene.models\n * position: [0, 0, 0],\n * scale: [1, 1, 1],\n * rotation: [0, 0, 0]\n * });\n *\n * // Create a reusable geometry within the SceneModel\n * // We'll instance this geometry by five meshes\n *\n * sceneModel.createGeometry({\n *\n * id: \"myBoxGeometry\",\n *\n * // The primitive type - allowed values are \"points\", \"lines\" and \"triangles\".\n * // See the OpenGL/WebGL specification docs\n * // for how the coordinate arrays are supposed to be laid out.\n * primitive: \"triangles\",\n *\n * // The vertices - eight for our cube, each\n * // one spanning three array elements for X,Y and Z\n * positions: [\n * 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // v0-v1-v2-v3 front\n * 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // v0-v3-v4-v1 right\n * 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // v0-v1-v6-v1 top\n * -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // v1-v6-v7-v2 left\n * -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // v7-v4-v3-v2 bottom\n * 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1 // v4-v7-v6-v1 back\n * ],\n *\n * // Normal vectors, one for each vertex\n * normals: [\n * 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0-v1-v2-v3 front\n * 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4-v5 right\n * 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0-v5-v6-v1 top\n * -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1-v6-v7-v2 left\n * 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, // v7-v4-v3-v2 bottom\n * 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1 // v4-v7-v6-v5 back\n * ],\n *\n * // Indices - these organise the positions and and normals\n * // into geometric primitives in accordance with the \"primitive\" parameter,\n * // in this case a set of three indices for each triangle.\n * //\n * // Note that each triangle is specified in counter-clockwise winding order.\n * //\n * indices: [\n * 0, 1, 2, 0, 2, 3, // front\n * 4, 5, 6, 4, 6, 7, // right\n * 8, 9, 10, 8, 10, 11, // top\n * 12, 13, 14, 12, 14, 15, // left\n * 16, 17, 18, 16, 18, 19, // bottom\n * 20, 21, 22, 20, 22, 23\n * ]\n * });\n *\n * // Red table leg\n *\n * sceneModel.createMesh({\n * id: \"redLegMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * id: \"redLeg\",\n * meshIds: [\"redLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Green table leg\n *\n * sceneModel.createMesh({\n * id: \"greenLegMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * id: \"greenLeg\",\n * meshIds: [\"greenLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Blue table leg\n *\n * sceneModel.createMesh({\n * id: \"blueLegMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"blueLeg\",\n * meshIds: [\"blueLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Yellow table leg\n *\n * sceneModel.createMesh({\n * id: \"yellowLegMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"yellowLeg\",\n * meshIds: [\"yellowLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Purple table top\n *\n * sceneModel.createMesh({\n * id: \"purpleTableTopMesh\",\n * geometryId: \"myBoxGeometry\",\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"purpleTableTop\",\n * meshIds: [\"purpleTableTopMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n * ````\n *\n * ## Finalizing a SceneModel\n *\n * Before we can view and interact with our ````SceneModel````, we need to **finalize** it. Internally, this causes the ````SceneModel```` to build the\n * vertex buffer objects (VBOs) that support our geometry instances. When using geometry batching (see next example),\n * this causes ````SceneModel```` to build the VBOs that combine the batched geometries. Note that you can do both instancing and\n * batching within the same ````SceneModel````.\n *\n * Once finalized, we can't add anything more to our ````SceneModel````.\n *\n * ```` javascript\n * SceneModel.finalize();\n * ````\n *\n * ## Finding Entities\n *\n * As mentioned earlier, {@link Entity} is\n * the abstract base class for components that represent models, objects, or just\n * anonymous visible elements.\n *\n * Since we created configured our ````SceneModel```` with ````isModel: true````,\n * we're able to find it as an Entity by ID in ````viewer.scene.models````. Likewise, since\n * we configured each of its Entities with ````isObject: true````, we're able to\n * find them in ````viewer.scene.objects````.\n *\n *\n * ````javascript\n * // Get the whole table model Entity\n * const table = viewer.scene.models[\"table\"];\n *\n * // Get some leg object Entities\n * const redLeg = viewer.scene.objects[\"redLeg\"];\n * const greenLeg = viewer.scene.objects[\"greenLeg\"];\n * const blueLeg = viewer.scene.objects[\"blueLeg\"];\n * ````\n *\n * ## Example 2: Geometry Batching\n *\n * Let's once more use a ````SceneModel````\n * to build the simple table model, this time exploiting geometry batching.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_batching)\n *\n * ````javascript\n * import {Viewer, SceneModel} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\",\n * transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * // Create a SceneModel representing a table with four legs, using geometry batching\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"table\",\n * isModel: true, // <--- Registers SceneModel in viewer.scene.models\n * position: [0, 0, 0],\n * scale: [1, 1, 1],\n * rotation: [0, 0, 0]\n * });\n *\n * // Red table leg\n *\n * sceneModel.createMesh({\n * id: \"redLegMesh\",\n *\n * // Geometry arrays are same as for the earlier batching example\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * id: \"redLeg\",\n * meshIds: [\"redLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Green table leg\n *\n * sceneModel.createMesh({\n * id: \"greenLegMesh\",\n * primitive: \"triangles\",\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * id: \"greenLeg\",\n * meshIds: [\"greenLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Blue table leg\n *\n * sceneModel.createMesh({\n * id: \"blueLegMesh\",\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"blueLeg\",\n * meshIds: [\"blueLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Yellow table leg object\n *\n * sceneModel.createMesh({\n * id: \"yellowLegMesh\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"yellowLeg\",\n * meshIds: [\"yellowLegMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Purple table top\n *\n * sceneModel.createMesh({\n * id: \"purpleTableTopMesh\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * id: \"purpleTableTop\",\n * meshIds: [\"purpleTableTopMesh\"],\n * isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Finalize the SceneModel.\n *\n * SceneModel.finalize();\n *\n * // Find BigModelNodes by their model and object IDs\n *\n * // Get the whole table model\n * const table = viewer.scene.models[\"table\"];\n *\n * // Get some leg objects\n * const redLeg = viewer.scene.objects[\"redLeg\"];\n * const greenLeg = viewer.scene.objects[\"greenLeg\"];\n * const blueLeg = viewer.scene.objects[\"blueLeg\"];\n * ````\n *\n * ## Classifying with Metadata\n *\n * In the previous examples, we used ````SceneModel```` to build\n * two versions of the same table model, to demonstrate geometry batching and geometry instancing.\n *\n * We'll now classify our {@link Entity}s with metadata. This metadata\n * will work the same for both our examples, since they create the exact same structure of {@link Entity}s\n * to represent their models and objects. The abstract Entity type is, after all, intended to provide an abstract interface through which differently-implemented scene content can be accessed uniformly.\n *\n * To create the metadata, we'll create a {@link MetaModel} for our model,\n * with a {@link MetaObject} for each of it's objects. The MetaModel and MetaObjects\n * get the same IDs as the {@link Entity}s that represent their model and objects within our scene.\n *\n * ```` javascript\n * const furnitureMetaModel = viewer.metaScene.createMetaModel(\"furniture\", { // Creates a MetaModel in the MetaScene\n *\n * \"projectId\": \"myTableProject\",\n * \"revisionId\": \"V1.0\",\n *\n * \"metaObjects\": [\n * { // Creates a MetaObject in the MetaModel\n * \"id\": \"table\",\n * \"name\": \"Table\", // Same ID as an object Entity\n * \"type\": \"furniture\", // Arbitrary type, could be IFC type\n * \"properties\": { // Arbitrary properties, could be IfcPropertySet\n * \"cost\": \"200\"\n * }\n * },\n * {\n * \"id\": \"redLeg\",\n * \"name\": \"Red table Leg\",\n * \"type\": \"leg\",\n * \"parent\": \"table\", // References first MetaObject as parent\n * \"properties\": {\n * \"material\": \"wood\"\n * }\n * },\n * {\n * \"id\": \"greenLeg\", // Node with corresponding id does not need to exist\n * \"name\": \"Green table leg\", // and MetaObject does not need to exist for Node with an id\n * \"type\": \"leg\",\n * \"parent\": \"table\",\n * \"properties\": {\n * \"material\": \"wood\"\n * }\n * },\n * {\n * \"id\": \"blueLeg\",\n * \"name\": \"Blue table leg\",\n * \"type\": \"leg\",\n * \"parent\": \"table\",\n * \"properties\": {\n * \"material\": \"wood\"\n * }\n * },\n * {\n * \"id\": \"yellowLeg\",\n * \"name\": \"Yellow table leg\",\n * \"type\": \"leg\",\n * \"parent\": \"table\",\n * \"properties\": {\n * \"material\": \"wood\"\n * }\n * },\n * {\n * \"id\": \"tableTop\",\n * \"name\": \"Purple table top\",\n * \"type\": \"surface\",\n * \"parent\": \"table\",\n * \"properties\": {\n * \"material\": \"formica\",\n * \"width\": \"60\",\n * \"depth\": \"60\",\n * \"thickness\": \"5\"\n * }\n * }\n * ]\n * });\n * ````\n *\n * ## Querying Metadata\n *\n * Having created and classified our model (either the instancing or batching example), we can now find the {@link MetaModel}\n * and {@link MetaObject}s using the IDs of their\n * corresponding {@link Entity}s.\n *\n * ````JavaScript\n * const furnitureMetaModel = scene.metaScene.metaModels[\"furniture\"];\n *\n * const redLegMetaObject = scene.metaScene.metaObjects[\"redLeg\"];\n * ````\n *\n * In the snippet below, we'll log metadata on each {@link Entity} we click on:\n *\n * ````JavaScript\n * viewer.scene.input.on(\"mouseclicked\", function (coords) {\n *\n * const hit = viewer.scene.pick({\n * canvasPos: coords\n * });\n *\n * if (hit) {\n * const entity = hit.entity;\n * const metaObject = viewer.metaScene.metaObjects[entity.id];\n * if (metaObject) {\n * console.log(JSON.stringify(metaObject.getJSON(), null, \"\\t\"));\n * }\n * }\n * });\n * ````\n *\n * ## Metadata Structure\n *\n * The {@link MetaModel}\n * organizes its {@link MetaObject}s in\n * a tree that describes their structural composition:\n *\n * ````JavaScript\n * // Get metadata on the root object\n * const tableMetaObject = furnitureMetaModel.rootMetaObject;\n *\n * // Get metadata on the leg objects\n * const redLegMetaObject = tableMetaObject.children[0];\n * const greenLegMetaObject = tableMetaObject.children[1];\n * const blueLegMetaObject = tableMetaObject.children[2];\n * const yellowLegMetaObject = tableMetaObject.children[3];\n * ````\n *\n * Given an {@link Entity}, we can find the object or model of which it is a part, or the objects that comprise it. We can also generate UI\n * components from the metadata, such as the tree view demonstrated in [this demo](https://xeokit.github.io/xeokit-sdk/examples/#BIMOffline_glTF_OTCConferenceCenter).\n *\n * This hierarchy allows us to express the hierarchical structure of a model while representing it in\n * various ways in the 3D scene (such as with ````SceneModel````, which\n * has a non-hierarchical scene representation).\n *\n * Note also that a {@link MetaObject} does not need to have a corresponding\n * {@link Entity} and vice-versa.\n *\n * # RTC Coordinates for Double Precision\n *\n * ````SceneModel```` can emulate 64-bit precision on GPUs using relative-to-center (RTC) coordinates.\n *\n * Consider a model that contains many small objects, but with such large spatial extents that 32 bits of GPU precision (accurate to ~7 digits) will not be sufficient to render all of the the objects without jittering.\n *\n * To prevent jittering, we could spatially subdivide the objects into \"tiles\". Each tile would have a center position, and the positions of the objects within the tile would be relative to that center (\"RTC coordinates\").\n *\n * While the center positions of the tiles would be 64-bit values, the object positions only need to be 32-bit.\n *\n * Internally, when rendering an object with RTC coordinates, xeokit first temporarily translates the camera viewing matrix by the object's tile's RTC center, on the CPU, using 64-bit math.\n *\n * Then xeokit loads the viewing matrix into its WebGL shaders, where math happens at 32-bit precision. Within the shaders, the matrix is effectively down-cast to 32-bit precision, and the object's 32-bit vertex positions are transformed by the matrix.\n *\n * We see no jittering, because with RTC a detectable loss of GPU accuracy only starts happening to objects as they become very distant from the camera viewpoint, at which point they are too small to be discernible anyway.\n *\n * ## RTC Coordinates with Geometry Instancing\n *\n * To use RTC with ````SceneModel```` geometry instancing, we specify an RTC center for the geometry via its ````origin```` parameter. Then ````SceneModel```` assumes that all meshes that instance that geometry are within the same RTC coordinate system, ie. the meshes ````position```` and ````rotation```` properties are assumed to be relative to the geometry's ````origin````.\n *\n * For simplicity, our example's meshes all instance the same geometry. Therefore, our example model has only one RTC center.\n *\n * Note that the axis-aligned World-space boundary (AABB) of our model is ````[ -6, -9, -6, 1000000006, -2.5, 1000000006]````.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_batching)\n *\n * ````javascript\n * const origin = [100000000, 0, 100000000];\n *\n * sceneModel.createGeometry({\n * id: \"box\",\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg1\",\n * geometryId: \"box\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg1\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg2\",\n * geometryId: \"box\",\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg2\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg3\",\n * geometryId: \"box\",\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg3\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg4\",\n * geometryId: \"box\",\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg4\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"top\",\n * geometryId: \"box\",\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0],\n * origin: origin\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"top\"],\n * isObject: true\n * });\n * ````\n *\n * ## RTC Coordinates with Geometry Batching\n *\n * To use RTC with ````SceneModel```` geometry batching, we specify an RTC center (````origin````) for each mesh. For performance, we try to have as many meshes share the same value for ````origin```` as possible. Each mesh's ````positions````, ````position```` and ````rotation```` properties are assumed to be relative to ````origin````.\n *\n * For simplicity, the meshes in our example all share the same RTC center.\n *\n * The axis-aligned World-space boundary (AABB) of our model is ````[ -6, -9, -6, 1000000006, -2.5, 1000000006]````.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_batching)\n *\n * ````javascript\n * const origin = [100000000, 0, 100000000];\n *\n * sceneModel.createMesh({\n * id: \"leg1\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg1\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg2\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg2\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg3\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg3\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg4\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg4\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"top\",\n * origin: origin, // This mesh's positions and transforms are relative to the RTC center\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"top\"],\n * isObject: true\n * });\n * ````\n *\n * ## Positioning at World-space coordinates\n *\n * To position a SceneModel at given double-precision World coordinates, we can\n * configure the ````origin```` of the SceneModel itself. The ````origin```` is a double-precision\n * 3D World-space position at which the SceneModel will be located.\n *\n * Note that ````position```` is a single-precision offset relative to ````origin````.\n *\n * ````javascript\n * const origin = [100000000, 0, 100000000];\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"table\",\n * isModel: true,\n * origin: origin, // Everything in this SceneModel is relative to this RTC center\n * position: [0, 0, 0],\n * scale: [1, 1, 1],\n * rotation: [0, 0, 0]\n * });\n *\n * sceneModel.createGeometry({\n * id: \"box\",\n * primitive: \"triangles\",\n * positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n * normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n * indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg1\",\n * geometryId: \"box\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg1\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg2\",\n * geometryId: \"box\",\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg2\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg3\",\n * geometryId: \"box\",\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg3\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"leg4\",\n * geometryId: \"box\",\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"leg4\"],\n * isObject: true\n * });\n *\n * sceneModel.createMesh({\n * id: \"top\",\n * geometryId: \"box\",\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n * meshIds: [\"top\"],\n * isObject: true\n * });\n * ````\n *\n * # Textures\n *\n * ## Loading KTX2 Texture Files into a SceneModel\n *\n * A {@link SceneModel} that is configured with a {@link KTX2TextureTranscoder} will\n * allow us to load textures into it from KTX2 buffers or files.\n *\n * In the example below, we'll create a {@link Viewer}, containing a {@link SceneModel} configured with a\n * {@link KTX2TextureTranscoder}. We'll then programmatically create a simple object within the SceneModel, consisting of\n * a single mesh with a texture loaded from a KTX2 file, which our SceneModel internally transcodes, using\n * its {@link KTX2TextureTranscoder}. Note how we configure our {@link KTX2TextureTranscoder} with a path to the Basis Universal\n * transcoder WASM module.\n *\n * ````javascript\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\",\n * transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n * viewer,\n * transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to BasisU transcoder module\n * });\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"myModel\",\n * textureTranscoder // <<-------------------- Configure model with our transcoder\n * });\n *\n * sceneModel.createTexture({\n * id: \"myColorTexture\",\n * src: \"../assets/textures/compressed/sample_uastc_zstd.ktx2\" // <<----- KTX2 texture asset\n * });\n *\n * sceneModel.createTexture({\n * id: \"myMetallicRoughnessTexture\",\n * src: \"../assets/textures/alpha/crosshatchAlphaMap.jpg\" // <<----- JPEG texture asset\n * });\n *\n * sceneModel.createTextureSet({\n * id: \"myTextureSet\",\n * colorTextureId: \"myColorTexture\",\n * metallicRoughnessTextureId: \"myMetallicRoughnessTexture\"\n * });\n *\n * sceneModel.createMesh({\n * id: \"myMesh\",\n * textureSetId: \"myTextureSet\",\n * primitive: \"triangles\",\n * positions: [1, 1, 1, ...],\n * normals: [0, 0, 1, 0, ...],\n * uv: [1, 0, 0, ...],\n * indices: [0, 1, 2, ...],\n * });\n *\n * sceneModel.createEntity({\n * id: \"myEntity\",\n * meshIds: [\"myMesh\"]\n * });\n *\n * sceneModel.finalize();\n * ````\n *\n * ## Loading KTX2 Textures from ArrayBuffers into a SceneModel\n *\n * A SceneModel that is configured with a {@link KTX2TextureTranscoder} will allow us to load textures into\n * it from KTX2 ArrayBuffers.\n *\n * In the example below, we'll create a {@link Viewer}, containing a {@link SceneModel} configured with a\n * {@link KTX2TextureTranscoder}. We'll then programmatically create a simple object within the SceneModel, consisting of\n * a single mesh with a texture loaded from a KTX2 ArrayBuffer, which our SceneModel internally transcodes, using\n * its {@link KTX2TextureTranscoder}.\n *\n * ````javascript\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\",\n * transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n * viewer,\n * transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to BasisU transcoder module\n * });\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n * id: \"myModel\",\n * textureTranscoder // <<-------------------- Configure model with our transcoder\n * });\n *\n * utils.loadArraybuffer(\"../assets/textures/compressed/sample_uastc_zstd.ktx2\",(arrayBuffer) => {\n *\n * sceneModel.createTexture({\n * id: \"myColorTexture\",\n * buffers: [arrayBuffer] // <<----- KTX2 texture asset\n * });\n *\n * sceneModel.createTexture({\n * id: \"myMetallicRoughnessTexture\",\n * src: \"../assets/textures/alpha/crosshatchAlphaMap.jpg\" // <<----- JPEG texture asset\n * });\n *\n * sceneModel.createTextureSet({\n * id: \"myTextureSet\",\n * colorTextureId: \"myColorTexture\",\n * metallicRoughnessTextureId: \"myMetallicRoughnessTexture\"\n * });\n *\n * sceneModel.createMesh({\n * id: \"myMesh\",\n * textureSetId: \"myTextureSet\",\n * primitive: \"triangles\",\n * positions: [1, 1, 1, ...],\n * normals: [0, 0, 1, 0, ...],\n * uv: [1, 0, 0, ...],\n * indices: [0, 1, 2, ...],\n * });\n *\n * sceneModel.createEntity({\n * id: \"myEntity\",\n * meshIds: [\"myMesh\"]\n * });\n *\n * sceneModel.finalize();\n * });\n * ````\n *\n * @implements {Entity}\n */\nclass SceneModel extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\n\t/**\n\t * @constructor\n\t * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n\t * @param {*} [cfg] Configs\n\t * @param {String} [cfg.id] Optional ID, unique among all components in the parent scene, generated automatically when omitted.\n\t * @param {Boolean} [cfg.isModel] Specify ````true```` if this SceneModel represents a model, in which case the SceneModel will be registered by {@link SceneModel#id} in {@link Scene#models} and may also have a corresponding {@link MetaModel} with matching {@link MetaModel#id}, registered by that ID in {@link MetaScene#metaModels}.\n\t * @param {Number[]} [cfg.origin=[0,0,0]] World-space double-precision 3D origin.\n\t * @param {Number[]} [cfg.position=[0,0,0]] Local, single-precision 3D position, relative to the origin parameter.\n\t * @param {Number[]} [cfg.scale=[1,1,1]] Local scale.\n\t * @param {Number[]} [cfg.rotation=[0,0,0]] Local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n\t * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] Local modelling transform matrix. Overrides the position, scale and rotation parameters.\n\t * @param {Boolean} [cfg.visible=true] Indicates if the SceneModel is initially visible.\n\t * @param {Boolean} [cfg.culled=false] Indicates if the SceneModel is initially culled from view.\n\t * @param {Boolean} [cfg.pickable=true] Indicates if the SceneModel is initially pickable.\n\t * @param {Boolean} [cfg.clippable=true] Indicates if the SceneModel is initially clippable.\n\t * @param {Boolean} [cfg.collidable=true] Indicates if the SceneModel is initially included in boundary calculations.\n\t * @param {Boolean} [cfg.xrayed=false] Indicates if the SceneModel is initially xrayed.\n\t * @param {Boolean} [cfg.highlighted=false] Indicates if the SceneModel is initially highlighted.\n\t * @param {Boolean} [cfg.selected=false] Indicates if the SceneModel is initially selected.\n\t * @param {Boolean} [cfg.edges=false] Indicates if the SceneModel's edges are initially emphasized.\n\t * @param {Number[]} [cfg.colorize=[1.0,1.0,1.0]] SceneModel's initial RGB colorize color, multiplies by the rendered fragment colors.\n\t * @param {Number} [cfg.opacity=1.0] SceneModel's initial opacity factor, multiplies by the rendered fragment alpha.\n\t * @param {Number} [cfg.backfaces=false] When we set this ````true````, then we force rendering of backfaces for this SceneModel. When\n\t * we leave this ````false````, then we allow the Viewer to decide when to render backfaces. In that case, the\n\t * Viewer will hide backfaces on watertight meshes, show backfaces on open meshes, and always show backfaces on meshes when we slice them open with {@link SectionPlane}s.\n\t * @param {Boolean} [cfg.saoEnabled=true] Indicates if Scalable Ambient Obscurance (SAO) will apply to this SceneModel. SAO is configured by the Scene's {@link SAO} component.\n\t * @param {Boolean} [cfg.pbrEnabled=true] Indicates if physically-based rendering (PBR) will apply to the SceneModel when {@link Scene#pbrEnabled} is ````true````.\n\t * @param {Boolean} [cfg.colorTextureEnabled=true] Indicates if base color textures will be rendered for the SceneModel when {@link Scene#colorTextureEnabled} is ````true````.\n\t * @param {Number} [cfg.edgeThreshold=10] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n\t * @param {Number} [cfg.maxGeometryBatchSize=50000000] Maximum geometry batch size, as number of vertices. This is optionally supplied\n\t * to limit the size of the batched geometry arrays that SceneModel internally creates for batched geometries.\n\t * A lower value means less heap allocation/de-allocation while creating/loading batched geometries, but more draw calls and\n\t * slower rendering speed. A high value means larger heap allocation/de-allocation while creating/loading, but less draw calls\n\t * and faster rendering speed. It's recommended to keep this somewhere roughly between ````50000```` and ````50000000```.\n\t * @param {TextureTranscoder} [cfg.textureTranscoder] Transcoder that will be used internally by {@link SceneModel#createTexture}\n\t * to convert transcoded texture data. Only required when we'll be providing transcoded data\n\t * to {@link SceneModel#createTexture}. We assume that all transcoded texture data added to a ````SceneModel````\n\t * will then in a format supported by this transcoder.\n\t * @param {Boolean} [cfg.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to\n\t * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable\n\t * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point\n\t * primitives. Only works while {@link DTX#enabled} is also ````true````.\n\t */\n\tconstructor(owner, cfg = {}) {\n\t\tsuper(owner, cfg);\n\n\t\tthis._dtxEnabled = this.scene.dtxEnabled && cfg.dtxEnabled !== false;\n\n\t\tthis._enableVertexWelding = false; // Not needed for most objects, and very expensive, so disabled\n\t\tthis._enableIndexBucketing = false; // Until fixed: https://github.com/xeokit/xeokit-sdk/issues/1204\n\n\t\tthis._vboBatchingLayerScratchMemory = (0,_vbo_ScratchMemory_js__WEBPACK_IMPORTED_MODULE_4__.getScratchMemory)();\n\t\tthis._textureTranscoder = cfg.textureTranscoder || (0,_utils_textureTranscoders_KTX2TextureTranscoder_KTX2TextureTranscoder_js__WEBPACK_IMPORTED_MODULE_20__.getKTX2TextureTranscoder)(this.scene.viewer);\n\n\t\tthis._maxGeometryBatchSize = cfg.maxGeometryBatchSize;\n\n\t\tthis._aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\tthis._aabbDirty = true;\n\t\tthis._aabbUpdate = false;\n\t\tthis._exceptionIds = [];\n\n\t\tthis._quantizationRanges = {};\n\n\t\tthis._vboInstancingLayers = {};\n\t\tthis._vboBatchingLayers = {};\n\t\tthis._dtxLayers = {};\n\n\t\tthis.layerList = []; // For GL state efficiency when drawing, InstancingLayers are in first part, BatchingLayers are in second\n\t\tthis._entityList = [];\n\n\t\tthis._geometries = {};\n\t\tthis._dtxBuckets = {}; // Geometries with optimizations used for data texture representation\n\t\tthis._textures = {};\n\t\tthis._textureSets = {};\n\t\tthis._transforms = {};\n\t\tthis._meshes = {};\n\t\tthis._entities = {};\n\n\t\tthis._scheduledMeshes = {};\n\t\tthis._meshesCfgsBeforeMeshCreation = {};\n\n\t\t/** @private **/\n\t\tthis.renderFlags = new _webgl_RenderFlags_js__WEBPACK_IMPORTED_MODULE_14__.RenderFlags();\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numGeometries = 0; // Number of geometries created with createGeometry()\n\n\t\t// These counts are used to avoid unnecessary render passes\n\t\t// They are incremented or decremented exclusively by BatchingLayer and InstancingLayer\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numPortions = 0;\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numVisibleLayerPortions = 0;\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numTransparentLayerPortions = 0;\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numXRayedLayerPortions = 0;\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numHighlightedLayerPortions = 0;\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numSelectedLayerPortions = 0;\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numEdgesLayerPortions = 0;\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numPickableLayerPortions = 0;\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numClippableLayerPortions = 0;\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tthis.numCulledLayerPortions = 0;\n\n\t\tthis.numEntities = 0;\n\t\tthis._numTriangles = 0;\n\t\tthis._numLines = 0;\n\t\tthis._numPoints = 0;\n\n\t\tthis._edgeThreshold = cfg.edgeThreshold || 10;\n\n\t\t// Build static matrix\n\n\t\tthis._origin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.origin || [0, 0, 0]);\n\t\tthis._position = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.position || [0, 0, 0]);\n\t\tthis._rotation = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.rotation || [0, 0, 0]);\n\t\tthis._quaternion = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4(cfg.quaternion || [0, 0, 0, 1]);\n\t\tthis._conjugateQuaternion = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4(cfg.quaternion || [0, 0, 0, 1]);\n\n\t\tif (cfg.rotation) {\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n\t\t}\n\t\tthis._scale = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.scale || [1, 1, 1]);\n\n\t\tthis._worldRotationMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\tthis._worldRotationMatrixConjugate = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\tthis._matrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\tthis._matrixDirty = true;\n\n\t\tthis._rebuildMatrices();\n\n\t\tthis._worldNormalMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(this._matrix, this._worldNormalMatrix);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transposeMat4(this._worldNormalMatrix);\n\n\t\tif (cfg.matrix || cfg.position || cfg.rotation || cfg.scale || cfg.quaternion) {\n\t\t\tthis._viewMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\t\tthis._viewNormalMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\t\tthis._viewMatrixDirty = true;\n\t\t\tthis._matrixNonIdentity = true;\n\t\t}\n\n\t\tthis._opacity = 1.0;\n\t\tthis._colorize = [1, 1, 1];\n\n\t\tthis._saoEnabled = cfg.saoEnabled !== false;\n\t\tthis._pbrEnabled = cfg.pbrEnabled !== false;\n\t\tthis._colorTextureEnabled = cfg.colorTextureEnabled !== false;\n\n\t\tthis._isModel = cfg.isModel;\n\t\tif (this._isModel) {\n\t\t\tthis.scene._registerModel(this);\n\t\t}\n\n\t\tthis._onCameraViewMatrix = this.scene.camera.on(\"matrix\", () => {\n\t\t\tthis._viewMatrixDirty = true;\n\t\t});\n\n\t\tthis._meshesWithDirtyMatrices = [];\n\t\tthis._numMeshesWithDirtyMatrices = 0;\n\n\t\tthis._onTick = this.scene.on(\"tick\", () => {\n\t\t\twhile (this._numMeshesWithDirtyMatrices > 0) {\n\t\t\t\tthis._meshesWithDirtyMatrices[--this._numMeshesWithDirtyMatrices]._updateMatrix();\n\t\t\t}\n\t\t});\n\n\t\tthis._createDefaultTextureSet();\n\n\t\tthis.visible = cfg.visible;\n\t\tthis.culled = cfg.culled;\n\t\tthis.pickable = cfg.pickable;\n\t\tthis.clippable = cfg.clippable;\n\t\tthis.collidable = cfg.collidable;\n\t\tthis.castsShadow = cfg.castsShadow;\n\t\tthis.receivesShadow = cfg.receivesShadow;\n\t\tthis.xrayed = cfg.xrayed;\n\t\tthis.highlighted = cfg.highlighted;\n\t\tthis.selected = cfg.selected;\n\t\tthis.edges = cfg.edges;\n\t\tthis.colorize = cfg.colorize;\n\t\tthis.opacity = cfg.opacity;\n\t\tthis.backfaces = cfg.backfaces;\n\t}\n\n\t_meshMatrixDirty(mesh) {\n\t\tthis._meshesWithDirtyMatrices[this._numMeshesWithDirtyMatrices++] = mesh;\n\t}\n\n\t_createDefaultTextureSet() {\n\t\t// Every SceneModelMesh gets at least the default TextureSet,\n\t\t// which contains empty default textures filled with color\n\t\tconst defaultColorTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n\t\t\tid: DEFAULT_COLOR_TEXTURE_ID,\n\t\t\ttexture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n\t\t\t\tgl: this.scene.canvas.gl,\n\t\t\t\tpreloadColor: [1, 1, 1, 1] // [r, g, b, a]})\n\t\t\t})\n\t\t});\n\t\tconst defaultMetalRoughTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n\t\t\tid: DEFAULT_METAL_ROUGH_TEXTURE_ID,\n\t\t\ttexture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n\t\t\t\tgl: this.scene.canvas.gl,\n\t\t\t\tpreloadColor: [0, 1, 1, 1] // [unused, roughness, metalness, unused]\n\t\t\t})\n\t\t});\n\t\tconst defaultNormalsTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n\t\t\tid: DEFAULT_NORMALS_TEXTURE_ID,\n\t\t\ttexture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n\t\t\t\tgl: this.scene.canvas.gl,\n\t\t\t\tpreloadColor: [0, 0, 0, 0] // [x, y, z, unused] - these must be zeros\n\t\t\t})\n\t\t});\n\t\tconst defaultEmissiveTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n\t\t\tid: DEFAULT_EMISSIVE_TEXTURE_ID,\n\t\t\ttexture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n\t\t\t\tgl: this.scene.canvas.gl,\n\t\t\t\tpreloadColor: [0, 0, 0, 1] // [x, y, z, unused]\n\t\t\t})\n\t\t});\n\t\tconst defaultOcclusionTexture = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({\n\t\t\tid: DEFAULT_OCCLUSION_TEXTURE_ID,\n\t\t\ttexture: new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n\t\t\t\tgl: this.scene.canvas.gl,\n\t\t\t\tpreloadColor: [1, 1, 1, 1] // [x, y, z, unused]\n\t\t\t})\n\t\t});\n\t\tthis._textures[DEFAULT_COLOR_TEXTURE_ID] = defaultColorTexture;\n\t\tthis._textures[DEFAULT_METAL_ROUGH_TEXTURE_ID] = defaultMetalRoughTexture;\n\t\tthis._textures[DEFAULT_NORMALS_TEXTURE_ID] = defaultNormalsTexture;\n\t\tthis._textures[DEFAULT_EMISSIVE_TEXTURE_ID] = defaultEmissiveTexture;\n\t\tthis._textures[DEFAULT_OCCLUSION_TEXTURE_ID] = defaultOcclusionTexture;\n\t\tthis._textureSets[DEFAULT_TEXTURE_SET_ID] = new _SceneModelTextureSet_js__WEBPACK_IMPORTED_MODULE_16__.SceneModelTextureSet({\n\t\t\tid: DEFAULT_TEXTURE_SET_ID,\n\t\t\tmodel: this,\n\t\t\tcolorTexture: defaultColorTexture,\n\t\t\tmetallicRoughnessTexture: defaultMetalRoughTexture,\n\t\t\tnormalsTexture: defaultNormalsTexture,\n\t\t\temissiveTexture: defaultEmissiveTexture,\n\t\t\tocclusionTexture: defaultOcclusionTexture\n\t\t});\n\t}\n\n\t//------------------------------------------------------------------------------------------------------------------\n\t// SceneModel members\n\t//------------------------------------------------------------------------------------------------------------------\n\n\t/**\n\t * Returns true to indicate that this Component is a SceneModel.\n\t * @type {Boolean}\n\t */\n\tget isPerformanceModel() {\n\t\treturn true;\n\t}\n\n\t/**\n\t * The {@link SceneModelTransform}s in this SceneModel.\n\t *\n\t * Each {#link SceneModelTransform} is stored here against its {@link SceneModelTransform.id}.\n\t *\n\t * @returns {*|{}}\n\t */\n\tget transforms() {\n\t\treturn this._transforms;\n\t}\n\n\t/**\n\t * The {@link SceneModelTexture}s in this SceneModel.\n\t *\n\t * * Each {@link SceneModelTexture} is created with {@link SceneModel.createTexture}.\n\t * * Each {@link SceneModelTexture} is stored here against its {@link SceneModelTexture.id}.\n\t *\n\t * @returns {*|{}}\n\t */\n\tget textures() {\n\t\treturn this._textures;\n\t}\n\n\t/**\n\t * The {@link SceneModelTextureSet}s in this SceneModel.\n\t *\n\t * Each {@link SceneModelTextureSet} is stored here against its {@link SceneModelTextureSet.id}.\n\t *\n\t * @returns {*|{}}\n\t */\n\tget textureSets() {\n\t\treturn this._textureSets;\n\t}\n\n\t/**\n\t * The {@link SceneModelMesh}es in this SceneModel.\n\t *\n\t * Each {@SceneModelMesh} is stored here against its {@link SceneModelMesh.id}.\n\t *\n\t * @returns {*|{}}\n\t */\n\tget meshes() {\n\t\treturn this._meshes;\n\t}\n\n\t/**\n\t * The {@link SceneModelEntity}s in this SceneModel.\n\t *\n\t * Each {#link SceneModelEntity} in this SceneModel that represents an object is\n\t * stored here against its {@link SceneModelTransform.id}.\n\t *\n\t * @returns {*|{}}\n\t */\n\tget objects() {\n\t\treturn this._entities;\n\t}\n\n\t/**\n\t * Gets the 3D World-space origin for this SceneModel.\n\t *\n\t * Each {@link SceneModelMesh.origin}, if supplied, is relative to this origin.\n\t *\n\t * Default value is ````[0,0,0]````.\n\t *\n\t * @type {Float64Array}\n\t */\n\tget origin() {\n\t\treturn this._origin;\n\t}\n\n\t/**\n\t * Sets the SceneModel's local translation.\n\t *\n\t * Default value is ````[0,0,0]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tset position(value) {\n\t\tthis._position.set(value || [0, 0, 0]);\n\t\tthis._setWorldMatrixDirty();\n\t\tthis._sceneModelDirty();\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the SceneModel's local translation.\n\t *\n\t * Default value is ````[0,0,0]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget position() {\n\t\treturn this._position;\n\t}\n\n\t/**\n\t * Sets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n\t *\n\t * Default value is ````[0,0,0]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tset rotation(value) {\n\t\tthis._rotation.set(value || [0, 0, 0]);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n\t\tthis._setWorldMatrixDirty();\n\t\tthis._sceneModelDirty();\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n\t *\n\t * Default value is ````[0,0,0]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget rotation() {\n\t\treturn this._rotation;\n\t}\n\n\t/**\n\t * Sets the SceneModel's local rotation quaternion.\n\t *\n\t * Default value is ````[0,0,0,1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tset quaternion(value) {\n\t\tthis._quaternion.set(value || [0, 0, 0, 1]);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToEuler(this._quaternion, \"XYZ\", this._rotation);\n\t\tthis._setWorldMatrixDirty();\n\t\tthis._sceneModelDirty();\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the SceneModel's local rotation quaternion.\n\t *\n\t * Default value is ````[0,0,0,1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget quaternion() {\n\t\treturn this._quaternion;\n\t}\n\n\t/**\n\t * Sets the SceneModel's local scale.\n\t *\n\t * Default value is ````[1,1,1]````.\n\t *\n\t * @type {Number[]}\n\t * @deprecated\n\t */\n\tset scale(value) {\n\t\t// NOP - deprecated\n\t}\n\n\t/**\n\t * Gets the SceneModel's local scale.\n\t *\n\t * Default value is ````[1,1,1]````.\n\t *\n\t * @type {Number[]}\n\t * @deprecated\n\t */\n\tget scale() {\n\t\treturn this._scale;\n\t}\n\n\t/**\n\t * Sets the SceneModel's local modeling transform matrix.\n\t *\n\t * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tset matrix(value) {\n\t\tthis._matrix.set(value || DEFAULT_MATRIX);\n\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrix);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.conjugateQuaternion(this._quaternion, this._conjugateQuaternion);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrixConjugate);\n\t\tthis._matrix.set(this._worldRotationMatrix);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.translateMat4v(this._position, this._matrix);\n\n\t\tthis._matrixDirty = false;\n\t\tthis._setWorldMatrixDirty();\n\t\tthis._sceneModelDirty();\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the SceneModel's local modeling transform matrix.\n\t *\n\t * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget matrix() {\n\t\tif (this._matrixDirty) {\n\t\t\tthis._rebuildMatrices();\n\t\t}\n\t\treturn this._matrix;\n\t}\n\n\t/**\n\t * Gets the SceneModel's local modeling rotation transform matrix.\n\t *\n\t * @type {Number[]}\n\t */\n\tget rotationMatrix() {\n\t\tif (this._matrixDirty) {\n\t\t\tthis._rebuildMatrices();\n\t\t}\n\t\treturn this._worldRotationMatrix;\n\t}\n\n\t_rebuildMatrices() {\n\t\tif (this._matrixDirty) {\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrix);\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.conjugateQuaternion(this._quaternion, this._conjugateQuaternion);\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrixConjugate);\n\t\t\tthis._matrix.set(this._worldRotationMatrix);\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.translateMat4v(this._position, this._matrix);\n\t\t\tthis._matrixDirty = false;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the conjugate of the SceneModel's local modeling rotation transform matrix.\n\t *\n\t * This is used for RTC view matrix management in renderers.\n\t *\n\t * @type {Number[]}\n\t */\n\tget rotationMatrixConjugate() {\n\t\tif (this._matrixDirty) {\n\t\t\tthis._rebuildMatrices();\n\t\t}\n\t\treturn this._worldRotationMatrixConjugate;\n\t}\n\n\t_setWorldMatrixDirty() {\n\t\tthis._matrixDirty = true;\n\t\tthis._aabbDirty = true;\n\t}\n\n\t_transformDirty() {\n\t\tthis._matrixDirty = true;\n\t\tthis._aabbDirty = true;\n\t\tthis.scene._aabbDirty = true;\n\t}\n\n\t_sceneModelDirty() {\n\t\tthis.scene._aabbDirty = true;\n\t\tthis._aabbDirty = true;\n\t\tthis.scene._aabbDirty = true;\n\t\tthis._matrixDirty = true;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i]._sceneModelDirty(); // Entities need to retransform their World AABBs by SceneModel's worldMatrix\n\t\t}\n\t}\n\n\t/**\n\t * Gets the SceneModel's World matrix.\n\t *\n\t * @property worldMatrix\n\t * @type {Number[]}\n\t */\n\tget worldMatrix() {\n\t\treturn this.matrix;\n\t}\n\n\t/**\n\t * Gets the SceneModel's World normal matrix.\n\t *\n\t * @type {Number[]}\n\t */\n\tget worldNormalMatrix() {\n\t\treturn this._worldNormalMatrix;\n\t}\n\n\t/**\n\t * Called by private renderers in ./lib, returns the view matrix with which to\n\t * render this SceneModel. The view matrix is the concatenation of the\n\t * Camera view matrix with the Performance model's world (modeling) matrix.\n\t *\n\t * @private\n\t */\n\tget viewMatrix() {\n\t\tif (!this._viewMatrix) {\n\t\t\treturn this.scene.camera.viewMatrix;\n\t\t}\n\t\tif (this._matrixDirty) {\n\t\t\tthis._rebuildMatrices();\n\t\t\tthis._viewMatrixDirty = true;\n\t\t}\n\t\tif (this._viewMatrixDirty) {\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulMat4(this.scene.camera.viewMatrix, this._matrix, this._viewMatrix);\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transposeMat4(this._viewNormalMatrix);\n\t\t\tthis._viewMatrixDirty = false;\n\t\t}\n\t\treturn this._viewMatrix;\n\t}\n\n\t/**\n\t * Called by private renderers in ./lib, returns the view normal matrix with which to render this SceneModel.\n\t *\n\t * @private\n\t */\n\tget viewNormalMatrix() {\n\t\tif (!this._viewNormalMatrix) {\n\t\t\treturn this.scene.camera.viewNormalMatrix;\n\t\t}\n\t\tif (this._matrixDirty) {\n\t\t\tthis._rebuildMatrices();\n\t\t\tthis._viewMatrixDirty = true;\n\t\t}\n\t\tif (this._viewMatrixDirty) {\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulMat4(this.scene.camera.viewMatrix, this._matrix, this._viewMatrix);\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transposeMat4(this._viewNormalMatrix);\n\t\t\tthis._viewMatrixDirty = false;\n\t\t}\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transposeMat4(this._viewNormalMatrix);\n\t\treturn this._viewNormalMatrix;\n\t}\n\n\t/**\n\t * Sets if backfaces are rendered for this SceneModel.\n\t *\n\t * Default is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget backfaces() {\n\t\treturn this._backfaces;\n\t}\n\n\t/**\n\t * Sets if backfaces are rendered for this SceneModel.\n\t *\n\t * Default is ````false````.\n\t *\n\t * When we set this ````true````, then backfaces are always rendered for this SceneModel.\n\t *\n\t * When we set this ````false````, then we allow the Viewer to decide whether to render backfaces. In this case,\n\t * the Viewer will:\n\t *\n\t * * hide backfaces on watertight meshes,\n\t * * show backfaces on open meshes, and\n\t * * always show backfaces on meshes when we slice them open with {@link SectionPlane}s.\n\t *\n\t * @type {Boolean}\n\t */\n\tset backfaces(backfaces) {\n\t\tbackfaces = !!backfaces;\n\t\tthis._backfaces = backfaces;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the list of {@link SceneModelEntity}s within this SceneModel.\n\t *\n\t * @returns {SceneModelEntity[]}\n\t */\n\tget entityList() {\n\t\treturn this._entityList;\n\t}\n\n\t/**\n\t * Returns true to indicate that SceneModel is an {@link Entity}.\n\t * @type {Boolean}\n\t */\n\tget isEntity() {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns ````true```` if this SceneModel represents a model.\n\t *\n\t * When ````true```` the SceneModel will be registered by {@link SceneModel#id} in\n\t * {@link Scene#models} and may also have a {@link MetaObject} with matching {@link MetaObject#id}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isModel() {\n\t\treturn this._isModel;\n\t}\n\n\t//------------------------------------------------------------------------------------------------------------------\n\t// SceneModel members\n\t//------------------------------------------------------------------------------------------------------------------\n\n\t/**\n\t * Returns ````false```` to indicate that SceneModel never represents an object.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isObject() {\n\t\treturn false;\n\t}\n\n\t/**\n\t * Gets the SceneModel's World-space 3D axis-aligned bounding box.\n\t *\n\t * Represented by a six-element Float64Array containing the min/max extents of the\n\t * axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget aabb() {\n\t\tif (this._aabbDirty) {\n\t\t\tif (this._aabbUpdate) {\n\t\t\t\treturn this._aabb;\n\t\t\t}\n\t\t\tif (this._exceptionIds.length > 0) this.updateAABBCullException(this._exceptionIds);\n\t\t\telse {\n\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3(this._aabb);\n\t\t\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3(this._aabb, this._entityList[i].aabb);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._aabbDirty = false;\n\t\t}\n\t\treturn this._aabb;\n\t}\n\n\tupdateAABBCullException(exceptionIds, callback) {\n\t\tfunction noExceptionId(id) {\n\t\t\tlet noExceptionId = true;\n\t\t\texceptionIds.forEach((exceptionId) => {\n\t\t\t\tif (exceptionId === id) {\n\t\t\t\t\tnoExceptionId = false;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn noExceptionId;\n\t\t}\n\t\tconst newAABB = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tif (noExceptionId(this._entityList[i].id)) {\n\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3(newAABB, this._entityList[i].aabb);\n\t\t\t}\n\t\t}\n\n\t\tfor (let a = 0; a < newAABB.length; a++) {\n\t\t\tthis._aabb[a] = newAABB[a];\n\t\t}\n\t\tthis._aabbDirty = false;\n\t\tthis._aabbUpdate = true;\n\t\tthis.scene._setAABBDirty();\n\t\tthis.scene._aabbUpdate = true;\n\t\tif (typeof callback === \"function\") callback();\n\t}\n\n\tcancelCullException(callback) {\n\t\tthis._exceptionIds = [];\n\t\tthis._aabbDirty = true;\n\t\tthis._aabbUpdate = false;\n\t\tthis.aabb;\n\t\tthis.scene._aabbUpdate = false;\n\t\tthis.scene._setAABBDirty();\n\t\tif (typeof callback === \"function\") callback();\n\t}\n\n\t/**\n\t * 获取所有实体的aabb\n\t */\n\tget aabbs() {\n\t\tlet aabbArray = [];\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\taabbArray.push(this._entityList[i].aabb);\n\t\t}\n\t\treturn aabbArray;\n\t}\n\n\t/**\n\t * The approximate number of triangle primitives in this SceneModel.\n\t *\n\t * @type {Number}\n\t */\n\tget numTriangles() {\n\t\treturn this._numTriangles;\n\t}\n\n\t//------------------------------------------------------------------------------------------------------------------\n\t// Entity members\n\t//------------------------------------------------------------------------------------------------------------------\n\n\t/**\n\t * The approximate number of line primitives in this SceneModel.\n\t *\n\t * @type {Number}\n\t */\n\tget numLines() {\n\t\treturn this._numLines;\n\t}\n\n\t/**\n\t * The approximate number of point primitives in this SceneModel.\n\t *\n\t * @type {Number}\n\t */\n\tget numPoints() {\n\t\treturn this._numPoints;\n\t}\n\n\t/**\n\t * Gets if any {@link SceneModelEntity}s in this SceneModel are visible.\n\t *\n\t * The SceneModel is only rendered when {@link SceneModel#visible} is ````true```` and {@link SceneModel#culled} is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget visible() {\n\t\treturn this.numVisibleLayerPortions > 0;\n\t}\n\n\t/**\n\t * Sets if this SceneModel is visible.\n\t *\n\t * The SceneModel is only rendered when {@link SceneModel#visible} is ````true```` and {@link SceneModel#culled} is ````false````.\n\t **\n\t * @type {Boolean}\n\t */\n\tset visible(visible) {\n\t\tvisible = visible !== false;\n\t\tthis._visible = visible;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].visible = visible;\n\t\t}\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets if any {@link SceneModelEntity}s in this SceneModel are xrayed.\n\t *\n\t * @type {Boolean}\n\t */\n\tget xrayed() {\n\t\treturn this.numXRayedLayerPortions > 0;\n\t}\n\n\t/**\n\t * Sets if all {@link SceneModelEntity}s in this SceneModel are xrayed.\n\t *\n\t * @type {Boolean}\n\t */\n\tset xrayed(xrayed) {\n\t\txrayed = !!xrayed;\n\t\tthis._xrayed = xrayed;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].xrayed = xrayed;\n\t\t}\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets if any {@link SceneModelEntity}s in this SceneModel are highlighted.\n\t *\n\t * @type {Boolean}\n\t */\n\tget highlighted() {\n\t\treturn this.numHighlightedLayerPortions > 0;\n\t}\n\n\t/**\n\t * Sets if all {@link SceneModelEntity}s in this SceneModel are highlighted.\n\t *\n\t * @type {Boolean}\n\t */\n\tset highlighted(highlighted) {\n\t\thighlighted = !!highlighted;\n\t\tthis._highlighted = highlighted;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].highlighted = highlighted;\n\t\t}\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets if any {@link SceneModelEntity}s in this SceneModel are selected.\n\t *\n\t * @type {Boolean}\n\t */\n\tget selected() {\n\t\treturn this.numSelectedLayerPortions > 0;\n\t}\n\n\t/**\n\t * Sets if all {@link SceneModelEntity}s in this SceneModel are selected.\n\t *\n\t * @type {Boolean}\n\t */\n\tset selected(selected) {\n\t\tselected = !!selected;\n\t\tthis._selected = selected;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].selected = selected;\n\t\t}\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets if any {@link SceneModelEntity}s in this SceneModel have edges emphasised.\n\t *\n\t * @type {Boolean}\n\t */\n\tget edges() {\n\t\treturn this.numEdgesLayerPortions > 0;\n\t}\n\n\t/**\n\t * Sets if all {@link SceneModelEntity}s in this SceneModel have edges emphasised.\n\t *\n\t * @type {Boolean}\n\t */\n\tset edges(edges) {\n\t\tedges = !!edges;\n\t\tthis._edges = edges;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].edges = edges;\n\t\t}\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets if this SceneModel is culled from view.\n\t *\n\t * The SceneModel is only rendered when {@link SceneModel#visible} is true and {@link SceneModel#culled} is false.\n\t *\n\t * @type {Boolean}\n\t */\n\tget culled() {\n\t\treturn this._culled;\n\t}\n\n\t/**\n\t * Sets if this SceneModel is culled from view.\n\t *\n\t * The SceneModel is only rendered when {@link SceneModel#visible} is true and {@link SceneModel#culled} is false.\n\t *\n\t * @type {Boolean}\n\t */\n\tset culled(culled) {\n\t\tculled = !!culled;\n\t\tthis._culled = culled;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].culled = culled;\n\t\t}\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets if {@link SceneModelEntity}s in this SceneModel are clippable.\n\t *\n\t * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget clippable() {\n\t\treturn this._clippable;\n\t}\n\n\t/**\n\t * Sets if {@link SceneModelEntity}s in this SceneModel are clippable.\n\t *\n\t * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n\t *\n\t * @type {Boolean}\n\t */\n\tset clippable(clippable) {\n\t\tclippable = clippable !== false;\n\t\tthis._clippable = clippable;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].clippable = clippable;\n\t\t}\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets if this SceneModel is collidable.\n\t *\n\t * @type {Boolean}\n\t */\n\tget collidable() {\n\t\treturn this._collidable;\n\t}\n\n\t/**\n\t * Sets if {@link SceneModelEntity}s in this SceneModel are collidable.\n\t *\n\t * @type {Boolean}\n\t */\n\tset collidable(collidable) {\n\t\tcollidable = collidable !== false;\n\t\tthis._collidable = collidable;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].collidable = collidable;\n\t\t}\n\t}\n\n\t/**\n\t * Gets if this SceneModel is pickable.\n\t *\n\t * Picking is done via calls to {@link Scene#pick}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget pickable() {\n\t\treturn this.numPickableLayerPortions > 0;\n\t}\n\n\t/**\n\t * Sets if {@link SceneModelEntity}s in this SceneModel are pickable.\n\t *\n\t * Picking is done via calls to {@link Scene#pick}.\n\t *\n\t * @type {Boolean}\n\t */\n\tset pickable(pickable) {\n\t\tpickable = pickable !== false;\n\t\tthis._pickable = pickable;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].pickable = pickable;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the RGB colorize color for this SceneModel.\n\t *\n\t * Each element of the color is in range ````[0..1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget colorize() {\n\t\treturn this._colorize;\n\t}\n\n\t/**\n\t * Sets the RGB colorize color for this SceneModel.\n\t *\n\t * Multiplies by rendered fragment colors.\n\t *\n\t * Each element of the color is in range ````[0..1]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tset colorize(colorize) {\n\t\tthis._colorize = colorize;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].colorize = colorize;\n\t\t}\n\t}\n\n\t/**\n\t * Gets this SceneModel's opacity factor.\n\t *\n\t * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n\t *\n\t * @type {Number}\n\t */\n\tget opacity() {\n\t\treturn this._opacity;\n\t}\n\n\t/**\n\t * Sets the opacity factor for this SceneModel.\n\t *\n\t * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n\t *\n\t * @type {Number}\n\t */\n\tset opacity(opacity) {\n\t\tthis._opacity = opacity;\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i].opacity = opacity;\n\t\t}\n\t}\n\n\t/**\n\t * Gets if this SceneModel casts a shadow.\n\t *\n\t * @type {Boolean}\n\t */\n\tget castsShadow() {\n\t\treturn this._castsShadow;\n\t}\n\n\t/**\n\t * Sets if this SceneModel casts a shadow.\n\t *\n\t * @type {Boolean}\n\t */\n\tset castsShadow(castsShadow) {\n\t\tcastsShadow = castsShadow !== false;\n\t\tif (castsShadow !== this._castsShadow) {\n\t\t\tthis._castsShadow = castsShadow;\n\t\t\tthis.glRedraw();\n\t\t}\n\t}\n\n\t/**\n\t * Sets if this SceneModel can have shadow cast upon it.\n\t *\n\t * @type {Boolean}\n\t */\n\tget receivesShadow() {\n\t\treturn this._receivesShadow;\n\t}\n\n\t/**\n\t * Sets if this SceneModel can have shadow cast upon it.\n\t *\n\t * @type {Boolean}\n\t */\n\tset receivesShadow(receivesShadow) {\n\t\treceivesShadow = receivesShadow !== false;\n\t\tif (receivesShadow !== this._receivesShadow) {\n\t\t\tthis._receivesShadow = receivesShadow;\n\t\t\tthis.glRedraw();\n\t\t}\n\t}\n\n\t/**\n\t * Gets if Scalable Ambient Obscurance (SAO) will apply to this SceneModel.\n\t *\n\t * SAO is configured by the Scene's {@link SAO} component.\n\t *\n\t * Only works when {@link SAO#enabled} is also true.\n\t *\n\t * @type {Boolean}\n\t */\n\tget saoEnabled() {\n\t\treturn this._saoEnabled;\n\t}\n\n\t/**\n\t * Gets if physically-based rendering (PBR) is enabled for this SceneModel.\n\t *\n\t * Only works when {@link Scene#pbrEnabled} is also true.\n\t *\n\t * @type {Boolean}\n\t */\n\tget pbrEnabled() {\n\t\treturn this._pbrEnabled;\n\t}\n\n\t/**\n\t * Gets if color textures are enabled for this SceneModel.\n\t *\n\t * Only works when {@link Scene#colorTextureEnabled} is also true.\n\t *\n\t * @type {Boolean}\n\t */\n\tget colorTextureEnabled() {\n\t\treturn this._colorTextureEnabled;\n\t}\n\n\t/**\n\t * Returns true to indicate that SceneModel is implements {@link Drawable}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isDrawable() {\n\t\treturn true;\n\t}\n\n\t/** @private */\n\tget isStateSortable() {\n\t\treturn false;\n\t}\n\n\t/**\n\t * Configures the appearance of xrayed {@link SceneModelEntity}s within this SceneModel.\n\t *\n\t * This is the {@link Scene#xrayMaterial}.\n\t *\n\t * @type {EmphasisMaterial}\n\t */\n\tget xrayMaterial() {\n\t\treturn this.scene.xrayMaterial;\n\t}\n\n\t/**\n\t * Configures the appearance of highlighted {@link SceneModelEntity}s within this SceneModel.\n\t *\n\t * This is the {@link Scene#highlightMaterial}.\n\t *\n\t * @type {EmphasisMaterial}\n\t */\n\tget highlightMaterial() {\n\t\treturn this.scene.highlightMaterial;\n\t}\n\n\t/**\n\t * Configures the appearance of selected {@link SceneModelEntity}s within this SceneModel.\n\t *\n\t * This is the {@link Scene#selectedMaterial}.\n\t *\n\t * @type {EmphasisMaterial}\n\t */\n\tget selectedMaterial() {\n\t\treturn this.scene.selectedMaterial;\n\t}\n\n\t/**\n\t * Configures the appearance of edges of {@link SceneModelEntity}s within this SceneModel.\n\t *\n\t * This is the {@link Scene#edgeMaterial}.\n\t *\n\t * @type {EdgeMaterial}\n\t */\n\tget edgeMaterial() {\n\t\treturn this.scene.edgeMaterial;\n\t}\n\n\t//------------------------------------------------------------------------------------------------------------------\n\t// Drawable members\n\t//------------------------------------------------------------------------------------------------------------------\n\n\t/**\n\t * Called by private renderers in ./lib, returns the picking view matrix with which to\n\t * ray-pick on this SceneModel.\n\t *\n\t * @private\n\t */\n\tgetPickViewMatrix(pickViewMatrix) {\n\t\tif (!this._viewMatrix) {\n\t\t\treturn pickViewMatrix;\n\t\t}\n\t\treturn this._viewMatrix;\n\t}\n\n\t/**\n\t *\n\t * @param cfg\n\t */\n\tcreateQuantizationRange(cfg) {\n\t\tif (cfg.id === undefined || cfg.id === null) {\n\t\t\tthis.error(\"[createQuantizationRange] Config missing: id\");\n\t\t\treturn;\n\t\t}\n\t\tif (cfg.aabb) {\n\t\t\tthis.error(\"[createQuantizationRange] Config missing: aabb\");\n\t\t\treturn;\n\t\t}\n\t\tif (this._quantizationRanges[cfg.id]) {\n\t\t\tthis.error(\"[createQuantizationRange] QuantizationRange already created: \" + cfg.id);\n\t\t\treturn;\n\t\t}\n\t\tthis._quantizationRanges[cfg.id] = {\n\t\t\tid: cfg.id,\n\t\t\taabb: cfg.aabb,\n\t\t\tmatrix: (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.createPositionsDecodeMatrix)(cfg.aabb, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4())\n\t\t};\n\t}\n\n\t/**\n\t * Creates a reusable geometry within this SceneModel.\n\t *\n\t * We can then supply the geometry ID to {@link SceneModel#createMesh} when we want to create meshes that\n\t * instance the geometry.\n\t *\n\t * @param {*} cfg Geometry properties.\n\t * @param {String|Number} cfg.id Mandatory ID for the geometry, to refer to with {@link SceneModel#createMesh}.\n\t * @param {String} cfg.primitive The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'.\n\t * @param {Number[]} [cfg.positions] Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by ````positionsCompressed````.\n\t * @param {Number[]} [cfg.positionsCompressed] Flat array of quantized 3D vertex positions. Overrides ````positions````, and must be accompanied by ````positionsDecodeMatrix````.\n\t * @param {Number[]} [cfg.positionsDecodeMatrix] A 4x4 matrix for decompressing ````positionsCompressed````. Must be accompanied by ````positionsCompressed````.\n\t * @param {Number[]} [cfg.normals] Flat array of normal vectors. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n\t * @param {Number[]} [cfg.normalsCompressed] Flat array of oct-encoded normal vectors. Overrides ````normals````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n\t * @param {Number[]} [cfg.colors] Flat array of uncompressed RGBA vertex colors, as float values in range ````[0..1]````. Ignored when ````geometryId```` is given. Overridden by ````color```` and ````colorsCompressed````.\n\t * @param {Number[]} [cfg.colorsCompressed] Flat array of compressed RGBA vertex colors, as unsigned short integers in range ````[0..255]````. Ignored when ````geometryId```` is given. Overrides ````colors```` and is overridden by ````color````.\n\t * @param {Number[]} [cfg.uv] Flat array of uncompressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n\t * @param {Number[]} [cfg.uvCompressed] Flat array of compressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Overrides ````uv````. Must be accompanied by ````uvDecodeMatrix````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n\t * @param {Number[]} [cfg.uvDecodeMatrix] A 3x3 matrix for decompressing ````uvCompressed````.\n\t * @param {Number[]} [cfg.indices] Array of primitive connectivity indices. Not required for `points` primitives.\n\t * @param {Number[]} [cfg.edgeIndices] Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional ````edgeThreshold```` given to the ````SceneModel```` constructor.\n\t */\n\tcreateGeometry(cfg) {\n\t\tif (cfg.id === undefined || cfg.id === null) {\n\t\t\tthis.error(\"[createGeometry] Config missing: id\");\n\t\t\treturn;\n\t\t}\n\t\tif (this._geometries[cfg.id]) {\n\t\t\tthis.error(\"[createGeometry] Geometry already created: \" + cfg.id);\n\t\t\treturn;\n\t\t}\n\t\tif (cfg.primitive === undefined || cfg.primitive === null) {\n\t\t\tcfg.primitive = \"triangles\";\n\t\t}\n\t\tif (\n\t\t\tcfg.primitive !== \"points\" &&\n\t\t\tcfg.primitive !== \"lines\" &&\n\t\t\tcfg.primitive !== \"triangles\" &&\n\t\t\tcfg.primitive !== \"solid\" &&\n\t\t\tcfg.primitive !== \"surface\"\n\t\t) {\n\t\t\tthis.error(\n\t\t\t\t`[createGeometry] Unsupported value for 'primitive': '${cfg.primitive}' - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'. Defaulting to 'triangles'.`\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (!cfg.positions && !cfg.positionsCompressed && !cfg.buckets) {\n\t\t\tthis.error(\"[createGeometry] Param expected: `positions`, `positionsCompressed' or 'buckets\");\n\t\t\treturn null;\n\t\t}\n\t\tif (cfg.positionsCompressed && !cfg.positionsDecodeMatrix && !cfg.positionsDecodeBoundary) {\n\t\t\tthis.error(\n\t\t\t\t\"[createGeometry] Param expected: `positionsDecodeMatrix` or 'positionsDecodeBoundary' (required for `positionsCompressed')\"\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\t\tif (cfg.positionsDecodeMatrix && cfg.positionsDecodeBoundary) {\n\t\t\tthis.error(\n\t\t\t\t\"[createGeometry] Only one of these params expected: `positionsDecodeMatrix` or 'positionsDecodeBoundary' (required for `positionsCompressed')\"\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\t\tif (cfg.uvCompressed && !cfg.uvDecodeMatrix) {\n\t\t\tthis.error(\"[createGeometry] Param expected: `uvDecodeMatrix` (required for `uvCompressed')\");\n\t\t\treturn null;\n\t\t}\n\t\tif (!cfg.buckets && !cfg.indices && cfg.primitive !== \"points\") {\n\t\t\tthis.error(`[createGeometry] Param expected: indices (required for '${cfg.primitive}' primitive type)`);\n\t\t\treturn null;\n\t\t}\n\t\tif (cfg.positionsDecodeBoundary) {\n\t\t\tcfg.positionsDecodeMatrix = (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.createPositionsDecodeMatrix)(cfg.positionsDecodeBoundary, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4());\n\t\t}\n\t\tif (cfg.positions) {\n\t\t\tconst aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t\tcfg.positionsDecodeMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positions);\n\t\t\tcfg.positionsCompressed = (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.quantizePositions)(cfg.positions, aabb, cfg.positionsDecodeMatrix);\n\t\t\tcfg.aabb = aabb;\n\t\t} else if (cfg.positionsCompressed) {\n\t\t\tconst aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t\tcfg.positionsDecodeMatrix = new Float64Array(cfg.positionsDecodeMatrix);\n\t\t\tcfg.positionsCompressed = new Uint16Array(cfg.positionsCompressed);\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positionsCompressed);\n\t\t\t_math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n\t\t\tcfg.aabb = aabb;\n\t\t} else if (cfg.buckets) {\n\t\t\tconst aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t\tthis._dtxBuckets[cfg.id] = cfg.buckets;\n\t\t\tfor (let i = 0, len = cfg.buckets.length; i < len; i++) {\n\t\t\t\tconst bucket = cfg.buckets[i];\n\t\t\t\tif (bucket.positions) {\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, bucket.positions);\n\t\t\t\t} else if (bucket.positionsCompressed) {\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, bucket.positionsCompressed);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (cfg.positionsDecodeMatrix) {\n\t\t\t\t_math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n\t\t\t}\n\t\t\tcfg.aabb = aabb;\n\t\t}\n\t\tif (cfg.colorsCompressed && cfg.colorsCompressed.length > 0) {\n\t\t\tcfg.colorsCompressed = new Uint8Array(cfg.colorsCompressed);\n\t\t} else if (cfg.colors && cfg.colors.length > 0) {\n\t\t\tconst colors = cfg.colors;\n\t\t\tconst colorsCompressed = new Uint8Array(colors.length);\n\t\t\tfor (let i = 0, len = colors.length; i < len; i++) {\n\t\t\t\tcolorsCompressed[i] = colors[i] * 255;\n\t\t\t}\n\t\t\tcfg.colorsCompressed = colorsCompressed;\n\t\t}\n\t\tif (\n\t\t\t!cfg.buckets &&\n\t\t\t!cfg.edgeIndices &&\n\t\t\t(cfg.primitive === \"triangles\" || cfg.primitive === \"solid\" || cfg.primitive === \"surface\")\n\t\t) {\n\t\t\tif (cfg.positions) {\n\t\t\t\tcfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positions, cfg.indices, null, 5.0);\n\t\t\t} else {\n\t\t\t\tcfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);\n\t\t\t}\n\t\t}\n\t\tif (cfg.uv) {\n\t\t\tconst bounds = _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.getUVBounds(cfg.uv);\n\t\t\tconst result = _math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.compressUVs(cfg.uv, bounds.min, bounds.max);\n\t\t\tcfg.uvCompressed = result.quantized;\n\t\t\tcfg.uvDecodeMatrix = result.decodeMatrix;\n\t\t} else if (cfg.uvCompressed) {\n\t\t\tcfg.uvCompressed = new Uint16Array(cfg.uvCompressed);\n\t\t\tcfg.uvDecodeMatrix = new Float64Array(cfg.uvDecodeMatrix);\n\t\t}\n\t\tif (cfg.normals) {\n\t\t\t// HACK\n\t\t\tcfg.normals = null;\n\t\t}\n\t\tthis._geometries[cfg.id] = cfg;\n\t\tthis._numTriangles += cfg.indices ? Math.round(cfg.indices.length / 3) : 0;\n\t\tthis.numGeometries++;\n\t}\n\n\t/**\n\t * Creates a texture within this SceneModel.\n\t *\n\t * We can then supply the texture ID to {@link SceneModel#createTextureSet} when we want to create texture sets that use the texture.\n\t *\n\t * @param {*} cfg Texture properties.\n\t * @param {String|Number} cfg.id Mandatory ID for the texture, to refer to with {@link SceneModel#createTextureSet}.\n\t * @param {String} [cfg.src] Image file for the texture. Assumed to be transcoded if not having a recognized image file\n\t * extension (jpg, jpeg, png etc.). If transcoded, then assumes ````SceneModel```` is configured with a {@link TextureTranscoder}.\n\t * @param {ArrayBuffer[]} [cfg.buffers] Transcoded texture data. Assumes ````SceneModel```` is\n\t * configured with a {@link TextureTranscoder}. This parameter is given as an array of buffers so we can potentially support multi-image textures, such as cube maps.\n\t * @param {HTMLImageElement} [cfg.image] HTML Image object to load into this texture. Overrides ````src```` and ````buffers````. Never transcoded.\n\t * @param {Number} [cfg.minFilter=LinearMipmapLinearFilter] How the texture is sampled when a texel covers less than one pixel.\n\t * Supported values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}.\n\t * @param {Number} [cfg.magFilter=LinearFilter] How the texture is sampled when a texel covers more than one pixel. Supported values are {@link LinearFilter} and {@link NearestFilter}.\n\t * @param {Number} [cfg.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n\t * @param {Number} [cfg.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}..\n\t * @param {Number} [cfg.wrapR=RepeatWrapping] Wrap parameter for texture coordinate *R*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n\t * @param {Boolean} [cfg.flipY=false] Flips this Texture's source data along its vertical axis when ````true````.\n\t * @param {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.\n\t */\n\tcreateTexture(cfg) {\n\t\tconst textureId = cfg.id;\n\t\tif (textureId === undefined || textureId === null) {\n\t\t\tthis.error(\"[createTexture] Config missing: id\");\n\t\t\treturn;\n\t\t}\n\t\tif (this._textures[textureId]) {\n\t\t\tthis.error(\"[createTexture] Texture already created: \" + textureId);\n\t\t\treturn;\n\t\t}\n\t\tif (!cfg.src && !cfg.image && !cfg.buffers) {\n\t\t\tthis.error(\"[createTexture] Param expected: `src`, `image' or 'buffers'\");\n\t\t\treturn null;\n\t\t}\n\t\tlet minFilter = cfg.minFilter || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipmapLinearFilter;\n\t\tif (\n\t\t\tminFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearFilter &&\n\t\t\tminFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipMapNearestFilter &&\n\t\t\tminFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipmapLinearFilter &&\n\t\t\tminFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestMipMapLinearFilter &&\n\t\t\tminFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestMipMapNearestFilter\n\t\t) {\n\t\t\tthis.error(`[createTexture] Unsupported value for 'minFilter' - \n supported values are LinearFilter, LinearMipMapNearestFilter, NearestMipMapNearestFilter, \n NearestMipMapLinearFilter and LinearMipmapLinearFilter. Defaulting to LinearMipmapLinearFilter.`);\n\t\t\tminFilter = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearMipmapLinearFilter;\n\t\t}\n\t\tlet magFilter = cfg.magFilter || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearFilter;\n\t\tif (magFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearFilter && magFilter !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.NearestFilter) {\n\t\t\tthis.error(\n\t\t\t\t`[createTexture] Unsupported value for 'magFilter' - supported values are LinearFilter and NearestFilter. Defaulting to LinearFilter.`\n\t\t\t);\n\t\t\tmagFilter = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearFilter;\n\t\t}\n\t\tlet wrapS = cfg.wrapS || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n\t\tif (wrapS !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.ClampToEdgeWrapping && wrapS !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.MirroredRepeatWrapping && wrapS !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping) {\n\t\t\tthis.error(\n\t\t\t\t`[createTexture] Unsupported value for 'wrapS' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`\n\t\t\t);\n\t\t\twrapS = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n\t\t}\n\t\tlet wrapT = cfg.wrapT || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n\t\tif (wrapT !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.ClampToEdgeWrapping && wrapT !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.MirroredRepeatWrapping && wrapT !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping) {\n\t\t\tthis.error(\n\t\t\t\t`[createTexture] Unsupported value for 'wrapT' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`\n\t\t\t);\n\t\t\twrapT = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n\t\t}\n\t\tlet wrapR = cfg.wrapR || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n\t\tif (wrapR !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.ClampToEdgeWrapping && wrapR !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.MirroredRepeatWrapping && wrapR !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping) {\n\t\t\tthis.error(\n\t\t\t\t`[createTexture] Unsupported value for 'wrapR' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`\n\t\t\t);\n\t\t\twrapR = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.RepeatWrapping;\n\t\t}\n\t\tlet encoding = cfg.encoding || _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearEncoding;\n\t\tif (encoding !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearEncoding && encoding !== _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.sRGBEncoding) {\n\t\t\tthis.error(\n\t\t\t\t\"[createTexture] Unsupported value for 'encoding' - supported values are LinearEncoding and sRGBEncoding. Defaulting to LinearEncoding.\"\n\t\t\t);\n\t\t\tencoding = _constants_constants_js__WEBPACK_IMPORTED_MODULE_21__.LinearEncoding;\n\t\t}\n\t\tconst texture = new _webgl_Texture2D_js__WEBPACK_IMPORTED_MODULE_18__.Texture2D({\n\t\t\tgl: this.scene.canvas.gl,\n\t\t\tminFilter,\n\t\t\tmagFilter,\n\t\t\twrapS,\n\t\t\twrapT,\n\t\t\twrapR,\n\t\t\t// flipY: cfg.flipY,\n\t\t\tencoding\n\t\t});\n\t\tif (cfg.preloadColor) {\n\t\t\ttexture.setPreloadColor(cfg.preloadColor);\n\t\t}\n\t\tif (cfg.image) {\n\t\t\t// Ignore transcoder for Images\n\t\t\tconst image = cfg.image;\n\t\t\timage.crossOrigin = \"Anonymous\";\n\t\t\ttexture.setImage(image, { minFilter, magFilter, wrapS, wrapT, wrapR, flipY: cfg.flipY, encoding });\n\t\t} else if (cfg.src) {\n\t\t\tconst ext = cfg.src.split(\".\").pop();\n\t\t\tswitch (\n\t\t\t\text // Don't transcode recognized image file types\n\t\t\t) {\n\t\t\t\tcase \"jpeg\":\n\t\t\t\tcase \"jpg\":\n\t\t\t\tcase \"png\":\n\t\t\t\tcase \"gif\":\n\t\t\t\t\tconst image = new Image();\n\t\t\t\t\timage.onload = () => {\n\t\t\t\t\t\ttexture.setImage(image, {\n\t\t\t\t\t\t\tminFilter,\n\t\t\t\t\t\t\tmagFilter,\n\t\t\t\t\t\t\twrapS,\n\t\t\t\t\t\t\twrapT,\n\t\t\t\t\t\t\twrapR,\n\t\t\t\t\t\t\tflipY: cfg.flipY,\n\t\t\t\t\t\t\tencoding\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthis.glRedraw();\n\t\t\t\t\t};\n\t\t\t\t\timage.src = cfg.src; // URL or Base64 string\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: // Assume other file types need transcoding\n\t\t\t\t\tif (!this._textureTranscoder) {\n\t\t\t\t\t\tthis.error(\n\t\t\t\t\t\t\t`[createTexture] Can't create texture from 'src' - SceneModel needs to be configured with a TextureTranscoder for this file type ('${ext}')`\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t_utils_js__WEBPACK_IMPORTED_MODULE_19__.utils.loadArraybuffer(\n\t\t\t\t\t\t\tcfg.src,\n\t\t\t\t\t\t\t(arrayBuffer) => {\n\t\t\t\t\t\t\t\tif (!arrayBuffer.byteLength) {\n\t\t\t\t\t\t\t\t\tthis.error(`[createTexture] Can't create texture from 'src': file data is zero length`);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis._textureTranscoder.transcode([arrayBuffer], texture).then(() => {\n\t\t\t\t\t\t\t\t\tthis.glRedraw();\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfunction (errMsg) {\n\t\t\t\t\t\t\t\tthis.error(`[createTexture] Can't create texture from 'src': ${errMsg}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if (cfg.buffers) {\n\t\t\t// Buffers implicitly require transcoding\n\t\t\tif (!this._textureTranscoder) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`[createTexture] Can't create texture from 'buffers' - SceneModel needs to be configured with a TextureTranscoder for this option`\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis._textureTranscoder.transcode(cfg.buffers, texture).then(() => {\n\t\t\t\t\tthis.glRedraw();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis._textures[textureId] = new _SceneModelTexture_js__WEBPACK_IMPORTED_MODULE_17__.SceneModelTexture({ id: textureId, texture });\n\t}\n\n\t/**\n\t * Creates a texture set within this SceneModel.\n\t *\n\t * * Stores the new {@link SceneModelTextureSet} in {@link SceneModel#textureSets}.\n\t *\n\t * A texture set is a collection of textures that can be shared among meshes. We can then supply the texture set\n\t * ID to {@link SceneModel#createMesh} when we want to create meshes that use the texture set.\n\t *\n\t * The textures can work as a texture atlas, where each mesh can have geometry UVs that index\n\t * a different part of the textures. This allows us to minimize the number of textures in our models, which\n\t * means faster rendering.\n\t *\n\t * @param {*} cfg Texture set properties.\n\t * @param {String|Number} cfg.id Mandatory ID for the texture set, to refer to with {@link SceneModel#createMesh}.\n\t * @param {*} [cfg.colorTextureId] ID of *RGBA* base color texture, with color in *RGB* and alpha in *A*.\n\t * @param {*} [cfg.metallicRoughnessTextureId] ID of *RGBA* metal-roughness texture, with the metallic factor in *R*, and roughness factor in *G*.\n\t * @param {*} [cfg.normalsTextureId] ID of *RGBA* normal map texture, with normal map vectors in *RGB*.\n\t * @param {*} [cfg.emissiveTextureId] ID of *RGBA* emissive map texture, with emissive color in *RGB*.\n\t * @param {*} [cfg.occlusionTextureId] ID of *RGBA* occlusion map texture, with occlusion factor in *R*.\n\t * @returns {SceneModelTransform} The new texture set.\n\t */\n\tcreateTextureSet(cfg) {\n\t\tconst textureSetId = cfg.id;\n\t\tif (textureSetId === undefined || textureSetId === null) {\n\t\t\tthis.error(\"[createTextureSet] Config missing: id\");\n\t\t\treturn;\n\t\t}\n\t\tif (this._textureSets[textureSetId]) {\n\t\t\tthis.error(`[createTextureSet] Texture set already created: ${textureSetId}`);\n\t\t\treturn;\n\t\t}\n\t\tlet colorTexture;\n\t\tif (cfg.colorTextureId !== undefined && cfg.colorTextureId !== null) {\n\t\t\tcolorTexture = this._textures[cfg.colorTextureId];\n\t\t\tif (!colorTexture) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`[createTextureSet] Texture not found: ${cfg.colorTextureId} - ensure that you create it first with createTexture()`\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tcolorTexture = this._textures[DEFAULT_COLOR_TEXTURE_ID];\n\t\t}\n\t\tlet metallicRoughnessTexture;\n\t\tif (cfg.metallicRoughnessTextureId !== undefined && cfg.metallicRoughnessTextureId !== null) {\n\t\t\tmetallicRoughnessTexture = this._textures[cfg.metallicRoughnessTextureId];\n\t\t\tif (!metallicRoughnessTexture) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`[createTextureSet] Texture not found: ${cfg.metallicRoughnessTextureId} - ensure that you create it first with createTexture()`\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tmetallicRoughnessTexture = this._textures[DEFAULT_METAL_ROUGH_TEXTURE_ID];\n\t\t}\n\t\tlet normalsTexture;\n\t\tif (cfg.normalsTextureId !== undefined && cfg.normalsTextureId !== null) {\n\t\t\tnormalsTexture = this._textures[cfg.normalsTextureId];\n\t\t\tif (!normalsTexture) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`[createTextureSet] Texture not found: ${cfg.normalsTextureId} - ensure that you create it first with createTexture()`\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tnormalsTexture = this._textures[DEFAULT_NORMALS_TEXTURE_ID];\n\t\t}\n\t\tlet emissiveTexture;\n\t\tif (cfg.emissiveTextureId !== undefined && cfg.emissiveTextureId !== null) {\n\t\t\temissiveTexture = this._textures[cfg.emissiveTextureId];\n\t\t\tif (!emissiveTexture) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`[createTextureSet] Texture not found: ${cfg.emissiveTextureId} - ensure that you create it first with createTexture()`\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\temissiveTexture = this._textures[DEFAULT_EMISSIVE_TEXTURE_ID];\n\t\t}\n\t\tlet occlusionTexture;\n\t\tif (cfg.occlusionTextureId !== undefined && cfg.occlusionTextureId !== null) {\n\t\t\tocclusionTexture = this._textures[cfg.occlusionTextureId];\n\t\t\tif (!occlusionTexture) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`[createTextureSet] Texture not found: ${cfg.occlusionTextureId} - ensure that you create it first with createTexture()`\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tocclusionTexture = this._textures[DEFAULT_OCCLUSION_TEXTURE_ID];\n\t\t}\n\t\tconst textureSet = new _SceneModelTextureSet_js__WEBPACK_IMPORTED_MODULE_16__.SceneModelTextureSet({\n\t\t\tid: textureSetId,\n\t\t\tmodel: this,\n\t\t\tcolorTexture,\n\t\t\tmetallicRoughnessTexture,\n\t\t\tnormalsTexture,\n\t\t\temissiveTexture,\n\t\t\tocclusionTexture\n\t\t});\n\t\tthis._textureSets[textureSetId] = textureSet;\n\t\treturn textureSet;\n\t}\n\n\t/**\n\t * Creates a new {@link SceneModelTransform} within this SceneModel.\n\t *\n\t * * Stores the new {@link SceneModelTransform} in {@link SceneModel#transforms}.\n\t * * Can be connected into hierarchies\n\t * * Each {@link SceneModelTransform} can be used by unlimited {@link SceneModelMesh}es\n\t *\n\t * @param {*} cfg Transform creation parameters.\n\t * @param {String} cfg.id Mandatory ID for the new transform. Must not clash with any existing components within the {@link Scene}.\n\t * @param {String} [cfg.parentTransformId] ID of a parent transform, previously created with {@link SceneModel#createTextureSet}.\n\t * @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.\n\t * @param {Number[]} [cfg.scale=[1,1,1]] Scale of the transform.\n\t * @param {Number[]} [cfg.rotation=[0,0,0]] Rotation of the transform as Euler angles given in degrees, for each of the X, Y and Z axis.\n\t * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Modelling transform matrix. Overrides the ````position````, ````scale```` and ````rotation```` parameters.\n\t * @returns {SceneModelTransform} The new transform.\n\t */\n\tcreateTransform(cfg) {\n\t\tif (cfg.id === undefined || cfg.id === null) {\n\t\t\tthis.error(\"[createTransform] SceneModel.createTransform() config missing: id\");\n\t\t\treturn;\n\t\t}\n\t\tif (this._transforms[cfg.id]) {\n\t\t\tthis.error(`[createTransform] SceneModel already has a transform with this ID: ${cfg.id}`);\n\t\t\treturn;\n\t\t}\n\t\tlet parentTransform;\n\t\tif (this.parentTransformId) {\n\t\t\tparentTransform = this._transforms[cfg.parentTransformId];\n\t\t\tif (!parentTransform) {\n\t\t\t\tthis.error(\"[createTransform] SceneModel.createTransform() config missing: id\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tconst transform = new _SceneModelTransform_js__WEBPACK_IMPORTED_MODULE_27__.SceneModelTransform({\n\t\t\tid: cfg.id,\n\t\t\tmodel: this,\n\t\t\tparentTransform,\n\t\t\tmatrix: cfg.matrix,\n\t\t\tposition: cfg.position,\n\t\t\tscale: cfg.scale,\n\t\t\trotation: cfg.rotation,\n\t\t\tquaternion: cfg.quaternion\n\t\t});\n\t\tthis._transforms[transform.id] = transform;\n\t\treturn transform;\n\t}\n\n\t/**\n\t * Creates a new {@link SceneModelMesh} within this SceneModel.\n\t *\n\t * * It prepares and saves data for a SceneModelMesh {@link SceneModel#meshes} creation. SceneModelMesh will be created only once the SceneModelEntity (which references this particular SceneModelMesh) will be created.\n\t * * The SceneModelMesh can either define its own geometry or share it with other SceneModelMeshes. To define own geometry, provide the\n\t * various geometry arrays to this method. To share a geometry, provide the ID of a geometry created earlier\n\t * with {@link SceneModel#createGeometry}.\n\t * * If you accompany the arrays with an ````origin````, then ````createMesh()```` will assume\n\t * that the geometry ````positions```` are in relative-to-center (RTC) coordinates, with ````origin```` being the\n\t * origin of their RTC coordinate system.\n\t *\n\t * @param {object} cfg Object properties.\n\t * @param {String} cfg.id Mandatory ID for the new mesh. Must not clash with any existing components within the {@link Scene}.\n\t * @param {String|Number} [cfg.textureSetId] ID of a {@link SceneModelTextureSet} previously created with {@link SceneModel#createTextureSet}.\n\t * @param {String|Number} [cfg.transformId] ID of a {@link SceneModelTransform} to instance, previously created with {@link SceneModel#createTransform}. Overrides all other transform parameters given to this method.\n\t * @param {String|Number} [cfg.geometryId] ID of a geometry to instance, previously created with {@link SceneModel#createGeometry}. Overrides all other geometry parameters given to this method.\n\t * @param {String} cfg.primitive The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'.\n\t * @param {Number[]} [cfg.positions] Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by ````positionsCompressed````.\n\t * @param {Number[]} [cfg.positionsCompressed] Flat array of quantized 3D vertex positions. Overrides ````positions````, and must be accompanied by ````positionsDecodeMatrix````.\n\t * @param {Number[]} [cfg.positionsDecodeMatrix] A 4x4 matrix for decompressing ````positionsCompressed````. Must be accompanied by ````positionsCompressed````.\n\t * @param {Number[]} [cfg.normals] Flat array of normal vectors. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n\t * @param {Number[]} [cfg.normalsCompressed] Flat array of oct-encoded normal vectors. Overrides ````normals````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n\t * @param {Number[]} [cfg.colors] Flat array of uncompressed RGBA vertex colors, as float values in range ````[0..1]````. Ignored when ````geometryId```` is given. Overridden by ````color```` and ````colorsCompressed````.\n\t * @param {Number[]} [cfg.colorsCompressed] Flat array of compressed RGBA vertex colors, as unsigned short integers in range ````[0..255]````. Ignored when ````geometryId```` is given. Overrides ````colors```` and is overridden by ````color````.\n\t * @param {Number[]} [cfg.uv] Flat array of uncompressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n\t * @param {Number[]} [cfg.uvCompressed] Flat array of compressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Overrides ````uv````. Must be accompanied by ````uvDecodeMatrix````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n\t * @param {Number[]} [cfg.uvDecodeMatrix] A 3x3 matrix for decompressing ````uvCompressed````.\n\t * @param {Number[]} [cfg.indices] Array of primitive connectivity indices. Not required for `points` primitives.\n\t * @param {Number[]} [cfg.edgeIndices] Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional ````edgeThreshold```` given to the ````SceneModel```` constructor.\n\t * @param {Number[]} [cfg.origin] Optional geometry origin, relative to {@link SceneModel#origin}. When this is given, then ````positions```` are assumed to be relative to this.\n\t * @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.\n\t * @param {Number[]} [cfg.scale=[1,1,1]] Scale of the mesh. Overridden by ````transformId````.\n\t * @param {Number[]} [cfg.rotation=[0,0,0]] Rotation of the mesh as Euler angles given in degrees, for each of the X, Y and Z axis. Overridden by ````transformId````.\n\t * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Mesh modelling transform matrix. Overrides the ````position````, ````scale```` and ````rotation```` parameters. Also overridden by ````transformId````.\n\t * @param {Number[]} [cfg.color=[1,1,1]] RGB color in range ````[0..1, 0..1, 0..1]````. Overridden by texture set ````colorTexture````. Overrides ````colors```` and ````colorsCompressed````.\n\t * @param {Number} [cfg.opacity=1] Opacity in range ````[0..1]````. Overridden by texture set ````colorTexture````.\n\t * @param {Number} [cfg.metallic=0] Metallic factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.\n\t * @param {Number} [cfg.roughness=1] Roughness factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.\n\t * @returns {Boolean} True = successfully mesh was created. False = error during creation of a mesh.\n\t */\n\tcreateMesh(cfg) {\n\t\tif (cfg.id === undefined || cfg.id === null) {\n\t\t\tthis.error(\"[createMesh] SceneModel.createMesh() config missing: id\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this._scheduledMeshes[cfg.id]) {\n\t\t\tthis.error(`[createMesh] SceneModel already has a mesh with this ID: ${cfg.id}`);\n\t\t\treturn false;\n\t\t}\n\n\t\tconst instancing = cfg.geometryId !== undefined;\n\t\tconst batching = !instancing;\n\n\t\tif (batching) {\n\t\t\t// Batched geometry\n\n\t\t\tif (cfg.primitive === undefined || cfg.primitive === null) {\n\t\t\t\tcfg.primitive = \"triangles\";\n\t\t\t}\n\t\t\tif (\n\t\t\t\tcfg.primitive !== \"points\" &&\n\t\t\t\tcfg.primitive !== \"lines\" &&\n\t\t\t\tcfg.primitive !== \"triangles\" &&\n\t\t\t\tcfg.primitive !== \"solid\" &&\n\t\t\t\tcfg.primitive !== \"surface\"\n\t\t\t) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`Unsupported value for 'primitive': '${primitive}' ('geometryId' is absent) - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'.`\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!cfg.positions && !cfg.positionsCompressed && !cfg.buckets) {\n\t\t\t\tthis.error(\"Param expected: 'positions', 'positionsCompressed' or `buckets` ('geometryId' is absent)\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (cfg.positions && (cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary)) {\n\t\t\t\tthis.error(\n\t\t\t\t\t\"Illegal params: 'positions' not expected with 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)\"\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (cfg.positionsCompressed && !cfg.positionsDecodeMatrix && !cfg.positionsDecodeBoundary) {\n\t\t\t\tthis.error(\n\t\t\t\t\t\"Param expected: 'positionsCompressed' should be accompanied by 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)\"\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (cfg.uvCompressed && !cfg.uvDecodeMatrix) {\n\t\t\t\tthis.error(\"Param expected: 'uvCompressed' should be accompanied by `uvDecodeMatrix` ('geometryId' is absent)\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!cfg.buckets && !cfg.indices && cfg.primitive !== \"points\") {\n\t\t\t\tthis.error(`Param expected: indices (required for '${cfg.primitive}' primitive type)`);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t(cfg.matrix || cfg.position || cfg.rotation || cfg.scale) &&\n\t\t\t\t(cfg.positionsCompressed || cfg.positionsDecodeBoundary)\n\t\t\t) {\n\t\t\t\tthis.error(\n\t\t\t\t\t\"Unexpected params: 'matrix', 'rotation', 'scale', 'position' not allowed with 'positionsCompressed'\"\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst useDTX =\n\t\t\t\t!!this._dtxEnabled &&\n\t\t\t\t(cfg.primitive === \"triangles\" || cfg.primitive === \"solid\" || cfg.primitive === \"surface\");\n\n\t\t\tcfg.origin = cfg.origin ? _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(this._origin, cfg.origin, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3()) : this._origin;\n\n\t\t\t// MATRIX - optional for batching\n\n\t\t\tif (cfg.matrix) {\n\t\t\t\tcfg.meshMatrix = cfg.matrix;\n\t\t\t} else if (cfg.scale || cfg.rotation || cfg.position) {\n\t\t\t\tconst scale = cfg.scale || DEFAULT_SCALE;\n\t\t\t\tconst position = cfg.position || DEFAULT_POSITION;\n\t\t\t\tconst rotation = cfg.rotation || DEFAULT_ROTATION;\n\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.eulerToQuaternion(rotation, \"XYZ\", DEFAULT_QUATERNION);\n\t\t\t\tcfg.meshMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.composeMat4(position, DEFAULT_QUATERNION, scale, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4());\n\t\t\t}\n\n\t\t\tif (cfg.positionsDecodeBoundary) {\n\t\t\t\tcfg.positionsDecodeMatrix = (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.createPositionsDecodeMatrix)(cfg.positionsDecodeBoundary, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4());\n\t\t\t}\n\n\t\t\tif (useDTX) {\n\t\t\t\t// DTX\n\n\t\t\t\tcfg.type = DTX;\n\n\t\t\t\t// NPR\n\n\t\t\t\tcfg.color = cfg.color\n\t\t\t\t\t? new Uint8Array([\n\t\t\t\t\t\t\tMath.floor(cfg.color[0] * 255),\n\t\t\t\t\t\t\tMath.floor(cfg.color[1] * 255),\n\t\t\t\t\t\t\tMath.floor(cfg.color[2] * 255)\n\t\t\t\t\t ])\n\t\t\t\t\t: defaultCompressedColor;\n\t\t\t\tcfg.opacity = cfg.opacity !== undefined && cfg.opacity !== null ? Math.floor(cfg.opacity * 255) : 255;\n\n\t\t\t\t// RTC\n\n\t\t\t\tif (cfg.positions) {\n\t\t\t\t\tconst rtcCenter = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\t\t\t\t\tconst rtcPositions = [];\n\t\t\t\t\tconst rtcNeeded = (0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_15__.worldToRTCPositions)(cfg.positions, rtcPositions, rtcCenter);\n\t\t\t\t\tif (rtcNeeded) {\n\t\t\t\t\t\tcfg.positions = rtcPositions;\n\t\t\t\t\t\tcfg.origin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(cfg.origin, rtcCenter, rtcCenter);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// COMPRESSION\n\n\t\t\t\tif (cfg.positions) {\n\t\t\t\t\tconst aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t\t\t\tcfg.positionsDecodeMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positions);\n\t\t\t\t\tcfg.positionsCompressed = (0,_compression_js__WEBPACK_IMPORTED_MODULE_22__.quantizePositions)(cfg.positions, aabb, cfg.positionsDecodeMatrix);\n\t\t\t\t\tcfg.aabb = aabb;\n\t\t\t\t} else if (cfg.positionsCompressed) {\n\t\t\t\t\tconst aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positionsCompressed);\n\t\t\t\t\t_math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n\t\t\t\t\tcfg.aabb = aabb;\n\t\t\t\t}\n\t\t\t\tif (cfg.buckets) {\n\t\t\t\t\tconst aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t\t\t\tfor (let i = 0, len = cfg.buckets.length; i < len; i++) {\n\t\t\t\t\t\tconst bucket = cfg.buckets[i];\n\t\t\t\t\t\tif (bucket.positions) {\n\t\t\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, bucket.positions);\n\t\t\t\t\t\t} else if (bucket.positionsCompressed) {\n\t\t\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, bucket.positionsCompressed);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (cfg.positionsDecodeMatrix) {\n\t\t\t\t\t\t_math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n\t\t\t\t\t}\n\t\t\t\t\tcfg.aabb = aabb;\n\t\t\t\t}\n\n\t\t\t\tif (cfg.meshMatrix) {\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(cfg.aabb, tempOBB3);\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformOBB3(cfg.meshMatrix, tempOBB3);\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3ToAABB3(tempOBB3, cfg.aabb);\n\t\t\t\t}\n\n\t\t\t\t// EDGES\n\n\t\t\t\tif (\n\t\t\t\t\t!cfg.buckets &&\n\t\t\t\t\t!cfg.edgeIndices &&\n\t\t\t\t\t(cfg.primitive === \"triangles\" || cfg.primitive === \"solid\" || cfg.primitive === \"surface\")\n\t\t\t\t) {\n\t\t\t\t\tif (cfg.positions) {\n\t\t\t\t\t\t// Faster\n\t\t\t\t\t\tcfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positions, cfg.indices, null, 2.0);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// BUCKETING\n\n\t\t\t\tif (!cfg.buckets) {\n\t\t\t\t\tcfg.buckets = createDTXBuckets(cfg, this._enableVertexWelding && this._enableIndexBucketing);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// VBO\n\n\t\t\t\tcfg.type = VBO_BATCHED;\n\n\t\t\t\t// PBR\n\n\t\t\t\tcfg.color = cfg.color\n\t\t\t\t\t? new Uint8Array([\n\t\t\t\t\t\t\tMath.floor(cfg.color[0] * 255),\n\t\t\t\t\t\t\tMath.floor(cfg.color[1] * 255),\n\t\t\t\t\t\t\tMath.floor(cfg.color[2] * 255)\n\t\t\t\t\t ])\n\t\t\t\t\t: [255, 255, 255];\n\t\t\t\tcfg.opacity = cfg.opacity !== undefined && cfg.opacity !== null ? Math.floor(cfg.opacity * 255) : 255;\n\t\t\t\tcfg.metallic = cfg.metallic !== undefined && cfg.metallic !== null ? Math.floor(cfg.metallic * 255) : 0;\n\t\t\t\tcfg.roughness = cfg.roughness !== undefined && cfg.roughness !== null ? Math.floor(cfg.roughness * 255) : 255;\n\n\t\t\t\t// RTC\n\n\t\t\t\tif (cfg.positions) {\n\t\t\t\t\tconst rtcPositions = [];\n\t\t\t\t\tconst rtcNeeded = (0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_15__.worldToRTCPositions)(cfg.positions, rtcPositions, tempVec3a);\n\t\t\t\t\tif (rtcNeeded) {\n\t\t\t\t\t\tcfg.positions = rtcPositions;\n\t\t\t\t\t\tcfg.origin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(cfg.origin, tempVec3a, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3());\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (cfg.positions) {\n\t\t\t\t\tconst aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t\t\t\tif (cfg.meshMatrix) {\n\t\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformPositions3(cfg.meshMatrix, cfg.positions, cfg.positions);\n\t\t\t\t\t\tcfg.meshMatrix = null; // Positions now baked, don't need any more\n\t\t\t\t\t}\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positions);\n\t\t\t\t\tcfg.aabb = aabb;\n\t\t\t\t} else {\n\t\t\t\t\tconst aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(aabb, cfg.positionsCompressed);\n\t\t\t\t\t_math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n\t\t\t\t\tcfg.aabb = aabb;\n\t\t\t\t}\n\n\t\t\t\tif (cfg.meshMatrix) {\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(cfg.aabb, tempOBB3);\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformOBB3(cfg.meshMatrix, tempOBB3);\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3ToAABB3(tempOBB3, cfg.aabb);\n\t\t\t\t}\n\n\t\t\t\t// EDGES\n\n\t\t\t\tif (\n\t\t\t\t\t!cfg.buckets &&\n\t\t\t\t\t!cfg.edgeIndices &&\n\t\t\t\t\t(cfg.primitive === \"triangles\" || cfg.primitive === \"solid\" || cfg.primitive === \"surface\")\n\t\t\t\t) {\n\t\t\t\t\tif (cfg.positions) {\n\t\t\t\t\t\tcfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positions, cfg.indices, null, 2.0);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcfg.edgeIndices = (0,_math_buildEdgeIndices_js__WEBPACK_IMPORTED_MODULE_2__.buildEdgeIndices)(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// TEXTURE\n\n\t\t\t\t// cfg.textureSetId = cfg.textureSetId || DEFAULT_TEXTURE_SET_ID;\n\t\t\t\tif (cfg.textureSetId) {\n\t\t\t\t\tcfg.textureSet = this._textureSets[cfg.textureSetId];\n\t\t\t\t\tif (!cfg.textureSet) {\n\t\t\t\t\t\tthis.error(\n\t\t\t\t\t\t\t`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// INSTANCING\n\n\t\t\tif (\n\t\t\t\tcfg.positions ||\n\t\t\t\tcfg.positionsCompressed ||\n\t\t\t\tcfg.indices ||\n\t\t\t\tcfg.edgeIndices ||\n\t\t\t\tcfg.normals ||\n\t\t\t\tcfg.normalsCompressed ||\n\t\t\t\tcfg.uv ||\n\t\t\t\tcfg.uvCompressed ||\n\t\t\t\tcfg.positionsDecodeMatrix\n\t\t\t) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`Mesh geometry parameters not expected when instancing a geometry (not expected: positions, positionsCompressed, indices, edgeIndices, normals, normalsCompressed, uv, uvCompressed, positionsDecodeMatrix)`\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tcfg.geometry = this._geometries[cfg.geometryId];\n\t\t\tif (!cfg.geometry) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`[createMesh] Geometry not found: ${cfg.geometryId} - ensure that you create it first with createGeometry()`\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tcfg.origin = cfg.origin ? _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(this._origin, cfg.origin, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3()) : this._origin;\n\t\t\tcfg.positionsDecodeMatrix = cfg.geometry.positionsDecodeMatrix;\n\n\t\t\tif (cfg.transformId) {\n\t\t\t\t// TRANSFORM\n\n\t\t\t\tcfg.transform = this._transforms[cfg.transformId];\n\n\t\t\t\tif (!cfg.transform) {\n\t\t\t\t\tthis.error(\n\t\t\t\t\t\t`[createMesh] Transform not found: ${cfg.transformId} - ensure that you create it first with createTransform()`\n\t\t\t\t\t);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tcfg.aabb = cfg.geometry.aabb;\n\t\t\t} else {\n\t\t\t\t// MATRIX\n\n\t\t\t\tif (cfg.matrix) {\n\t\t\t\t\tcfg.meshMatrix = cfg.matrix.slice();\n\t\t\t\t} else {\n\t\t\t\t\tconst scale = cfg.scale || DEFAULT_SCALE;\n\t\t\t\t\tconst position = cfg.position || DEFAULT_POSITION;\n\t\t\t\t\tconst rotation = cfg.rotation || DEFAULT_ROTATION;\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.eulerToQuaternion(rotation, \"XYZ\", DEFAULT_QUATERNION);\n\t\t\t\t\tcfg.meshMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.composeMat4(position, DEFAULT_QUATERNION, scale, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4());\n\t\t\t\t}\n\n\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(cfg.geometry.aabb, tempOBB3);\n\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformOBB3(cfg.meshMatrix, tempOBB3);\n\t\t\t\tcfg.aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3ToAABB3(tempOBB3, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3());\n\t\t\t}\n\n\t\t\tconst useDTX =\n\t\t\t\t!!this._dtxEnabled &&\n\t\t\t\t(cfg.geometry.primitive === \"triangles\" ||\n\t\t\t\t\tcfg.geometry.primitive === \"solid\" ||\n\t\t\t\t\tcfg.geometry.primitive === \"surface\");\n\n\t\t\tif (useDTX) {\n\t\t\t\t// DTX\n\n\t\t\t\tcfg.type = DTX;\n\n\t\t\t\t// NPR\n\n\t\t\t\tcfg.color = cfg.color\n\t\t\t\t\t? new Uint8Array([\n\t\t\t\t\t\t\tMath.floor(cfg.color[0] * 255),\n\t\t\t\t\t\t\tMath.floor(cfg.color[1] * 255),\n\t\t\t\t\t\t\tMath.floor(cfg.color[2] * 255)\n\t\t\t\t\t ])\n\t\t\t\t\t: defaultCompressedColor;\n\t\t\t\tcfg.opacity = cfg.opacity !== undefined && cfg.opacity !== null ? Math.floor(cfg.opacity * 255) : 255;\n\n\t\t\t\t// BUCKETING - lazy generated, reused\n\n\t\t\t\tlet buckets = this._dtxBuckets[cfg.geometryId];\n\t\t\t\tif (!buckets) {\n\t\t\t\t\tbuckets = createDTXBuckets(cfg.geometry, this._enableVertexWelding, this._enableIndexBucketing);\n\t\t\t\t\tthis._dtxBuckets[cfg.geometryId] = buckets;\n\t\t\t\t}\n\t\t\t\tcfg.buckets = buckets;\n\t\t\t} else {\n\t\t\t\t// VBO\n\n\t\t\t\tcfg.type = VBO_INSTANCED;\n\n\t\t\t\t// PBR\n\n\t\t\t\tcfg.color = cfg.color\n\t\t\t\t\t? new Uint8Array([\n\t\t\t\t\t\t\tMath.floor(cfg.color[0] * 255),\n\t\t\t\t\t\t\tMath.floor(cfg.color[1] * 255),\n\t\t\t\t\t\t\tMath.floor(cfg.color[2] * 255)\n\t\t\t\t\t ])\n\t\t\t\t\t: defaultCompressedColor;\n\t\t\t\tcfg.opacity = cfg.opacity !== undefined && cfg.opacity !== null ? Math.floor(cfg.opacity * 255) : 255;\n\t\t\t\tcfg.metallic = cfg.metallic !== undefined && cfg.metallic !== null ? Math.floor(cfg.metallic * 255) : 0;\n\t\t\t\tcfg.roughness = cfg.roughness !== undefined && cfg.roughness !== null ? Math.floor(cfg.roughness * 255) : 255;\n\n\t\t\t\t// TEXTURE\n\n\t\t\t\tif (cfg.textureSetId) {\n\t\t\t\t\tcfg.textureSet = this._textureSets[cfg.textureSetId];\n\t\t\t\t\t// if (!cfg.textureSet) {\n\t\t\t\t\t// this.error(`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`);\n\t\t\t\t\t// return false;\n\t\t\t\t\t// }\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tcfg.numPrimitives = this._getNumPrimitives(cfg);\n\n\t\tthis._meshesCfgsBeforeMeshCreation[cfg.id] = cfg;\n\n\t\treturn true;\n\t}\n\n\t_createMesh(cfg) {\n\t\tconst mesh = new _SceneModelMesh_js__WEBPACK_IMPORTED_MODULE_3__.SceneModelMesh(this, cfg.id, cfg.color, cfg.opacity, cfg.transform, cfg.textureSet);\n\t\tmesh.pickId = this.scene._renderer.getPickID(mesh);\n\t\tconst pickId = mesh.pickId;\n\t\tconst a = (pickId >> 24) & 0xff;\n\t\tconst b = (pickId >> 16) & 0xff;\n\t\tconst g = (pickId >> 8) & 0xff;\n\t\tconst r = pickId & 0xff;\n\t\tcfg.pickColor = new Uint8Array([r, g, b, a]); // Quantized pick color\n\t\tcfg.solid = cfg.primitive === \"solid\";\n\t\tmesh.origin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3(cfg.origin);\n\t\tswitch (cfg.type) {\n\t\t\tcase DTX:\n\t\t\t\tmesh.layer = this._getDTXLayer(cfg);\n\t\t\t\tmesh.aabb = cfg.aabb;\n\t\t\t\tbreak;\n\t\t\tcase VBO_BATCHED:\n\t\t\t\tmesh.layer = this._getVBOBatchingLayer(cfg);\n\t\t\t\tmesh.aabb = cfg.aabb;\n\t\t\t\tbreak;\n\t\t\tcase VBO_INSTANCED:\n\t\t\t\tmesh.layer = this._getVBOInstancingLayer(cfg);\n\t\t\t\tmesh.aabb = cfg.aabb;\n\t\t\t\tbreak;\n\t\t}\n\t\tif (cfg.transform) {\n\t\t\tcfg.meshMatrix = cfg.transform.worldMatrix;\n\t\t}\n\t\tmesh.portionId = mesh.layer.createPortion(mesh, cfg);\n\t\treturn mesh;\n\t}\n\n\t_getNumPrimitives(cfg) {\n\t\tlet countIndices = 0;\n\t\tconst primitive = cfg.geometry ? cfg.geometry.primitive : cfg.primitive;\n\t\tswitch (primitive) {\n\t\t\tcase \"triangles\":\n\t\t\tcase \"solid\":\n\t\t\tcase \"surface\":\n\t\t\t\tswitch (cfg.type) {\n\t\t\t\t\tcase DTX:\n\t\t\t\t\t\tfor (let i = 0, len = cfg.buckets.length; i < len; i++) {\n\t\t\t\t\t\t\tcountIndices += cfg.buckets[i].indices.length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VBO_BATCHED:\n\t\t\t\t\t\tcountIndices += cfg.indices.length;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VBO_INSTANCED:\n\t\t\t\t\t\tcountIndices += cfg.geometry.indices.length;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn Math.round(countIndices / 3);\n\t\t\tcase \"points\":\n\t\t\t\tswitch (cfg.type) {\n\t\t\t\t\tcase DTX:\n\t\t\t\t\t\tfor (let i = 0, len = cfg.buckets.length; i < len; i++) {\n\t\t\t\t\t\t\tcountIndices += cfg.buckets[i].positionsCompressed.length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VBO_BATCHED:\n\t\t\t\t\t\tcountIndices += cfg.positions ? cfg.positions.length : cfg.positionsCompressed.length;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VBO_INSTANCED:\n\t\t\t\t\t\tconst geometry = cfg.geometry;\n\t\t\t\t\t\tcountIndices += geometry.positions ? geometry.positions.length : geometry.positionsCompressed.length;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn Math.round(countIndices);\n\t\t\tcase \"lines\":\n\t\t\tcase \"line-strip\":\n\t\t\t\tswitch (cfg.type) {\n\t\t\t\t\tcase DTX:\n\t\t\t\t\t\tfor (let i = 0, len = cfg.buckets.length; i < len; i++) {\n\t\t\t\t\t\t\tcountIndices += cfg.buckets[i].indices.length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VBO_BATCHED:\n\t\t\t\t\t\tcountIndices += cfg.indices.length;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VBO_INSTANCED:\n\t\t\t\t\t\tcountIndices += cfg.geometry.indices.length;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn Math.round(countIndices / 2);\n\t\t}\n\t\treturn 0;\n\t}\n\n\t_getDTXLayer(cfg) {\n\t\tconst origin = cfg.origin;\n\t\tconst primitive = cfg.geometry ? cfg.geometry.primitive : cfg.primitive;\n\t\tconst layerId = `.${primitive}.${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}`;\n\t\tlet dtxLayer = this._dtxLayers[layerId];\n\t\tif (dtxLayer) {\n\t\t\tif (!dtxLayer.canCreatePortion(cfg)) {\n\t\t\t\tdtxLayer.finalize();\n\t\t\t\tdelete this._dtxLayers[layerId];\n\t\t\t\tdtxLayer = null;\n\t\t\t} else {\n\t\t\t\treturn dtxLayer;\n\t\t\t}\n\t\t}\n\t\tswitch (primitive) {\n\t\t\tcase \"triangles\":\n\t\t\tcase \"solid\":\n\t\t\tcase \"surface\":\n\t\t\t\tdtxLayer = new _dtx_triangles_DTXTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_12__.DTXTrianglesLayer(this, { layerIndex: 0, origin }); // layerIndex is set in #finalize()\n\t\t\t\tbreak;\n\t\t\tcase \"lines\":\n\t\t\t\tdtxLayer = new _dtx_lines_DTXLinesLayer_js__WEBPACK_IMPORTED_MODULE_11__.DTXLinesLayer(this, { layerIndex: 0, origin }); // layerIndex is set in #finalize()\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\t\tthis._dtxLayers[layerId] = dtxLayer;\n\t\tthis.layerList.push(dtxLayer);\n\t\treturn dtxLayer;\n\t}\n\n\t_getVBOBatchingLayer(cfg) {\n\t\tconst model = this;\n\t\tconst origin = cfg.origin;\n\t\tconst positionsDecodeHash =\n\t\t\tcfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary\n\t\t\t\t? this._createHashStringFromMatrix(cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary)\n\t\t\t\t: \"-\";\n\t\tconst textureSetId = cfg.textureSetId || \"-\";\n\t\tconst layerId = `${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}.${\n\t\t\tcfg.primitive\n\t\t}.${positionsDecodeHash}.${textureSetId}`;\n\t\tlet vboBatchingLayer = this._vboBatchingLayers[layerId];\n\t\tif (vboBatchingLayer) {\n\t\t\treturn vboBatchingLayer;\n\t\t}\n\t\tlet textureSet = cfg.textureSet;\n\t\twhile (!vboBatchingLayer) {\n\t\t\tswitch (cfg.primitive) {\n\t\t\t\tcase \"triangles\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);\n\t\t\t\t\tvboBatchingLayer = new _vbo_batching_triangles_VBOBatchingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_5__.VBOBatchingTrianglesLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttextureSet,\n\t\t\t\t\t\tlayerIndex: 0, // This is set in #finalize()\n\t\t\t\t\t\tscratchMemory: this._vboBatchingLayerScratchMemory,\n\t\t\t\t\t\tpositionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n\t\t\t\t\t\tuvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tmaxGeometryBatchSize: this._maxGeometryBatchSize,\n\t\t\t\t\t\tsolid: cfg.primitive === \"solid\",\n\t\t\t\t\t\tautoNormals: true\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"solid\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);\n\t\t\t\t\tvboBatchingLayer = new _vbo_batching_triangles_VBOBatchingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_5__.VBOBatchingTrianglesLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttextureSet,\n\t\t\t\t\t\tlayerIndex: 0, // This is set in #finalize()\n\t\t\t\t\t\tscratchMemory: this._vboBatchingLayerScratchMemory,\n\t\t\t\t\t\tpositionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n\t\t\t\t\t\tuvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tmaxGeometryBatchSize: this._maxGeometryBatchSize,\n\t\t\t\t\t\tsolid: cfg.primitive === \"solid\",\n\t\t\t\t\t\tautoNormals: true\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"surface\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);\n\t\t\t\t\tvboBatchingLayer = new _vbo_batching_triangles_VBOBatchingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_5__.VBOBatchingTrianglesLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttextureSet,\n\t\t\t\t\t\tlayerIndex: 0, // This is set in #finalize()\n\t\t\t\t\t\tscratchMemory: this._vboBatchingLayerScratchMemory,\n\t\t\t\t\t\tpositionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n\t\t\t\t\t\tuvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tmaxGeometryBatchSize: this._maxGeometryBatchSize,\n\t\t\t\t\t\tsolid: cfg.primitive === \"solid\",\n\t\t\t\t\t\tautoNormals: true\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"lines\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating VBOBatchingLinesLayer`);\n\t\t\t\t\tvboBatchingLayer = new _vbo_batching_lines_VBOBatchingLinesLayer_js__WEBPACK_IMPORTED_MODULE_7__.VBOBatchingLinesLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tlayerIndex: 0, // This is set in #finalize()\n\t\t\t\t\t\tscratchMemory: this._vboBatchingLayerScratchMemory,\n\t\t\t\t\t\tpositionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n\t\t\t\t\t\tuvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tmaxGeometryBatchSize: this._maxGeometryBatchSize\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"points\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating VBOBatchingPointsLayer`);\n\t\t\t\t\tvboBatchingLayer = new _vbo_batching_points_VBOBatchingPointsLayer_js__WEBPACK_IMPORTED_MODULE_9__.VBOBatchingPointsLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tlayerIndex: 0, // This is set in #finalize()\n\t\t\t\t\t\tscratchMemory: this._vboBatchingLayerScratchMemory,\n\t\t\t\t\t\tpositionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined\n\t\t\t\t\t\tuvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tmaxGeometryBatchSize: this._maxGeometryBatchSize\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst lenPositions = cfg.positionsCompressed ? cfg.positionsCompressed.length : cfg.positions.length;\n\t\t\tconst canCreatePortion =\n\t\t\t\tcfg.primitive === \"points\"\n\t\t\t\t\t? vboBatchingLayer.canCreatePortion(lenPositions)\n\t\t\t\t\t: vboBatchingLayer.canCreatePortion(lenPositions, cfg.indices.length);\n\t\t\tif (!canCreatePortion) {\n\t\t\t\tvboBatchingLayer.finalize();\n\t\t\t\tdelete this._vboBatchingLayers[layerId];\n\t\t\t\tvboBatchingLayer = null;\n\t\t\t}\n\t\t}\n\t\tthis._vboBatchingLayers[layerId] = vboBatchingLayer;\n\t\tthis.layerList.push(vboBatchingLayer);\n\t\treturn vboBatchingLayer;\n\t}\n\n\t_createHashStringFromMatrix(matrix) {\n\t\tconst matrixString = matrix.join(\"\");\n\t\tlet hash = 0;\n\t\tfor (let i = 0; i < matrixString.length; i++) {\n\t\t\tconst char = matrixString.charCodeAt(i);\n\t\t\thash = (hash << 5) - hash + char;\n\t\t\thash |= 0; // Convert to 32-bit integer\n\t\t}\n\t\tconst hashString = (hash >>> 0).toString(16);\n\t\treturn hashString;\n\t}\n\n\t_getVBOInstancingLayer(cfg) {\n\t\tconst model = this;\n\t\tconst origin = cfg.origin;\n\t\tconst textureSetId = cfg.textureSetId || \"-\";\n\t\tconst geometryId = cfg.geometryId;\n\t\tconst layerId = `${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(\n\t\t\torigin[2]\n\t\t)}.${textureSetId}.${geometryId}`;\n\t\tlet vboInstancingLayer = this._vboInstancingLayers[layerId];\n\t\tif (vboInstancingLayer) {\n\t\t\treturn vboInstancingLayer;\n\t\t}\n\t\tlet textureSet = cfg.textureSet;\n\t\tconst geometry = cfg.geometry;\n\t\twhile (!vboInstancingLayer) {\n\t\t\tswitch (geometry.primitive) {\n\t\t\t\tcase \"triangles\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);\n\t\t\t\t\tvboInstancingLayer = new _vbo_instancing_triangles_VBOInstancingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_6__.VBOInstancingTrianglesLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttextureSet,\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tlayerIndex: 0,\n\t\t\t\t\t\tsolid: false\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"solid\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);\n\t\t\t\t\tvboInstancingLayer = new _vbo_instancing_triangles_VBOInstancingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_6__.VBOInstancingTrianglesLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttextureSet,\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tlayerIndex: 0,\n\t\t\t\t\t\tsolid: true\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"surface\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);\n\t\t\t\t\tvboInstancingLayer = new _vbo_instancing_triangles_VBOInstancingTrianglesLayer_js__WEBPACK_IMPORTED_MODULE_6__.VBOInstancingTrianglesLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttextureSet,\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tlayerIndex: 0,\n\t\t\t\t\t\tsolid: false\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"lines\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating VBOInstancingLinesLayer`);\n\t\t\t\t\tvboInstancingLayer = new _vbo_instancing_lines_VBOInstancingLinesLayer_js__WEBPACK_IMPORTED_MODULE_8__.VBOInstancingLinesLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttextureSet,\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tlayerIndex: 0\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"points\":\n\t\t\t\t\t// console.info(`[SceneModel ${this.id}]: creating PointsInstancingLayer`);\n\t\t\t\t\tvboInstancingLayer = new _vbo_instancing_points_VBOInstancingPointsLayer_js__WEBPACK_IMPORTED_MODULE_10__.VBOInstancingPointsLayer({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttextureSet,\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tlayerIndex: 0\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// const lenPositions = geometry.positionsCompressed.length;\n\t\t\t// if (!vboInstancingLayer.canCreatePortion(lenPositions, geometry.indices.length)) { // FIXME: indices should be optional\n\t\t\t// vboInstancingLayer.finalize();\n\t\t\t// delete this._vboInstancingLayers[layerId];\n\t\t\t// vboInstancingLayer = null;\n\t\t\t// }\n\t\t}\n\t\tthis._vboInstancingLayers[layerId] = vboInstancingLayer;\n\t\tthis.layerList.push(vboInstancingLayer);\n\t\treturn vboInstancingLayer;\n\t}\n\n\t/**\n\t * Creates a {@link SceneModelEntity} within this SceneModel.\n\t *\n\t * * Gives the SceneModelEntity one or more {@link SceneModelMesh}es previously created with\n\t * {@link SceneModel#createMesh}. A SceneModelMesh can only belong to one SceneModelEntity, so you'll get an\n\t * error if you try to reuse a mesh among multiple SceneModelEntitys.\n\t * * The SceneModelEntity can have a {@link SceneModelTextureSet}, previously created with\n\t * {@link SceneModel#createTextureSet}. A SceneModelTextureSet can belong to multiple SceneModelEntitys.\n\t * * The SceneModelEntity can have a geometry, previously created with\n\t * {@link SceneModel#createTextureSet}. A geometry is a \"virtual component\" and can belong to multiple SceneModelEntitys.\n\t *\n\t * @param {Object} cfg SceneModelEntity configuration.\n\t * @param {String} cfg.id Optional ID for the new SceneModelEntity. Must not clash with any existing components within the {@link Scene}.\n\t * @param {String[]} cfg.meshIds IDs of one or more meshes created previously with {@link SceneModel@createMesh}.\n\t * @param {Boolean} [cfg.isObject] Set ````true```` if the {@link SceneModelEntity} represents an object, in which case it will be registered by {@link SceneModelEntity#id} in {@link Scene#objects} and can also have a corresponding {@link MetaObject} with matching {@link MetaObject#id}, registered by that ID in {@link MetaScene#metaObjects}.\n\t * @param {Boolean} [cfg.visible=true] Indicates if the SceneModelEntity is initially visible.\n\t * @param {Boolean} [cfg.culled=false] Indicates if the SceneModelEntity is initially culled from view.\n\t * @param {Boolean} [cfg.pickable=true] Indicates if the SceneModelEntity is initially pickable.\n\t * @param {Boolean} [cfg.clippable=true] Indicates if the SceneModelEntity is initially clippable.\n\t * @param {Boolean} [cfg.collidable=true] Indicates if the SceneModelEntity is initially included in boundary calculations.\n\t * @param {Boolean} [cfg.castsShadow=true] Indicates if the SceneModelEntity initially casts shadows.\n\t * @param {Boolean} [cfg.receivesShadow=true] Indicates if the SceneModelEntity initially receives shadows.\n\t * @param {Boolean} [cfg.xrayed=false] Indicates if the SceneModelEntity is initially xrayed. XRayed appearance is configured by {@link SceneModel#xrayMaterial}.\n\t * @param {Boolean} [cfg.highlighted=false] Indicates if the SceneModelEntity is initially highlighted. Highlighted appearance is configured by {@link SceneModel#highlightMaterial}.\n\t * @param {Boolean} [cfg.selected=false] Indicates if the SceneModelEntity is initially selected. Selected appearance is configured by {@link SceneModel#selectedMaterial}.\n\t * @param {Boolean} [cfg.edges=false] Indicates if the SceneModelEntity's edges are initially emphasized. Edges appearance is configured by {@link SceneModel#edgeMaterial}.\n\t * @returns {SceneModelEntity} The new SceneModelEntity.\n\t */\n\tcreateEntity(cfg) {\n\t\tif (cfg.id === undefined) {\n\t\t\tcfg.id = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.createUUID();\n\t\t} else if (this.scene.components[cfg.id]) {\n\t\t\tthis.error(`Scene already has a Component with this ID: ${cfg.id} - will assign random ID`);\n\t\t\tcfg.id = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.createUUID();\n\t\t}\n\t\tif (cfg.meshIds === undefined) {\n\t\t\tthis.error(\"Config missing: meshIds\");\n\t\t\treturn;\n\t\t}\n\t\tlet flags = 0;\n\t\tif (this._visible && cfg.visible !== false) {\n\t\t\tflags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.VISIBLE;\n\t\t}\n\t\tif (this._pickable && cfg.pickable !== false) {\n\t\t\tflags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.PICKABLE;\n\t\t}\n\t\tif (this._culled && cfg.culled !== false) {\n\t\t\tflags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.CULLED;\n\t\t}\n\t\tif (this._clippable && cfg.clippable !== false) {\n\t\t\tflags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.CLIPPABLE;\n\t\t}\n\t\tif (this._collidable && cfg.collidable !== false) {\n\t\t\tflags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.COLLIDABLE;\n\t\t}\n\t\tif (this._edges && cfg.edges !== false) {\n\t\t\tflags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.EDGES;\n\t\t}\n\t\tif (this._xrayed && cfg.xrayed !== false) {\n\t\t\tflags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.XRAYED;\n\t\t}\n\t\tif (this._highlighted && cfg.highlighted !== false) {\n\t\t\tflags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.HIGHLIGHTED;\n\t\t}\n\t\tif (this._selected && cfg.selected !== false) {\n\t\t\tflags = flags | _ENTITY_FLAGS_js__WEBPACK_IMPORTED_MODULE_13__.ENTITY_FLAGS.SELECTED;\n\t\t}\n\t\tcfg.flags = flags;\n\t\tthis._createEntity(cfg);\n\t}\n\n\t_createEntity(cfg) {\n\t\tlet meshes = [];\n\t\tfor (let i = 0, len = cfg.meshIds.length; i < len; i++) {\n\t\t\tconst meshId = cfg.meshIds[i];\n\t\t\tlet mesh = this._meshes[meshId]; // Trying to get already created mesh\n\t\t\tif (!mesh) {\n\t\t\t\t// Checks if there is already created mesh for this meshId\n\t\t\t\tlet meshCfg = this._meshesCfgsBeforeMeshCreation[meshId]; // Trying to get already created cfg\n\t\t\t\tif (!meshCfg) {\n\t\t\t\t\t// Checks if there is already created cfg for this meshId\n\t\t\t\t\tthis.error(`Mesh with this ID not found: \"${meshId}\" - ignoring this mesh`); // There is no such cfg\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tmesh = this._createMesh(meshCfg); // There is no such mesh yet, but there is already created cfg, so it creates this mesh\n\t\t\t\tthis._meshes[cfg.id] = mesh; // Now it will also add this mesh to dictionary of created meshes\n\t\t\t}\n\t\t\tif (mesh.parent) {\n\t\t\t\tthis.error(\n\t\t\t\t\t`Mesh with ID \"${meshId}\" already belongs to object with ID \"${mesh.parent.id}\" - ignoring this mesh`\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmeshes.push(mesh);\n\t\t}\n\t\tconst lodCullable = true;\n\t\tconst entity = new _SceneModelEntity_js__WEBPACK_IMPORTED_MODULE_25__.SceneModelEntity(this, cfg.isObject, cfg.id, meshes, cfg.flags, lodCullable); // Internally sets SceneModelEntity#parent to this SceneModel\n\t\tthis._entityList.push(entity);\n\t\tthis._entities[cfg.id] = entity;\n\t\tthis.numEntities++;\n\t}\n\n\t/**\n\t * Finalizes this SceneModel.\n\t *\n\t * Once finalized, you can't add anything more to this SceneModel.\n\t */\n\tfinalize() {\n\t\tif (this.destroyed) {\n\t\t\treturn;\n\t\t}\n\t\tfor (let i = 0, len = this.layerList.length; i < len; i++) {\n\t\t\tconst layer = this.layerList[i];\n\t\t\tlayer.finalize();\n\t\t}\n\t\tthis._geometries = {};\n\t\tthis._dtxBuckets = {};\n\t\tthis._textures = {};\n\t\tthis._textureSets = {};\n\t\tthis._dtxLayers = {};\n\t\tthis._vboInstancingLayers = {};\n\t\tthis._vboBatchingLayers = {};\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tconst entity = this._entityList[i];\n\t\t\tentity._finalize();\n\t\t}\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tconst entity = this._entityList[i];\n\t\t\tentity._finalize2();\n\t\t}\n\t\t// Sort layers to reduce WebGL shader switching when rendering them\n\t\tthis.layerList.sort((a, b) => {\n\t\t\tif (a.sortId < b.sortId) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (a.sortId > b.sortId) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t});\n\t\tfor (let i = 0, len = this.layerList.length; i < len; i++) {\n\t\t\tconst layer = this.layerList[i];\n\t\t\tlayer.layerIndex = i;\n\t\t}\n\t\tthis.glRedraw();\n\t\tthis.scene._aabbDirty = true;\n\t\tthis._viewMatrixDirty = true;\n\t\tthis._matrixDirty = true;\n\t\tthis._aabbDirty = true;\n\n\t\tthis._setWorldMatrixDirty();\n\t\tthis._sceneModelDirty();\n\n\t\tthis.position = this._position;\n\t}\n\n\t/** @private */\n\tstateSortCompare(drawable1, drawable2) {}\n\n\t/** @private */\n\trebuildRenderFlags() {\n\t\tthis.renderFlags.reset();\n\t\tthis._updateRenderFlagsVisibleLayers();\n\t\tif (this.renderFlags.numLayers > 0 && this.renderFlags.numVisibleLayers === 0) {\n\t\t\tthis.renderFlags.culled = true;\n\t\t\treturn;\n\t\t}\n\t\tthis._updateRenderFlags();\n\t}\n\n\t/**\n\t * @private\n\t */\n\t_updateRenderFlagsVisibleLayers() {\n\t\tconst renderFlags = this.renderFlags;\n\t\trenderFlags.numLayers = this.layerList.length;\n\t\trenderFlags.numVisibleLayers = 0;\n\t\tfor (let layerIndex = 0, len = this.layerList.length; layerIndex < len; layerIndex++) {\n\t\t\tconst layer = this.layerList[layerIndex];\n\t\t\tconst layerVisible = this._getActiveSectionPlanesForLayer(layer);\n\t\t\tif (layerVisible) {\n\t\t\t\trenderFlags.visibleLayers[renderFlags.numVisibleLayers++] = layerIndex;\n\t\t\t}\n\t\t}\n\t}\n\n\t_getActiveSectionPlanesForLayer(layer) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tconst sectionPlanes = this.scene._sectionPlanesState.sectionPlanes;\n\t\tconst numSectionPlanes = sectionPlanes.length;\n\t\tconst baseIndex = layer.layerIndex * numSectionPlanes;\n\t\tif (numSectionPlanes > 0) {\n\t\t\tfor (let i = 0; i < numSectionPlanes; i++) {\n\t\t\t\tconst sectionPlane = sectionPlanes[i];\n\t\t\t\tif (!sectionPlane.active) {\n\t\t\t\t\trenderFlags.sectionPlanesActivePerLayer[baseIndex + i] = false;\n\t\t\t\t} else {\n\t\t\t\t\trenderFlags.sectionPlanesActivePerLayer[baseIndex + i] = true;\n\t\t\t\t\trenderFlags.sectioned = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t_updateRenderFlags() {\n\t\tif (this.numVisibleLayerPortions === 0) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.numCulledLayerPortions === this.numPortions) {\n\t\t\treturn;\n\t\t}\n\t\tconst renderFlags = this.renderFlags;\n\t\trenderFlags.colorOpaque = this.numTransparentLayerPortions < this.numPortions;\n\t\tif (this.numTransparentLayerPortions > 0) {\n\t\t\trenderFlags.colorTransparent = true;\n\t\t}\n\t\tif (this.numXRayedLayerPortions > 0) {\n\t\t\tconst xrayMaterial = this.scene.xrayMaterial._state;\n\t\t\tif (xrayMaterial.fill) {\n\t\t\t\tif (xrayMaterial.fillAlpha < 1.0) {\n\t\t\t\t\trenderFlags.xrayedSilhouetteTransparent = true;\n\t\t\t\t} else {\n\t\t\t\t\trenderFlags.xrayedSilhouetteOpaque = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (xrayMaterial.edges) {\n\t\t\t\tif (xrayMaterial.edgeAlpha < 1.0) {\n\t\t\t\t\trenderFlags.xrayedEdgesTransparent = true;\n\t\t\t\t} else {\n\t\t\t\t\trenderFlags.xrayedEdgesOpaque = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.numEdgesLayerPortions > 0) {\n\t\t\tconst edgeMaterial = this.scene.edgeMaterial._state;\n\t\t\tif (edgeMaterial.edges) {\n\t\t\t\trenderFlags.edgesOpaque = this.numTransparentLayerPortions < this.numPortions;\n\t\t\t\tif (this.numTransparentLayerPortions > 0) {\n\t\t\t\t\trenderFlags.edgesTransparent = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.numSelectedLayerPortions > 0) {\n\t\t\tconst selectedMaterial = this.scene.selectedMaterial._state;\n\t\t\tif (selectedMaterial.fill) {\n\t\t\t\tif (selectedMaterial.fillAlpha < 1.0) {\n\t\t\t\t\trenderFlags.selectedSilhouetteTransparent = true;\n\t\t\t\t} else {\n\t\t\t\t\trenderFlags.selectedSilhouetteOpaque = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (selectedMaterial.edges) {\n\t\t\t\tif (selectedMaterial.edgeAlpha < 1.0) {\n\t\t\t\t\trenderFlags.selectedEdgesTransparent = true;\n\t\t\t\t} else {\n\t\t\t\t\trenderFlags.selectedEdgesOpaque = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.numHighlightedLayerPortions > 0) {\n\t\t\tconst highlightMaterial = this.scene.highlightMaterial._state;\n\t\t\tif (highlightMaterial.fill) {\n\t\t\t\tif (highlightMaterial.fillAlpha < 1.0) {\n\t\t\t\t\trenderFlags.highlightedSilhouetteTransparent = true;\n\t\t\t\t} else {\n\t\t\t\t\trenderFlags.highlightedSilhouetteOpaque = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (highlightMaterial.edges) {\n\t\t\t\tif (highlightMaterial.edgeAlpha < 1.0) {\n\t\t\t\t\trenderFlags.highlightedEdgesTransparent = true;\n\t\t\t\t} else {\n\t\t\t\t\trenderFlags.highlightedEdgesOpaque = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// -------------- RENDERING ---------------------------------------------------------------------------------------\n\n\t/** @private */\n\tdrawColorOpaque(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawColorOpaque(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawColorTransparent(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawColorTransparent(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawDepth(frameCtx) {\n\t\t// Dedicated to SAO because it skips transparent objects\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawDepth(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawNormals(frameCtx) {\n\t\t// Dedicated to SAO because it skips transparent objects\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawNormals(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawSilhouetteXRayed(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawSilhouetteXRayed(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawSilhouetteHighlighted(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawSilhouetteHighlighted(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawSilhouetteSelected(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawSilhouetteSelected(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawEdgesColorOpaque(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawEdgesColorOpaque(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawEdgesColorTransparent(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawEdgesColorTransparent(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawEdgesXRayed(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawEdgesXRayed(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawEdgesHighlighted(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawEdgesHighlighted(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawEdgesSelected(frameCtx) {\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawEdgesSelected(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t */\n\tdrawOcclusion(frameCtx) {\n\t\tif (this.numVisibleLayerPortions === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawOcclusion(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t */\n\tdrawShadow(frameCtx) {\n\t\tif (this.numVisibleLayerPortions === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawShadow(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/** @private */\n\tsetPickMatrices(pickViewMatrix, pickProjMatrix) {\n\t\tif (this._numVisibleLayerPortions === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tconst layer = this.layerList[layerIndex];\n\t\t\tif (layer.setPickMatrices) {\n\t\t\t\tlayer.setPickMatrices(pickViewMatrix, pickProjMatrix);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @private */\n\tdrawPickMesh(frameCtx) {\n\t\tif (this.numVisibleLayerPortions === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawPickMesh(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/**\n\t * Called by SceneModelMesh.drawPickDepths()\n\t * @private\n\t */\n\tdrawPickDepths(frameCtx) {\n\t\tif (this.numVisibleLayerPortions === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawPickDepths(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/**\n\t * Called by SceneModelMesh.drawPickNormals()\n\t * @private\n\t */\n\tdrawPickNormals(frameCtx) {\n\t\tif (this.numVisibleLayerPortions === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tthis.layerList[layerIndex].drawPickNormals(renderFlags, frameCtx);\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t */\n\tdrawSnapInit(frameCtx) {\n\t\tif (this.numVisibleLayerPortions === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tconst layer = this.layerList[layerIndex];\n\t\t\tif (layer.drawSnapInit) {\n\t\t\t\tframeCtx.snapPickOrigin = [0, 0, 0];\n\t\t\t\tframeCtx.snapPickCoordinateScale = [1, 1, 1];\n\t\t\t\tframeCtx.snapPickLayerNumber++;\n\t\t\t\tlayer.drawSnapInit(renderFlags, frameCtx);\n\t\t\t\tframeCtx.snapPickLayerParams[frameCtx.snapPickLayerNumber] = {\n\t\t\t\t\torigin: frameCtx.snapPickOrigin.slice(),\n\t\t\t\t\tcoordinateScale: frameCtx.snapPickCoordinateScale.slice()\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t */\n\tdrawSnap(frameCtx) {\n\t\tif (this.numVisibleLayerPortions === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst renderFlags = this.renderFlags;\n\t\tfor (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n\t\t\tconst layerIndex = renderFlags.visibleLayers[i];\n\t\t\tconst layer = this.layerList[layerIndex];\n\t\t\tif (layer.drawSnap) {\n\t\t\t\tframeCtx.snapPickOrigin = [0, 0, 0];\n\t\t\t\tframeCtx.snapPickCoordinateScale = [1, 1, 1];\n\t\t\t\tframeCtx.snapPickLayerNumber++;\n\t\t\t\tlayer.drawSnap(renderFlags, frameCtx);\n\t\t\t\tframeCtx.snapPickLayerParams[frameCtx.snapPickLayerNumber] = {\n\t\t\t\t\torigin: frameCtx.snapPickOrigin.slice(),\n\t\t\t\t\tcoordinateScale: frameCtx.snapPickCoordinateScale.slice()\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Destroys this SceneModel.\n\t */\n\tdestroy() {\n\t\tfor (let layerId in this._vboBatchingLayers) {\n\t\t\tif (this._vboBatchingLayers.hasOwnProperty(layerId)) {\n\t\t\t\tthis._vboBatchingLayers[layerId].destroy();\n\t\t\t}\n\t\t}\n\t\tthis._vboBatchingLayers = {};\n\t\tfor (let layerId in this._vboInstancingLayers) {\n\t\t\tif (this._vboInstancingLayers.hasOwnProperty(layerId)) {\n\t\t\t\tthis._vboInstancingLayers[layerId].destroy();\n\t\t\t}\n\t\t}\n\t\tthis._vboInstancingLayers = {};\n\t\tthis.scene.camera.off(this._onCameraViewMatrix);\n\t\tthis.scene.off(this._onTick);\n\t\tfor (let i = 0, len = this.layerList.length; i < len; i++) {\n\t\t\tthis.layerList[i].destroy();\n\t\t}\n\t\tthis.layerList = [];\n\t\tfor (let i = 0, len = this._entityList.length; i < len; i++) {\n\t\t\tthis._entityList[i]._destroy();\n\t\t}\n\t\t// Object.entries(this._geometries).forEach(([id, geometry]) => {\n\t\t// geometry.destroy();\n\t\t// });\n\t\tthis._geometries = {};\n\t\tthis._dtxBuckets = {};\n\t\tthis._textures = {};\n\t\tthis._textureSets = {};\n\t\tthis._meshes = {};\n\t\tthis._entities = {};\n\t\tthis.scene._aabbDirty = true;\n\t\tif (this._isModel) {\n\t\t\tthis.scene._deregisterModel(this);\n\t\t}\n\t\t(0,_vbo_ScratchMemory_js__WEBPACK_IMPORTED_MODULE_4__.putScratchMemory)();\n\t\tsuper.destroy();\n\t}\n}\n\n/**\n * This function applies two steps to the provided mesh geometry data:\n *\n * - 1st, it reduces its `.positions` to unique positions, thus removing duplicate vertices. It will adjust the `.indices` and `.edgeIndices` array accordingly to the unique `.positions`.\n *\n * - 2nd, it tries to do an optimization called `index rebucketting`\n *\n * _Rebucketting minimizes the amount of RAM usage for a given mesh geometry by trying do demote its needed index bitness._\n *\n * - _for 32 bit indices, will try to demote them to 16 bit indices_\n * - _for 16 bit indices, will try to demote them to 8 bits indices_\n * - _8 bits indices are kept as-is_\n *\n * The fact that 32/16/8 bits are needed for indices, depends on the number of maximumm indexable vertices within the mesh geometry: this is, the number of vertices in the mesh geometry.\n *\n * The function returns the same provided input `geometry`, enrichened with the additional key `.preparedBukets`.\n *\n * @param {object} geometry The mesh information containing `.positions`, `.indices`, `.edgeIndices` arrays.\n *\n * @param enableVertexWelding\n * @param enableIndexBucketing\n * @returns {object} The mesh information enrichened with `.buckets` key.\n */\nfunction createDTXBuckets(geometry, enableVertexWelding, enableIndexBucketing) {\n\tlet uniquePositionsCompressed, uniqueIndices, uniqueEdgeIndices;\n\tif (enableVertexWelding || enableIndexBucketing) {\n\t\t// Expensive - careful!\n\t\t[uniquePositionsCompressed, uniqueIndices, uniqueEdgeIndices] = (0,_calculateUniquePositions_js__WEBPACK_IMPORTED_MODULE_23__.uniquifyPositions)({\n\t\t\tpositionsCompressed: geometry.positionsCompressed,\n\t\t\tindices: geometry.indices,\n\t\t\tedgeIndices: geometry.edgeIndices\n\t\t});\n\t} else {\n\t\tuniquePositionsCompressed = geometry.positionsCompressed;\n\t\tuniqueIndices = geometry.indices;\n\t\tuniqueEdgeIndices = geometry.edgeIndices;\n\t}\n\tlet buckets;\n\tif (enableIndexBucketing) {\n\t\tlet numUniquePositions = uniquePositionsCompressed.length / 3;\n\t\tbuckets = (0,_rebucketPositions_js__WEBPACK_IMPORTED_MODULE_24__.rebucketPositions)(\n\t\t\t{\n\t\t\t\tpositionsCompressed: uniquePositionsCompressed,\n\t\t\t\tindices: uniqueIndices,\n\t\t\t\tedgeIndices: uniqueEdgeIndices\n\t\t\t},\n\t\t\tnumUniquePositions > 1 << 16 ? 16 : 8\n\t\t\t// true\n\t\t);\n\t} else {\n\t\tbuckets = [\n\t\t\t{\n\t\t\t\tpositionsCompressed: uniquePositionsCompressed,\n\t\t\t\tindices: uniqueIndices,\n\t\t\t\tedgeIndices: uniqueEdgeIndices\n\t\t\t}\n\t\t];\n\t}\n\treturn buckets;\n}\n\nfunction createGeometryOBB(geometry) {\n\tgeometry.obb = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.OBB3();\n\tif (geometry.positionsCompressed && geometry.positionsCompressed.length > 0) {\n\t\tconst localAABB = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(localAABB, geometry.positionsCompressed);\n\t\t_math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(localAABB, geometry.positionsDecodeMatrix);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(localAABB, geometry.obb);\n\t} else if (geometry.positions && geometry.positions.length > 0) {\n\t\tconst localAABB = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(localAABB, geometry.positions);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(localAABB, geometry.obb);\n\t} else if (geometry.buckets) {\n\t\tconst localAABB = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.collapseAABB3();\n\t\tfor (let i = 0, len = geometry.buckets.length; i < len; i++) {\n\t\t\tconst bucket = geometry.buckets[i];\n\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.expandAABB3Points3(localAABB, bucket.positionsCompressed);\n\t\t}\n\t\t_math_geometryCompressionUtils_js__WEBPACK_IMPORTED_MODULE_26__.geometryCompressionUtils.decompressAABB(localAABB, geometry.positionsDecodeMatrix);\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.AABB3ToOBB3(localAABB, geometry.obb);\n\t}\n}\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/model/SceneModel.js?");
3528
3548
 
3529
3549
  /***/ }),
3530
3550
 
@@ -4714,7 +4734,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4714
4734
  \****************************************/
4715
4735
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4716
4736
 
4717
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Node: () => (/* binding */ Node)\n/* harmony export */ });\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n\r\n\r\n\r\n\r\nconst angleAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec4(4);\r\nconst q1 = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec4();\r\nconst q2 = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec4();\r\nconst xAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3([1, 0, 0]);\r\nconst yAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3([0, 1, 0]);\r\nconst zAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3([0, 0, 1]);\r\n\r\nconst veca = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3(3);\r\nconst vecb = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3(3);\r\n\r\nconst identityMat = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\r\n\r\n/**\r\n * @desc An {@link Entity} that is a scene graph node that can have child Nodes and {@link Mesh}es.\r\n *\r\n * ## Usage\r\n *\r\n * The example below is the same as the one given for {@link Mesh}, since the two classes work together. In this example,\r\n * we'll create a scene graph in which a root Node represents a group and the {@link Mesh}s are leaves. Since Node\r\n * implements {@link Entity}, we can designate the root Node as a model, causing it to be registered by its ID in {@link Scene#models}.\r\n *\r\n * Since {@link Mesh} also implements {@link Entity}, we can designate the leaf {@link Mesh}es as objects, causing them to\r\n * be registered by their IDs in {@link Scene#objects}.\r\n *\r\n * We can then find those {@link Entity} types in {@link Scene#models} and {@link Scene#objects}.\r\n *\r\n * We can also update properties of our object-Meshes via calls to {@link Scene#setObjectsHighlighted} etc.\r\n *\r\n * [[Run this example](/examples/#sceneRepresentation_SceneGraph)]\r\n *\r\n * ````javascript\r\n * import {Viewer, Mesh, Node, PhongMaterial} from \"xeokit-sdk.es.js\";\r\n *\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\"\r\n * });\r\n *\r\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\r\n * viewer.scene.camera.look = [0, -5.75, 0];\r\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\r\n *\r\n * new Node(viewer.scene, {\r\n * id: \"table\",\r\n * isModel: true, // <---------- Node represents a model, so is registered by ID in viewer.scene.models\r\n * rotation: [0, 50, 0],\r\n * position: [0, 0, 0],\r\n * scale: [1, 1, 1],\r\n *\r\n * children: [\r\n *\r\n * new Mesh(viewer.scene, { // Red table leg\r\n * id: \"redLeg\",\r\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\r\n * position: [-4, -6, -4],\r\n * scale: [1, 3, 1],\r\n * rotation: [0, 0, 0],\r\n * material: new PhongMaterial(viewer.scene, {\r\n * diffuse: [1, 0.3, 0.3]\r\n * })\r\n * }),\r\n *\r\n * new Mesh(viewer.scene, { // Green table leg\r\n * id: \"greenLeg\",\r\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\r\n * position: [4, -6, -4],\r\n * scale: [1, 3, 1],\r\n * rotation: [0, 0, 0],\r\n * material: new PhongMaterial(viewer.scene, {\r\n * diffuse: [0.3, 1.0, 0.3]\r\n * })\r\n * }),\r\n *\r\n * new Mesh(viewer.scene, {// Blue table leg\r\n * id: \"blueLeg\",\r\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\r\n * position: [4, -6, 4],\r\n * scale: [1, 3, 1],\r\n * rotation: [0, 0, 0],\r\n * material: new PhongMaterial(viewer.scene, {\r\n * diffuse: [0.3, 0.3, 1.0]\r\n * })\r\n * }),\r\n *\r\n * new Mesh(viewer.scene, { // Yellow table leg\r\n * id: \"yellowLeg\",\r\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\r\n * position: [-4, -6, 4],\r\n * scale: [1, 3, 1],\r\n * rotation: [0, 0, 0],\r\n * material: new PhongMaterial(viewer.scene, {\r\n * diffuse: [1.0, 1.0, 0.0]\r\n * })\r\n * }),\r\n *\r\n * new Mesh(viewer.scene, { // Purple table top\r\n * id: \"tableTop\",\r\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\r\n * position: [0, -3, 0],\r\n * scale: [6, 0.5, 6],\r\n * rotation: [0, 0, 0],\r\n * material: new PhongMaterial(viewer.scene, {\r\n * diffuse: [1.0, 0.3, 1.0]\r\n * })\r\n * })\r\n * ]\r\n * });\r\n *\r\n * // Find Nodes and Meshes by their IDs\r\n *\r\n * var table = viewer.scene.models[\"table\"]; // Since table Node has isModel == true\r\n *\r\n * var redLeg = viewer.scene.objects[\"redLeg\"]; // Since the Meshes have isObject == true\r\n * var greenLeg = viewer.scene.objects[\"greenLeg\"];\r\n * var blueLeg = viewer.scene.objects[\"blueLeg\"];\r\n *\r\n * // Highlight one of the table leg Meshes\r\n *\r\n * viewer.scene.setObjectsHighlighted([\"redLeg\"], true); // Since the Meshes have isObject == true\r\n *\r\n * // Periodically update transforms on our Nodes and Meshes\r\n *\r\n * viewer.scene.on(\"tick\", function () {\r\n *\r\n * // Rotate legs\r\n * redLeg.rotateY(0.5);\r\n * greenLeg.rotateY(0.5);\r\n * blueLeg.rotateY(0.5);\r\n *\r\n * // Rotate table\r\n * table.rotateY(0.5);\r\n * table.rotateX(0.3);\r\n * });\r\n * ````\r\n *\r\n * ## Metadata\r\n *\r\n * As mentioned, we can also associate {@link MetaModel}s and {@link MetaObject}s with our Nodes and {@link Mesh}es,\r\n * within a {@link MetaScene}. See {@link MetaScene} for an example.\r\n *\r\n * @implements {Entity}\r\n */\r\nclass Node extends _Component_js__WEBPACK_IMPORTED_MODULE_1__.Component {\r\n\r\n /**\r\n * @constructor\r\n * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\r\n * @param {*} [cfg] Configs\r\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent scene, generated automatically when omitted.\r\n * @param {Boolean} [cfg.isModel] Specify ````true```` if this Mesh represents a model, in which case the Mesh will be registered by {@link Mesh#id} in {@link Scene#models} and may also have a corresponding {@link MetaModel} with matching {@link MetaModel#id}, registered by that ID in {@link MetaScene#metaModels}.\r\n * @param {Boolean} [cfg.isObject] Specify ````true```` if this Mesh represents an object, in which case the Mesh will be registered by {@link Mesh#id} in {@link Scene#objects} and may also have a corresponding {@link MetaObject} with matching {@link MetaObject#id}, registered by that ID in {@link MetaScene#metaObjects}.\r\n * @param {Node} [cfg.parent] The parent Node.\r\n * @param {Number[]} [cfg.origin] World-space origin for this Node.\r\n * @param {Number[]} [cfg.rtcCenter] Deprecated - renamed to ````origin````.\r\n * @param {Number[]} [cfg.position=[0,0,0]] Local 3D position.\r\n * @param {Number[]} [cfg.scale=[1,1,1]] Local scale.\r\n * @param {Number[]} [cfg.rotation=[0,0,0]] Local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\r\n * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] Local modelling transform matrix. Overrides the position, scale and rotation parameters.\r\n * @param {Number[]} [cfg.offset=[0,0,0]] World-space 3D translation offset. Translates the Node in World space, after modelling transforms.\r\n * @param {Boolean} [cfg.visible=true] Indicates if the Node is initially visible.\r\n * @param {Boolean} [cfg.culled=false] Indicates if the Node is initially culled from view.\r\n * @param {Boolean} [cfg.pickable=true] Indicates if the Node is initially pickable.\r\n * @param {Boolean} [cfg.clippable=true] Indicates if the Node is initially clippable.\r\n * @param {Boolean} [cfg.collidable=true] Indicates if the Node is initially included in boundary calculations.\r\n * @param {Boolean} [cfg.castsShadow=true] Indicates if the Node initially casts shadows.\r\n * @param {Boolean} [cfg.receivesShadow=true] Indicates if the Node initially receives shadows.\r\n * @param {Boolean} [cfg.xrayed=false] Indicates if the Node is initially xrayed.\r\n * @param {Boolean} [cfg.highlighted=false] Indicates if the Node is initially highlighted.\r\n * @param {Boolean} [cfg.selected=false] Indicates if the Mesh is initially selected.\r\n * @param {Boolean} [cfg.edges=false] Indicates if the Node's edges are initially emphasized.\r\n * @param {Number[]} [cfg.colorize=[1.0,1.0,1.0]] Node's initial RGB colorize color, multiplies by the rendered fragment colors.\r\n * @param {Number} [cfg.opacity=1.0] Node's initial opacity factor, multiplies by the rendered fragment alpha.\r\n * @param {Array} [cfg.children] Child Nodes or {@link Mesh}es to add initially. Children must be in the same {@link Scene} and will be removed first from whatever parents they may already have.\r\n * @param {Boolean} [cfg.inheritStates=true] Indicates if children given to this constructor should inherit rendering state from this parent as they are added. Rendering state includes {@link Node#visible}, {@link Node#culled}, {@link Node#pickable}, {@link Node#clippable}, {@link Node#castsShadow}, {@link Node#receivesShadow}, {@link Node#selected}, {@link Node#highlighted}, {@link Node#colorize} and {@link Node#opacity}.\r\n */\r\n constructor(owner, cfg = {}) {\r\n\r\n super(owner, cfg);\r\n\r\n this._parentNode = null;\r\n this._children = [];\r\n\r\n this._aabb = null;\r\n this._aabbDirty = true;\r\n\r\n this.scene._aabbDirty = true;\r\n\r\n this._numTriangles = 0;\r\n\r\n this._scale = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\r\n this._quaternion = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityQuaternion();\r\n this._rotation = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\r\n this._position = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\r\n this._offset = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\r\n\r\n this._localMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\r\n this._worldMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\r\n\r\n this._localMatrixDirty = true;\r\n this._worldMatrixDirty = true;\r\n\r\n if (cfg.matrix) {\r\n this.matrix = cfg.matrix;\r\n } else {\r\n this.scale = cfg.scale;\r\n this.position = cfg.position;\r\n if (cfg.quaternion) {\r\n } else {\r\n this.rotation = cfg.rotation;\r\n }\r\n }\r\n\r\n this._isModel = cfg.isModel;\r\n if (this._isModel) {\r\n this.scene._registerModel(this);\r\n }\r\n\r\n this._isObject = cfg.isObject;\r\n if (this._isObject) {\r\n this.scene._registerObject(this);\r\n }\r\n\r\n this.origin = cfg.origin;\r\n this.visible = cfg.visible;\r\n this.culled = cfg.culled;\r\n this.pickable = cfg.pickable;\r\n this.clippable = cfg.clippable;\r\n this.collidable = cfg.collidable;\r\n this.castsShadow = cfg.castsShadow;\r\n this.receivesShadow = cfg.receivesShadow;\r\n this.xrayed = cfg.xrayed;\r\n this.highlighted = cfg.highlighted;\r\n this.selected = cfg.selected;\r\n this.edges = cfg.edges;\r\n this.colorize = cfg.colorize;\r\n this.opacity = cfg.opacity;\r\n this.offset = cfg.offset;\r\n\r\n // Add children, which inherit state from this Node\r\n\r\n if (cfg.children) {\r\n const children = cfg.children;\r\n for (let i = 0, len = children.length; i < len; i++) {\r\n this.addChild(children[i], cfg.inheritStates);\r\n }\r\n }\r\n\r\n if (cfg.parentId) {\r\n const parentNode = this.scene.components[cfg.parentId];\r\n if (!parentNode) {\r\n this.error(\"Parent not found: '\" + cfg.parentId + \"'\");\r\n } else if (!parentNode.isNode) {\r\n this.error(\"Parent is not a Node: '\" + cfg.parentId + \"'\");\r\n } else {\r\n parentNode.addChild(this);\r\n }\r\n } else if (cfg.parent) {\r\n if (!cfg.parent.isNode) {\r\n this.error(\"Parent is not a Node\");\r\n }\r\n cfg.parent.addChild(this);\r\n }\r\n }\r\n\r\n //------------------------------------------------------------------------------------------------------------------\r\n // Entity members\r\n //------------------------------------------------------------------------------------------------------------------\r\n\r\n /**\r\n * Returns true to indicate that this Component is an Entity.\r\n * @type {Boolean}\r\n */\r\n get isEntity() {\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns ````true```` if this Mesh represents a model.\r\n *\r\n * When this returns ````true````, the Mesh will be registered by {@link Mesh#id} in {@link Scene#models} and\r\n * may also have a corresponding {@link MetaModel}.\r\n *\r\n * @type {Boolean}\r\n */\r\n get isModel() {\r\n return this._isModel;\r\n }\r\n\r\n /**\r\n * Returns ````true```` if this Node represents an object.\r\n *\r\n * When ````true```` the Node will be registered by {@link Node#id} in\r\n * {@link Scene#objects} and may also have a {@link MetaObject} with matching {@link MetaObject#id}.\r\n *\r\n * @type {Boolean}\r\n * @abstract\r\n */\r\n get isObject() {\r\n return this._isObject;\r\n }\r\n\r\n /**\r\n * Gets the Node's World-space 3D axis-aligned bounding box.\r\n *\r\n * Represented by a six-element Float64Array containing the min/max extents of the\r\n * axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n get aabb() {\r\n if (this._aabbDirty) {\r\n this._updateAABB();\r\n }\r\n return this._aabb;\r\n }\r\n\r\n /**\r\n * Sets the World-space origin for this Node.\r\n *\r\n * @type {Float64Array}\r\n */\r\n set origin(origin) {\r\n if (origin) {\r\n if (!this._origin) {\r\n this._origin = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\r\n }\r\n this._origin.set(origin);\r\n } else {\r\n if (this._origin) {\r\n this._origin = null;\r\n }\r\n }\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].origin = origin;\r\n }\r\n this.glRedraw();\r\n }\r\n\r\n /**\r\n * Gets the World-space origin for this Node.\r\n *\r\n * @type {Float64Array}\r\n */\r\n get origin() {\r\n return this._origin;\r\n }\r\n\r\n /**\r\n * Sets the World-space origin for this Node.\r\n *\r\n * Deprecated and replaced by {@link Node#origin}.\r\n *\r\n * @deprecated\r\n * @type {Float64Array}\r\n */\r\n set rtcCenter(rtcCenter) {\r\n this.origin = rtcCenter;\r\n }\r\n\r\n /**\r\n * Gets the World-space origin for this Node.\r\n *\r\n * Deprecated and replaced by {@link Node#origin}.\r\n *\r\n * @deprecated\r\n * @type {Float64Array}\r\n */\r\n get rtcCenter() {\r\n return this.origin;\r\n }\r\n\r\n /**\r\n * The number of triangles in this Node.\r\n *\r\n * @type {Number}\r\n */\r\n get numTriangles() {\r\n return this._numTriangles;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es are visible.\r\n *\r\n * Only rendered both {@link Node#visible} is ````true```` and {@link Node#culled} is ````false````.\r\n *\r\n * When {@link Node#isObject} and {@link Node#visible} are both ````true```` the Node will be\r\n * registered by {@link Node#id} in {@link Scene#visibleObjects}.\r\n *\r\n * @type {Boolean}\r\n */\r\n set visible(visible) {\r\n visible = visible !== false;\r\n this._visible = visible;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].visible = visible;\r\n }\r\n if (this._isObject) {\r\n this.scene._objectVisibilityUpdated(this, visible);\r\n }\r\n }\r\n\r\n /**\r\n * Gets if this Node is visible.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * When {@link Node#isObject} and {@link Node#visible} are both ````true```` the Node will be\r\n * registered by {@link Node#id} in {@link Scene#visibleObjects}.\r\n *\r\n * @type {Boolean}\r\n */\r\n get visible() {\r\n return this._visible;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es are xrayed.\r\n *\r\n * When {@link Node#isObject} and {@link Node#xrayed} are both ````true```` the Node will be\r\n * registered by {@link Node#id} in {@link Scene#xrayedObjects}.\r\n *\r\n * @type {Boolean}\r\n */\r\n set xrayed(xrayed) {\r\n xrayed = !!xrayed;\r\n this._xrayed = xrayed;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].xrayed = xrayed;\r\n }\r\n if (this._isObject) {\r\n this.scene._objectXRayedUpdated(this, xrayed);\r\n }\r\n }\r\n\r\n /**\r\n * Gets if this Node is xrayed.\r\n *\r\n * When {@link Node#isObject} and {@link Node#xrayed} are both ````true```` the Node will be\r\n * registered by {@link Node#id} in {@link Scene#xrayedObjects}.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Boolean}\r\n */\r\n get xrayed() {\r\n return this._xrayed;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es are highlighted.\r\n *\r\n * When {@link Node#isObject} and {@link Node#highlighted} are both ````true```` the Node will be\r\n * registered by {@link Node#id} in {@link Scene#highlightedObjects}.\r\n *\r\n * @type {Boolean}\r\n */\r\n set highlighted(highlighted) {\r\n highlighted = !!highlighted;\r\n this._highlighted = highlighted;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].highlighted = highlighted;\r\n }\r\n if (this._isObject) {\r\n this.scene._objectHighlightedUpdated(this, highlighted);\r\n }\r\n }\r\n\r\n /**\r\n * Gets if this Node is highlighted.\r\n *\r\n * When {@link Node#isObject} and {@link Node#highlighted} are both ````true```` the Node will be\r\n * registered by {@link Node#id} in {@link Scene#highlightedObjects}.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Boolean}\r\n */\r\n get highlighted() {\r\n return this._highlighted;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es are selected.\r\n *\r\n * When {@link Node#isObject} and {@link Node#selected} are both ````true```` the Node will be\r\n * registered by {@link Node#id} in {@link Scene#selectedObjects}.\r\n *\r\n * @type {Boolean}\r\n */\r\n set selected(selected) {\r\n selected = !!selected;\r\n this._selected = selected;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].selected = selected;\r\n }\r\n if (this._isObject) {\r\n this.scene._objectSelectedUpdated(this, selected);\r\n }\r\n }\r\n\r\n /**\r\n * Gets if this Node is selected.\r\n *\r\n * When {@link Node#isObject} and {@link Node#selected} are both ````true```` the Node will be\r\n * registered by {@link Node#id} in {@link Scene#selectedObjects}.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Boolean}\r\n */\r\n get selected() {\r\n return this._selected;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es are edge-enhanced.\r\n *\r\n * @type {Boolean}\r\n */\r\n set edges(edges) {\r\n edges = !!edges;\r\n this._edges = edges;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].edges = edges;\r\n }\r\n }\r\n\r\n /**\r\n * Gets if this Node's edges are enhanced.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Boolean}\r\n */\r\n get edges() {\r\n return this._edges;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es are culled.\r\n *\r\n * @type {Boolean}\r\n */\r\n set culled(culled) {\r\n culled = !!culled;\r\n this._culled = culled;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].culled = culled;\r\n }\r\n }\r\n\r\n /**\r\n * Gets if this Node is culled.\r\n *\r\n * @type {Boolean}\r\n */\r\n get culled() {\r\n return this._culled;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es are clippable.\r\n *\r\n * Clipping is done by the {@link SectionPlane}s in {@link Scene#clips}.\r\n *\r\n * @type {Boolean}\r\n */\r\n set clippable(clippable) {\r\n clippable = clippable !== false;\r\n this._clippable = clippable;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].clippable = clippable;\r\n }\r\n }\r\n\r\n /**\r\n * Gets if this Node is clippable.\r\n *\r\n * Clipping is done by the {@link SectionPlane}s in {@link Scene#clips}.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Boolean}\r\n */\r\n get clippable() {\r\n return this._clippable;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es are included in boundary calculations.\r\n *\r\n * @type {Boolean}\r\n */\r\n set collidable(collidable) {\r\n collidable = collidable !== false;\r\n this._collidable = collidable;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].collidable = collidable;\r\n }\r\n }\r\n\r\n /**\r\n * Gets if this Node is included in boundary calculations.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Boolean}\r\n */\r\n get collidable() {\r\n return this._collidable;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es are pickable.\r\n *\r\n * Picking is done via calls to {@link Scene#pick}.\r\n *\r\n * @type {Boolean}\r\n */\r\n set pickable(pickable) {\r\n pickable = pickable !== false;\r\n this._pickable = pickable;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].pickable = pickable;\r\n }\r\n }\r\n\r\n /**\r\n * Gets if to this Node is pickable.\r\n *\r\n * Picking is done via calls to {@link Scene#pick}.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Boolean}\r\n */\r\n get pickable() {\r\n return this._pickable;\r\n }\r\n\r\n /**\r\n * Sets the RGB colorize color for this Node and all child Nodes and {@link Mesh}es}.\r\n *\r\n * Multiplies by rendered fragment colors.\r\n *\r\n * Each element of the color is in range ````[0..1]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n set colorize(rgb) {\r\n let colorize = this._colorize;\r\n if (!colorize) {\r\n colorize = this._colorize = new Float32Array(4);\r\n colorize[3] = 1.0;\r\n }\r\n if (rgb) {\r\n colorize[0] = rgb[0];\r\n colorize[1] = rgb[1];\r\n colorize[2] = rgb[2];\r\n } else {\r\n colorize[0] = 1;\r\n colorize[1] = 1;\r\n colorize[2] = 1;\r\n }\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].colorize = colorize;\r\n }\r\n if (this._isObject) {\r\n const colorized = (!!rgb);\r\n this.scene._objectColorizeUpdated(this, colorized);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the RGB colorize color for this Node.\r\n *\r\n * Each element of the color is in range ````[0..1]````.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Number[]}\r\n */\r\n get colorize() {\r\n return this._colorize.slice(0, 3);\r\n }\r\n\r\n /**\r\n * Sets the opacity factor for this Node and all child Nodes and {@link Mesh}es.\r\n *\r\n * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\r\n *\r\n * @type {Number}\r\n */\r\n set opacity(opacity) {\r\n let colorize = this._colorize;\r\n if (!colorize) {\r\n colorize = this._colorize = new Float32Array(4);\r\n colorize[0] = 1;\r\n colorize[1] = 1;\r\n colorize[2] = 1;\r\n }\r\n colorize[3] = opacity !== null && opacity !== undefined ? opacity : 1.0;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].opacity = opacity;\r\n }\r\n if (this._isObject) {\r\n const opacityUpdated = (opacity !== null && opacity !== undefined);\r\n this.scene._objectOpacityUpdated(this, opacityUpdated);\r\n }\r\n }\r\n\r\n /**\r\n * Gets this Node's opacity factor.\r\n *\r\n * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Number}\r\n */\r\n get opacity() {\r\n return this._colorize[3];\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es cast shadows.\r\n *\r\n * @type {Boolean}\r\n */\r\n set castsShadow(castsShadow) {\r\n castsShadow = !!castsShadow;\r\n this._castsShadow = castsShadow;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].castsShadow = castsShadow;\r\n }\r\n }\r\n\r\n /**\r\n * Gets if this Node casts shadows.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Boolean}\r\n */\r\n get castsShadow() {\r\n return this._castsShadow;\r\n }\r\n\r\n /**\r\n * Sets if this Node and all child Nodes and {@link Mesh}es can have shadows cast upon them.\r\n *\r\n * @type {Boolean}\r\n */\r\n set receivesShadow(receivesShadow) {\r\n receivesShadow = !!receivesShadow;\r\n this._receivesShadow = receivesShadow;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].receivesShadow = receivesShadow;\r\n }\r\n }\r\n\r\n /**\r\n * Whether or not to this Node can have shadows cast upon it.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Boolean}\r\n */\r\n get receivesShadow() {\r\n return this._receivesShadow;\r\n }\r\n\r\n /**\r\n * Gets if this Node can have Scalable Ambient Obscurance (SAO) applied to it.\r\n *\r\n * SAO is configured by {@link SAO}.\r\n *\r\n * @type {Boolean}\r\n * @abstract\r\n */\r\n get saoEnabled() {\r\n return false; // TODO: Support SAO on Nodes\r\n }\r\n\r\n\r\n /**\r\n * Sets the 3D World-space offset for this Node and all child Nodes and {@link Mesh}es}.\r\n *\r\n * The offset dynamically translates those components in World-space.\r\n *\r\n * Default value is ````[0, 0, 0]````.\r\n *\r\n * Note that child Nodes and {@link Mesh}es may subsequently be given different values for this property.\r\n *\r\n * @type {Number[]}\r\n */\r\n set offset(offset) {\r\n if (offset) {\r\n this._offset[0] = offset[0];\r\n this._offset[1] = offset[1];\r\n this._offset[2] = offset[2];\r\n } else {\r\n this._offset[0] = 0;\r\n this._offset[1] = 0;\r\n this._offset[2] = 0;\r\n }\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i].offset = this._offset;\r\n }\r\n if (this._isObject) {\r\n this.scene._objectOffsetUpdated(this, offset);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the Node's 3D World-space offset.\r\n *\r\n * Default value is ````[0, 0, 0]````.\r\n *\r\n * Child Nodes and {@link Mesh}es may have different values for this property.\r\n *\r\n * @type {Number[]}\r\n */\r\n get offset() {\r\n return this._offset;\r\n }\r\n\r\n\r\n //------------------------------------------------------------------------------------------------------------------\r\n // Node members\r\n //------------------------------------------------------------------------------------------------------------------\r\n\r\n /**\r\n * Returns true to indicate that this Component is a Node.\r\n * @type {Boolean}\r\n */\r\n get isNode() {\r\n return true;\r\n }\r\n\r\n _setLocalMatrixDirty() {\r\n this._localMatrixDirty = true;\r\n this._setWorldMatrixDirty();\r\n }\r\n\r\n _setWorldMatrixDirty() {\r\n this._worldMatrixDirty = true;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n this._children[i]._setWorldMatrixDirty();\r\n }\r\n }\r\n\r\n _buildWorldMatrix() {\r\n const localMatrix = this.matrix;\r\n if (!this._parentNode) {\r\n for (let i = 0, len = localMatrix.length; i < len; i++) {\r\n this._worldMatrix[i] = localMatrix[i];\r\n }\r\n } else {\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.mulMat4(this._parentNode.worldMatrix, localMatrix, this._worldMatrix);\r\n }\r\n this._worldMatrixDirty = false;\r\n }\r\n\r\n _setSubtreeAABBsDirty(node) {\r\n node._aabbDirty = true;\r\n if (node._children) {\r\n for (let i = 0, len = node._children.length; i < len; i++) {\r\n this._setSubtreeAABBsDirty(node._children[i]);\r\n }\r\n }\r\n }\r\n\r\n _setAABBDirty() {\r\n this._setSubtreeAABBsDirty(this);\r\n if (this.collidable) {\r\n for (let node = this; node; node = node._parentNode) {\r\n node._aabbDirty = true;\r\n }\r\n }\r\n }\r\n\r\n _updateAABB() {\r\n this.scene._aabbDirty = true;\r\n if (!this._aabb) {\r\n this._aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.AABB3();\r\n }\r\n if (this._buildAABB) {\r\n this._buildAABB(this.worldMatrix, this._aabb); // Mesh or VBOSceneModel\r\n } else { // Node | Node | Model\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.collapseAABB3(this._aabb);\r\n let node;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n node = this._children[i];\r\n if (!node.collidable) {\r\n continue;\r\n }\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.expandAABB3(this._aabb, node.aabb);\r\n }\r\n }\r\n this._aabbDirty = false;\r\n }\r\n\r\n /**\r\n * Adds a child Node or {@link Mesh}.\r\n *\r\n * The child must be a Node or {@link Mesh} in the same {@link Scene}.\r\n *\r\n * If the child already has a parent, will be removed from that parent first.\r\n *\r\n * Does nothing if already a child.\r\n *\r\n * @param {Node|Mesh|String} child Instance or ID of the child to add.\r\n * @param [inheritStates=false] Indicates if the child should inherit rendering states from this parent as it is added. Rendering state includes {@link Node#visible}, {@link Node#culled}, {@link Node#pickable}, {@link Node#clippable}, {@link Node#castsShadow}, {@link Node#receivesShadow}, {@link Node#selected}, {@link Node#highlighted}, {@link Node#colorize} and {@link Node#opacity}.\r\n * @returns {Node|Mesh} The child.\r\n */\r\n addChild(child, inheritStates) {\r\n if (_utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.isNumeric(child) || _utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.isString(child)) {\r\n const nodeId = child;\r\n child = this.scene.component[nodeId];\r\n if (!child) {\r\n this.warn(\"Component not found: \" + _utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.inQuotes(nodeId));\r\n return;\r\n }\r\n if (!child.isNode && !child.isMesh) {\r\n this.error(\"Not a Node or Mesh: \" + nodeId);\r\n return;\r\n }\r\n } else {\r\n if (!child.isNode && !child.isMesh) {\r\n this.error(\"Not a Node or Mesh: \" + child.id);\r\n return;\r\n }\r\n if (child._parentNode) {\r\n if (child._parentNode.id === this.id) {\r\n this.warn(\"Already a child: \" + child.id);\r\n return;\r\n }\r\n child._parentNode.removeChild(child);\r\n }\r\n }\r\n const id = child.id;\r\n if (child.scene.id !== this.scene.id) {\r\n this.error(\"Child not in same Scene: \" + child.id);\r\n return;\r\n }\r\n this._children.push(child);\r\n child._parentNode = this;\r\n if (!!inheritStates) {\r\n child.visible = this.visible;\r\n child.culled = this.culled;\r\n child.xrayed = this.xrayed;\r\n child.highlited = this.highlighted;\r\n child.selected = this.selected;\r\n child.edges = this.edges;\r\n child.clippable = this.clippable;\r\n child.pickable = this.pickable;\r\n child.collidable = this.collidable;\r\n child.castsShadow = this.castsShadow;\r\n child.receivesShadow = this.receivesShadow;\r\n child.colorize = this.colorize;\r\n child.opacity = this.opacity;\r\n child.offset = this.offset;\r\n }\r\n child._setWorldMatrixDirty();\r\n child._setAABBDirty();\r\n this._numTriangles += child.numTriangles;\r\n return child;\r\n }\r\n\r\n /**\r\n * Removes the given child Node or {@link Mesh}.\r\n *\r\n * @param {Node|Mesh} child Child to remove.\r\n */\r\n removeChild(child) {\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n if (this._children[i].id === child.id) {\r\n child._parentNode = null;\r\n this._children = this._children.splice(i, 1);\r\n child._setWorldMatrixDirty();\r\n child._setAABBDirty();\r\n this._setAABBDirty();\r\n this._numTriangles -= child.numTriangles;\r\n return;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Removes all child Nodes and {@link Mesh}es.\r\n */\r\n removeChildren() {\r\n let child;\r\n for (let i = 0, len = this._children.length; i < len; i++) {\r\n child = this._children[i];\r\n child._parentNode = null;\r\n child._setWorldMatrixDirty();\r\n child._setAABBDirty();\r\n this._numTriangles -= child.numTriangles;\r\n }\r\n this._children = [];\r\n this._setAABBDirty();\r\n }\r\n\r\n /**\r\n * Number of child Nodes or {@link Mesh}es.\r\n *\r\n * @type {Number}\r\n */\r\n get numChildren() {\r\n return this._children.length;\r\n }\r\n\r\n /**\r\n * Array of child Nodes or {@link Mesh}es.\r\n *\r\n * @type {Array}\r\n */\r\n get children() {\r\n return this._children;\r\n }\r\n\r\n /**\r\n * The parent Node.\r\n *\r\n * The parent Node may also be set by passing the Node to the parent's {@link Node#addChild} method.\r\n *\r\n * @type {Node}\r\n */\r\n set parent(node) {\r\n if (_utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.isNumeric(node) || _utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.isString(node)) {\r\n const nodeId = node;\r\n node = this.scene.components[nodeId];\r\n if (!node) {\r\n this.warn(\"Node not found: \" + _utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.inQuotes(nodeId));\r\n return;\r\n }\r\n if (!node.isNode) {\r\n this.error(\"Not a Node: \" + node.id);\r\n return;\r\n }\r\n }\r\n if (node.scene.id !== this.scene.id) {\r\n this.error(\"Node not in same Scene: \" + node.id);\r\n return;\r\n }\r\n if (this._parentNode && this._parentNode.id === node.id) {\r\n this.warn(\"Already a child of Node: \" + node.id);\r\n return;\r\n }\r\n node.addChild(this);\r\n }\r\n\r\n /**\r\n * The parent Node.\r\n *\r\n * @type {Node}\r\n */\r\n get parent() {\r\n return this._parentNode;\r\n }\r\n\r\n /**\r\n * Sets the Node's local translation.\r\n *\r\n * Default value is ````[0,0,0]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n set position(value) {\r\n this._position.set(value || [0, 0, 0]);\r\n this._setLocalMatrixDirty();\r\n this._setAABBDirty();\r\n this.glRedraw();\r\n }\r\n\r\n /**\r\n * Gets the Node's local translation.\r\n *\r\n * Default value is ````[0,0,0]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n get position() {\r\n return this._position;\r\n }\r\n\r\n /**\r\n * Sets the Node's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\r\n *\r\n * Default value is ````[0,0,0]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n set rotation(value) {\r\n this._rotation.set(value || [0, 0, 0]);\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\r\n this._setLocalMatrixDirty();\r\n this._setAABBDirty();\r\n this.glRedraw();\r\n }\r\n\r\n /**\r\n * Gets the Node's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\r\n *\r\n * Default value is ````[0,0,0]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n get rotation() {\r\n return this._rotation;\r\n }\r\n\r\n /**\r\n * Sets the Node's local rotation quaternion.\r\n *\r\n * Default value is ````[0,0,0,1]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n set quaternion(value) {\r\n this._quaternion.set(value || [0, 0, 0, 1]);\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.quaternionToEuler(this._quaternion, \"XYZ\", this._rotation);\r\n this._setLocalMatrixDirty();\r\n this._setAABBDirty();\r\n this.glRedraw();\r\n }\r\n\r\n /**\r\n * Gets the Node's local rotation quaternion.\r\n *\r\n * Default value is ````[0,0,0,1]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n get quaternion() {\r\n return this._quaternion;\r\n }\r\n\r\n /**\r\n * Sets the Node's local scale.\r\n *\r\n * Default value is ````[1,1,1]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n set scale(value) {\r\n this._scale.set(value || [1, 1, 1]);\r\n this._setLocalMatrixDirty();\r\n this._setAABBDirty();\r\n this.glRedraw();\r\n }\r\n\r\n /**\r\n * Gets the Node's local scale.\r\n *\r\n * Default value is ````[1,1,1]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n get scale() {\r\n return this._scale;\r\n }\r\n\r\n /**\r\n * Sets the Node's local modeling transform matrix.\r\n *\r\n * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n set matrix(value) {\r\n if (!this._localMatrix) {\r\n this._localMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\r\n }\r\n this._localMatrix.set(value || identityMat);\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.decomposeMat4(this._localMatrix, this._position, this._quaternion, this._scale);\r\n this._localMatrixDirty = false;\r\n this._setWorldMatrixDirty();\r\n this._setAABBDirty();\r\n this.glRedraw();\r\n }\r\n\r\n /**\r\n * Gets the Node's local modeling transform matrix.\r\n *\r\n * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\r\n *\r\n * @type {Number[]}\r\n */\r\n get matrix() {\r\n if (this._localMatrixDirty) {\r\n if (!this._localMatrix) {\r\n this._localMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\r\n }\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.composeMat4(this._position, this._quaternion, this._scale, this._localMatrix);\r\n this._localMatrixDirty = false;\r\n }\r\n return this._localMatrix;\r\n }\r\n\r\n /**\r\n * Gets the Node's World matrix.\r\n *\r\n * @property worldMatrix\r\n * @type {Number[]}\r\n */\r\n get worldMatrix() {\r\n if (this._worldMatrixDirty) {\r\n this._buildWorldMatrix();\r\n }\r\n return this._worldMatrix;\r\n }\r\n\r\n /**\r\n * Rotates the Node about the given local axis by the given increment.\r\n *\r\n * @param {Number[]} axis Local axis about which to rotate.\r\n * @param {Number} angle Angle increment in degrees.\r\n */\r\n rotate(axis, angle) {\r\n angleAxis[0] = axis[0];\r\n angleAxis[1] = axis[1];\r\n angleAxis[2] = axis[2];\r\n angleAxis[3] = angle * _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.DEGTORAD;\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.angleAxisToQuaternion(angleAxis, q1);\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.mulQuaternions(this.quaternion, q1, q2);\r\n this.quaternion = q2;\r\n this._setLocalMatrixDirty();\r\n this._setAABBDirty();\r\n this.glRedraw();\r\n return this;\r\n }\r\n\r\n /**\r\n * Rotates the Node about the given World-space axis by the given increment.\r\n *\r\n * @param {Number[]} axis Local axis about which to rotate.\r\n * @param {Number} angle Angle increment in degrees.\r\n */\r\n rotateOnWorldAxis(axis, angle) {\r\n angleAxis[0] = axis[0];\r\n angleAxis[1] = axis[1];\r\n angleAxis[2] = axis[2];\r\n angleAxis[3] = angle * _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.DEGTORAD;\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.angleAxisToQuaternion(angleAxis, q1);\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.mulQuaternions(q1, this.quaternion, q1);\r\n //this.quaternion.premultiply(q1);\r\n return this;\r\n }\r\n\r\n /**\r\n * Rotates the Node about the local X-axis by the given increment.\r\n *\r\n * @param {Number} angle Angle increment in degrees.\r\n */\r\n rotateX(angle) {\r\n return this.rotate(xAxis, angle);\r\n }\r\n\r\n /**\r\n * Rotates the Node about the local Y-axis by the given increment.\r\n *\r\n * @param {Number} angle Angle increment in degrees.\r\n */\r\n rotateY(angle) {\r\n return this.rotate(yAxis, angle);\r\n }\r\n\r\n /**\r\n * Rotates the Node about the local Z-axis by the given increment.\r\n *\r\n * @param {Number} angle Angle increment in degrees.\r\n */\r\n rotateZ(angle) {\r\n return this.rotate(zAxis, angle);\r\n }\r\n\r\n /**\r\n * Translates the Node along local space vector by the given increment.\r\n *\r\n * @param {Number[]} axis Normalized local space 3D vector along which to translate.\r\n * @param {Number} distance Distance to translate along the vector.\r\n */\r\n translate(axis, distance) {\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3ApplyQuaternion(this.quaternion, axis, veca);\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.mulVec3Scalar(veca, distance, vecb);\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.addVec3(this.position, vecb, this.position);\r\n this._setLocalMatrixDirty();\r\n this._setAABBDirty();\r\n this.glRedraw();\r\n return this;\r\n }\r\n\r\n /**\r\n * Translates the Node along the local X-axis by the given increment.\r\n *\r\n * @param {Number} distance Distance to translate along the X-axis.\r\n */\r\n translateX(distance) {\r\n return this.translate(xAxis, distance);\r\n }\r\n\r\n /**\r\n * Translates the Node along the local Y-axis by the given increment.\r\n *\r\n * @param {Number} distance Distance to translate along the Y-axis.\r\n */\r\n translateY(distance) {\r\n return this.translate(yAxis, distance);\r\n }\r\n\r\n /**\r\n * Translates the Node along the local Z-axis by the given increment.\r\n *\r\n * @param {Number} distance Distance to translate along the Z-axis.\r\n */\r\n translateZ(distance) {\r\n return this.translate(zAxis, distance);\r\n }\r\n\r\n //------------------------------------------------------------------------------------------------------------------\r\n // Component members\r\n //------------------------------------------------------------------------------------------------------------------\r\n\r\n /**\r\n @private\r\n */\r\n get type() {\r\n return \"Node\";\r\n }\r\n\r\n /**\r\n * Destroys this Node.\r\n */\r\n destroy() {\r\n super.destroy();\r\n if (this._parentNode) {\r\n this._parentNode.removeChild(this);\r\n }\r\n if (this._isObject) {\r\n this.scene._deregisterObject(this);\r\n if (this._visible) {\r\n this.scene._objectVisibilityUpdated(this, false, false);\r\n }\r\n if (this._xrayed) {\r\n this.scene._objectXRayedUpdated(this, false, false);\r\n }\r\n if (this._selected) {\r\n this.scene._objectSelectedUpdated(this, false, false);\r\n }\r\n if (this._highlighted) {\r\n this.scene._objectHighlightedUpdated(this, false, false);\r\n }\r\n this.scene._objectColorizeUpdated(this, false);\r\n this.scene._objectOpacityUpdated(this, false);\r\n if (this.offset.some((v) => v !== 0))\r\n this.scene._objectOffsetUpdated(this, false);\r\n }\r\n if (this._isModel) {\r\n this.scene._deregisterModel(this);\r\n }\r\n if (this._children.length) {\r\n // Clone the _children before iterating, so our children don't mess us up when calling removeChild().\r\n const tempChildList = this._children.splice();\r\n let child;\r\n for (let i = 0, len = tempChildList.length; i < len; i++) {\r\n child = tempChildList[i];\r\n child.destroy();\r\n }\r\n }\r\n this._children = [];\r\n this._setAABBDirty();\r\n this.scene._aabbDirty = true;\r\n }\r\n\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/nodes/Node.js?");
4737
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Node: () => (/* binding */ Node)\n/* harmony export */ });\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n\n\n\n\nconst angleAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec4(4);\nconst q1 = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec4();\nconst q2 = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec4();\nconst xAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3([1, 0, 0]);\nconst yAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3([0, 1, 0]);\nconst zAxis = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3([0, 0, 1]);\n\nconst veca = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3(3);\nconst vecb = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3(3);\n\nconst identityMat = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\n\n/**\n * @desc An {@link Entity} that is a scene graph node that can have child Nodes and {@link Mesh}es.\n *\n * ## Usage\n *\n * The example below is the same as the one given for {@link Mesh}, since the two classes work together. In this example,\n * we'll create a scene graph in which a root Node represents a group and the {@link Mesh}s are leaves. Since Node\n * implements {@link Entity}, we can designate the root Node as a model, causing it to be registered by its ID in {@link Scene#models}.\n *\n * Since {@link Mesh} also implements {@link Entity}, we can designate the leaf {@link Mesh}es as objects, causing them to\n * be registered by their IDs in {@link Scene#objects}.\n *\n * We can then find those {@link Entity} types in {@link Scene#models} and {@link Scene#objects}.\n *\n * We can also update properties of our object-Meshes via calls to {@link Scene#setObjectsHighlighted} etc.\n *\n * [[Run this example](/examples/#sceneRepresentation_SceneGraph)]\n *\n * ````javascript\n * import {Viewer, Mesh, Node, PhongMaterial} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * new Node(viewer.scene, {\n * id: \"table\",\n * isModel: true, // <---------- Node represents a model, so is registered by ID in viewer.scene.models\n * rotation: [0, 50, 0],\n * position: [0, 0, 0],\n * scale: [1, 1, 1],\n *\n * children: [\n *\n * new Mesh(viewer.scene, { // Red table leg\n * id: \"redLeg\",\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * material: new PhongMaterial(viewer.scene, {\n * diffuse: [1, 0.3, 0.3]\n * })\n * }),\n *\n * new Mesh(viewer.scene, { // Green table leg\n * id: \"greenLeg\",\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n * position: [4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * material: new PhongMaterial(viewer.scene, {\n * diffuse: [0.3, 1.0, 0.3]\n * })\n * }),\n *\n * new Mesh(viewer.scene, {// Blue table leg\n * id: \"blueLeg\",\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n * position: [4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * material: new PhongMaterial(viewer.scene, {\n * diffuse: [0.3, 0.3, 1.0]\n * })\n * }),\n *\n * new Mesh(viewer.scene, { // Yellow table leg\n * id: \"yellowLeg\",\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n * position: [-4, -6, 4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * material: new PhongMaterial(viewer.scene, {\n * diffuse: [1.0, 1.0, 0.0]\n * })\n * }),\n *\n * new Mesh(viewer.scene, { // Purple table top\n * id: \"tableTop\",\n * isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n * position: [0, -3, 0],\n * scale: [6, 0.5, 6],\n * rotation: [0, 0, 0],\n * material: new PhongMaterial(viewer.scene, {\n * diffuse: [1.0, 0.3, 1.0]\n * })\n * })\n * ]\n * });\n *\n * // Find Nodes and Meshes by their IDs\n *\n * var table = viewer.scene.models[\"table\"]; // Since table Node has isModel == true\n *\n * var redLeg = viewer.scene.objects[\"redLeg\"]; // Since the Meshes have isObject == true\n * var greenLeg = viewer.scene.objects[\"greenLeg\"];\n * var blueLeg = viewer.scene.objects[\"blueLeg\"];\n *\n * // Highlight one of the table leg Meshes\n *\n * viewer.scene.setObjectsHighlighted([\"redLeg\"], true); // Since the Meshes have isObject == true\n *\n * // Periodically update transforms on our Nodes and Meshes\n *\n * viewer.scene.on(\"tick\", function () {\n *\n * // Rotate legs\n * redLeg.rotateY(0.5);\n * greenLeg.rotateY(0.5);\n * blueLeg.rotateY(0.5);\n *\n * // Rotate table\n * table.rotateY(0.5);\n * table.rotateX(0.3);\n * });\n * ````\n *\n * ## Metadata\n *\n * As mentioned, we can also associate {@link MetaModel}s and {@link MetaObject}s with our Nodes and {@link Mesh}es,\n * within a {@link MetaScene}. See {@link MetaScene} for an example.\n *\n * @implements {Entity}\n */\nclass Node extends _Component_js__WEBPACK_IMPORTED_MODULE_1__.Component {\n\n /**\n * @constructor\n * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent scene, generated automatically when omitted.\n * @param {Boolean} [cfg.isModel] Specify ````true```` if this Mesh represents a model, in which case the Mesh will be registered by {@link Mesh#id} in {@link Scene#models} and may also have a corresponding {@link MetaModel} with matching {@link MetaModel#id}, registered by that ID in {@link MetaScene#metaModels}.\n * @param {Boolean} [cfg.isObject] Specify ````true```` if this Mesh represents an object, in which case the Mesh will be registered by {@link Mesh#id} in {@link Scene#objects} and may also have a corresponding {@link MetaObject} with matching {@link MetaObject#id}, registered by that ID in {@link MetaScene#metaObjects}.\n * @param {Node} [cfg.parent] The parent Node.\n * @param {Number[]} [cfg.origin] World-space origin for this Node.\n * @param {Number[]} [cfg.rtcCenter] Deprecated - renamed to ````origin````.\n * @param {Number[]} [cfg.position=[0,0,0]] Local 3D position.\n * @param {Number[]} [cfg.scale=[1,1,1]] Local scale.\n * @param {Number[]} [cfg.rotation=[0,0,0]] Local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] Local modelling transform matrix. Overrides the position, scale and rotation parameters.\n * @param {Number[]} [cfg.offset=[0,0,0]] World-space 3D translation offset. Translates the Node in World space, after modelling transforms.\n * @param {Boolean} [cfg.visible=true] Indicates if the Node is initially visible.\n * @param {Boolean} [cfg.culled=false] Indicates if the Node is initially culled from view.\n * @param {Boolean} [cfg.pickable=true] Indicates if the Node is initially pickable.\n * @param {Boolean} [cfg.clippable=true] Indicates if the Node is initially clippable.\n * @param {Boolean} [cfg.collidable=true] Indicates if the Node is initially included in boundary calculations.\n * @param {Boolean} [cfg.castsShadow=true] Indicates if the Node initially casts shadows.\n * @param {Boolean} [cfg.receivesShadow=true] Indicates if the Node initially receives shadows.\n * @param {Boolean} [cfg.xrayed=false] Indicates if the Node is initially xrayed.\n * @param {Boolean} [cfg.highlighted=false] Indicates if the Node is initially highlighted.\n * @param {Boolean} [cfg.selected=false] Indicates if the Mesh is initially selected.\n * @param {Boolean} [cfg.edges=false] Indicates if the Node's edges are initially emphasized.\n * @param {Number[]} [cfg.colorize=[1.0,1.0,1.0]] Node's initial RGB colorize color, multiplies by the rendered fragment colors.\n * @param {Number} [cfg.opacity=1.0] Node's initial opacity factor, multiplies by the rendered fragment alpha.\n * @param {Array} [cfg.children] Child Nodes or {@link Mesh}es to add initially. Children must be in the same {@link Scene} and will be removed first from whatever parents they may already have.\n * @param {Boolean} [cfg.inheritStates=true] Indicates if children given to this constructor should inherit rendering state from this parent as they are added. Rendering state includes {@link Node#visible}, {@link Node#culled}, {@link Node#pickable}, {@link Node#clippable}, {@link Node#castsShadow}, {@link Node#receivesShadow}, {@link Node#selected}, {@link Node#highlighted}, {@link Node#colorize} and {@link Node#opacity}.\n */\n constructor(owner, cfg = {}) {\n\n super(owner, cfg);\n\n this._parentNode = null;\n this._children = [];\n\n this._aabb = null;\n this._aabbDirty = true;\n\n this.scene._aabbDirty = true;\n\n this._numTriangles = 0;\n\n this._scale = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\n this._quaternion = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityQuaternion();\n this._rotation = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\n this._position = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\n this._offset = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\n\n this._localMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\n this._worldMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\n\n this._localMatrixDirty = true;\n this._worldMatrixDirty = true;\n\n if (cfg.matrix) {\n this.matrix = cfg.matrix;\n } else {\n this.scale = cfg.scale;\n this.position = cfg.position;\n if (cfg.quaternion) {\n } else {\n this.rotation = cfg.rotation;\n }\n }\n\n this._isModel = cfg.isModel;\n if (this._isModel) {\n this.scene._registerModel(this);\n }\n\n this._isObject = cfg.isObject;\n if (this._isObject) {\n this.scene._registerObject(this);\n }\n\n this.origin = cfg.origin;\n this.visible = cfg.visible;\n this.culled = cfg.culled;\n this.pickable = cfg.pickable;\n this.clippable = cfg.clippable;\n this.collidable = cfg.collidable;\n this.castsShadow = cfg.castsShadow;\n this.receivesShadow = cfg.receivesShadow;\n this.xrayed = cfg.xrayed;\n this.highlighted = cfg.highlighted;\n this.selected = cfg.selected;\n this.edges = cfg.edges;\n this.colorize = cfg.colorize;\n this.opacity = cfg.opacity;\n this.offset = cfg.offset;\n\n // Add children, which inherit state from this Node\n\n if (cfg.children) {\n const children = cfg.children;\n for (let i = 0, len = children.length; i < len; i++) {\n this.addChild(children[i], cfg.inheritStates);\n }\n }\n\n if (cfg.parentId) {\n const parentNode = this.scene.components[cfg.parentId];\n if (!parentNode) {\n this.error(\"Parent not found: '\" + cfg.parentId + \"'\");\n } else if (!parentNode.isNode) {\n this.error(\"Parent is not a Node: '\" + cfg.parentId + \"'\");\n } else {\n parentNode.addChild(this);\n }\n } else if (cfg.parent) {\n if (!cfg.parent.isNode) {\n this.error(\"Parent is not a Node\");\n }\n cfg.parent.addChild(this);\n }\n }\n\n //------------------------------------------------------------------------------------------------------------------\n // Entity members\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Returns true to indicate that this Component is an Entity.\n * @type {Boolean}\n */\n get isEntity() {\n return true;\n }\n\n /**\n * Returns ````true```` if this Mesh represents a model.\n *\n * When this returns ````true````, the Mesh will be registered by {@link Mesh#id} in {@link Scene#models} and\n * may also have a corresponding {@link MetaModel}.\n *\n * @type {Boolean}\n */\n get isModel() {\n return this._isModel;\n }\n\n /**\n * Returns ````true```` if this Node represents an object.\n *\n * When ````true```` the Node will be registered by {@link Node#id} in\n * {@link Scene#objects} and may also have a {@link MetaObject} with matching {@link MetaObject#id}.\n *\n * @type {Boolean}\n * @abstract\n */\n get isObject() {\n return this._isObject;\n }\n\n /**\n * Gets the Node's World-space 3D axis-aligned bounding box.\n *\n * Represented by a six-element Float64Array containing the min/max extents of the\n * axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n *\n * @type {Number[]}\n */\n get aabb() {\n if (this._aabbDirty) {\n this._updateAABB();\n }\n return this._aabb;\n }\n\n /**\n * Sets the World-space origin for this Node.\n *\n * @type {Float64Array}\n */\n set origin(origin) {\n if (origin) {\n if (!this._origin) {\n this._origin = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\n }\n this._origin.set(origin);\n } else {\n if (this._origin) {\n this._origin = null;\n }\n }\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].origin = origin;\n }\n this.glRedraw();\n }\n\n /**\n * Gets the World-space origin for this Node.\n *\n * @type {Float64Array}\n */\n get origin() {\n return this._origin;\n }\n\n /**\n * Sets the World-space origin for this Node.\n *\n * Deprecated and replaced by {@link Node#origin}.\n *\n * @deprecated\n * @type {Float64Array}\n */\n set rtcCenter(rtcCenter) {\n this.origin = rtcCenter;\n }\n\n /**\n * Gets the World-space origin for this Node.\n *\n * Deprecated and replaced by {@link Node#origin}.\n *\n * @deprecated\n * @type {Float64Array}\n */\n get rtcCenter() {\n return this.origin;\n }\n\n /**\n * The number of triangles in this Node.\n *\n * @type {Number}\n */\n get numTriangles() {\n return this._numTriangles;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es are visible.\n *\n * Only rendered both {@link Node#visible} is ````true```` and {@link Node#culled} is ````false````.\n *\n * When {@link Node#isObject} and {@link Node#visible} are both ````true```` the Node will be\n * registered by {@link Node#id} in {@link Scene#visibleObjects}.\n *\n * @type {Boolean}\n */\n set visible(visible) {\n visible = visible !== false;\n this._visible = visible;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].visible = visible;\n }\n if (this._isObject) {\n this.scene._objectVisibilityUpdated(this, visible);\n }\n }\n\n /**\n * Gets if this Node is visible.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * When {@link Node#isObject} and {@link Node#visible} are both ````true```` the Node will be\n * registered by {@link Node#id} in {@link Scene#visibleObjects}.\n *\n * @type {Boolean}\n */\n get visible() {\n return this._visible;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es are xrayed.\n *\n * When {@link Node#isObject} and {@link Node#xrayed} are both ````true```` the Node will be\n * registered by {@link Node#id} in {@link Scene#xrayedObjects}.\n *\n * @type {Boolean}\n */\n set xrayed(xrayed) {\n xrayed = !!xrayed;\n this._xrayed = xrayed;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].xrayed = xrayed;\n }\n if (this._isObject) {\n this.scene._objectXRayedUpdated(this, xrayed);\n }\n }\n\n /**\n * Gets if this Node is xrayed.\n *\n * When {@link Node#isObject} and {@link Node#xrayed} are both ````true```` the Node will be\n * registered by {@link Node#id} in {@link Scene#xrayedObjects}.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Boolean}\n */\n get xrayed() {\n return this._xrayed;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es are highlighted.\n *\n * When {@link Node#isObject} and {@link Node#highlighted} are both ````true```` the Node will be\n * registered by {@link Node#id} in {@link Scene#highlightedObjects}.\n *\n * @type {Boolean}\n */\n set highlighted(highlighted) {\n highlighted = !!highlighted;\n this._highlighted = highlighted;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].highlighted = highlighted;\n }\n if (this._isObject) {\n this.scene._objectHighlightedUpdated(this, highlighted);\n }\n }\n\n /**\n * Gets if this Node is highlighted.\n *\n * When {@link Node#isObject} and {@link Node#highlighted} are both ````true```` the Node will be\n * registered by {@link Node#id} in {@link Scene#highlightedObjects}.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Boolean}\n */\n get highlighted() {\n return this._highlighted;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es are selected.\n *\n * When {@link Node#isObject} and {@link Node#selected} are both ````true```` the Node will be\n * registered by {@link Node#id} in {@link Scene#selectedObjects}.\n *\n * @type {Boolean}\n */\n set selected(selected) {\n selected = !!selected;\n this._selected = selected;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].selected = selected;\n }\n if (this._isObject) {\n this.scene._objectSelectedUpdated(this, selected);\n }\n }\n\n /**\n * Gets if this Node is selected.\n *\n * When {@link Node#isObject} and {@link Node#selected} are both ````true```` the Node will be\n * registered by {@link Node#id} in {@link Scene#selectedObjects}.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Boolean}\n */\n get selected() {\n return this._selected;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es are edge-enhanced.\n *\n * @type {Boolean}\n */\n set edges(edges) {\n edges = !!edges;\n this._edges = edges;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].edges = edges;\n }\n }\n\n /**\n * Gets if this Node's edges are enhanced.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Boolean}\n */\n get edges() {\n return this._edges;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es are culled.\n *\n * @type {Boolean}\n */\n set culled(culled) {\n culled = !!culled;\n this._culled = culled;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].culled = culled;\n }\n }\n\n /**\n * Gets if this Node is culled.\n *\n * @type {Boolean}\n */\n get culled() {\n return this._culled;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es are clippable.\n *\n * Clipping is done by the {@link SectionPlane}s in {@link Scene#clips}.\n *\n * @type {Boolean}\n */\n set clippable(clippable) {\n clippable = clippable !== false;\n this._clippable = clippable;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].clippable = clippable;\n }\n }\n\n /**\n * Gets if this Node is clippable.\n *\n * Clipping is done by the {@link SectionPlane}s in {@link Scene#clips}.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Boolean}\n */\n get clippable() {\n return this._clippable;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es are included in boundary calculations.\n *\n * @type {Boolean}\n */\n set collidable(collidable) {\n collidable = collidable !== false;\n this._collidable = collidable;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].collidable = collidable;\n }\n }\n\n /**\n * Gets if this Node is included in boundary calculations.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Boolean}\n */\n get collidable() {\n return this._collidable;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es are pickable.\n *\n * Picking is done via calls to {@link Scene#pick}.\n *\n * @type {Boolean}\n */\n set pickable(pickable) {\n pickable = pickable !== false;\n this._pickable = pickable;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].pickable = pickable;\n }\n }\n\n /**\n * Gets if to this Node is pickable.\n *\n * Picking is done via calls to {@link Scene#pick}.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Boolean}\n */\n get pickable() {\n return this._pickable;\n }\n\n /**\n * Sets the RGB colorize color for this Node and all child Nodes and {@link Mesh}es}.\n *\n * Multiplies by rendered fragment colors.\n *\n * Each element of the color is in range ````[0..1]````.\n *\n * @type {Number[]}\n */\n set colorize(rgb) {\n let colorize = this._colorize;\n if (!colorize) {\n colorize = this._colorize = new Float32Array(4);\n colorize[3] = 1.0;\n }\n if (rgb) {\n colorize[0] = rgb[0];\n colorize[1] = rgb[1];\n colorize[2] = rgb[2];\n } else {\n colorize[0] = 1;\n colorize[1] = 1;\n colorize[2] = 1;\n }\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].colorize = colorize;\n }\n if (this._isObject) {\n const colorized = (!!rgb);\n this.scene._objectColorizeUpdated(this, colorized);\n }\n }\n\n /**\n * Gets the RGB colorize color for this Node.\n *\n * Each element of the color is in range ````[0..1]````.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Number[]}\n */\n get colorize() {\n return this._colorize.slice(0, 3);\n }\n\n /**\n * Sets the opacity factor for this Node and all child Nodes and {@link Mesh}es.\n *\n * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n *\n * @type {Number}\n */\n set opacity(opacity) {\n let colorize = this._colorize;\n if (!colorize) {\n colorize = this._colorize = new Float32Array(4);\n colorize[0] = 1;\n colorize[1] = 1;\n colorize[2] = 1;\n }\n colorize[3] = opacity !== null && opacity !== undefined ? opacity : 1.0;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].opacity = opacity;\n }\n if (this._isObject) {\n const opacityUpdated = (opacity !== null && opacity !== undefined);\n this.scene._objectOpacityUpdated(this, opacityUpdated);\n }\n }\n\n /**\n * Gets this Node's opacity factor.\n *\n * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Number}\n */\n get opacity() {\n return this._colorize[3];\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es cast shadows.\n *\n * @type {Boolean}\n */\n set castsShadow(castsShadow) {\n castsShadow = !!castsShadow;\n this._castsShadow = castsShadow;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].castsShadow = castsShadow;\n }\n }\n\n /**\n * Gets if this Node casts shadows.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Boolean}\n */\n get castsShadow() {\n return this._castsShadow;\n }\n\n /**\n * Sets if this Node and all child Nodes and {@link Mesh}es can have shadows cast upon them.\n *\n * @type {Boolean}\n */\n set receivesShadow(receivesShadow) {\n receivesShadow = !!receivesShadow;\n this._receivesShadow = receivesShadow;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].receivesShadow = receivesShadow;\n }\n }\n\n /**\n * Whether or not to this Node can have shadows cast upon it.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Boolean}\n */\n get receivesShadow() {\n return this._receivesShadow;\n }\n\n /**\n * Gets if this Node can have Scalable Ambient Obscurance (SAO) applied to it.\n *\n * SAO is configured by {@link SAO}.\n *\n * @type {Boolean}\n * @abstract\n */\n get saoEnabled() {\n return false; // TODO: Support SAO on Nodes\n }\n\n\n /**\n * Sets the 3D World-space offset for this Node and all child Nodes and {@link Mesh}es}.\n *\n * The offset dynamically translates those components in World-space.\n *\n * Default value is ````[0, 0, 0]````.\n *\n * Note that child Nodes and {@link Mesh}es may subsequently be given different values for this property.\n *\n * @type {Number[]}\n */\n set offset(offset) {\n if (offset) {\n this._offset[0] = offset[0];\n this._offset[1] = offset[1];\n this._offset[2] = offset[2];\n } else {\n this._offset[0] = 0;\n this._offset[1] = 0;\n this._offset[2] = 0;\n }\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i].offset = this._offset;\n }\n if (this._isObject) {\n this.scene._objectOffsetUpdated(this, offset);\n }\n }\n\n /**\n * Gets the Node's 3D World-space offset.\n *\n * Default value is ````[0, 0, 0]````.\n *\n * Child Nodes and {@link Mesh}es may have different values for this property.\n *\n * @type {Number[]}\n */\n get offset() {\n return this._offset;\n }\n\n\n //------------------------------------------------------------------------------------------------------------------\n // Node members\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Returns true to indicate that this Component is a Node.\n * @type {Boolean}\n */\n get isNode() {\n return true;\n }\n\n _setLocalMatrixDirty() {\n this._localMatrixDirty = true;\n this._setWorldMatrixDirty();\n }\n\n _setWorldMatrixDirty() {\n this._worldMatrixDirty = true;\n for (let i = 0, len = this._children.length; i < len; i++) {\n this._children[i]._setWorldMatrixDirty();\n }\n }\n\n _buildWorldMatrix() {\n const localMatrix = this.matrix;\n if (!this._parentNode) {\n for (let i = 0, len = localMatrix.length; i < len; i++) {\n this._worldMatrix[i] = localMatrix[i];\n }\n } else {\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.mulMat4(this._parentNode.worldMatrix, localMatrix, this._worldMatrix);\n }\n this._worldMatrixDirty = false;\n }\n\n _setSubtreeAABBsDirty(node) {\n node._aabbDirty = true;\n if (node._children) {\n for (let i = 0, len = node._children.length; i < len; i++) {\n this._setSubtreeAABBsDirty(node._children[i]);\n }\n }\n }\n\n _setAABBDirty() {\n this._setSubtreeAABBsDirty(this);\n if (this.collidable) {\n for (let node = this; node; node = node._parentNode) {\n node._aabbDirty = true;\n }\n }\n }\n\n _updateAABB() {\n this.scene._aabbDirty = true;\n if (!this._aabb) {\n this._aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.AABB3();\n }\n if (this._buildAABB) {\n this._buildAABB(this.worldMatrix, this._aabb); // Mesh or VBOSceneModel\n } else { // Node | Node | Model\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.collapseAABB3(this._aabb);\n let node;\n for (let i = 0, len = this._children.length; i < len; i++) {\n node = this._children[i];\n if (!node.collidable) {\n continue;\n }\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.expandAABB3(this._aabb, node.aabb);\n }\n }\n this._aabbDirty = false;\n }\n\n /**\n * Adds a child Node or {@link Mesh}.\n *\n * The child must be a Node or {@link Mesh} in the same {@link Scene}.\n *\n * If the child already has a parent, will be removed from that parent first.\n *\n * Does nothing if already a child.\n *\n * @param {Node|Mesh|String} child Instance or ID of the child to add.\n * @param [inheritStates=false] Indicates if the child should inherit rendering states from this parent as it is added. Rendering state includes {@link Node#visible}, {@link Node#culled}, {@link Node#pickable}, {@link Node#clippable}, {@link Node#castsShadow}, {@link Node#receivesShadow}, {@link Node#selected}, {@link Node#highlighted}, {@link Node#colorize} and {@link Node#opacity}.\n * @returns {Node|Mesh} The child.\n */\n addChild(child, inheritStates) {\n if (_utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.isNumeric(child) || _utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.isString(child)) {\n const nodeId = child;\n child = this.scene.component[nodeId];\n if (!child) {\n this.warn(\"Component not found: \" + _utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.inQuotes(nodeId));\n return;\n }\n if (!child.isNode && !child.isMesh) {\n this.error(\"Not a Node or Mesh: \" + nodeId);\n return;\n }\n } else {\n if (!child.isNode && !child.isMesh) {\n this.error(\"Not a Node or Mesh: \" + child.id);\n return;\n }\n if (child._parentNode) {\n if (child._parentNode.id === this.id) {\n this.warn(\"Already a child: \" + child.id);\n return;\n }\n child._parentNode.removeChild(child);\n }\n }\n const id = child.id;\n if (child.scene.id !== this.scene.id) {\n this.error(\"Child not in same Scene: \" + child.id);\n return;\n }\n this._children.push(child);\n child._parentNode = this;\n if (!!inheritStates) {\n child.visible = this.visible;\n child.culled = this.culled;\n child.xrayed = this.xrayed;\n child.highlited = this.highlighted;\n child.selected = this.selected;\n child.edges = this.edges;\n child.clippable = this.clippable;\n child.pickable = this.pickable;\n child.collidable = this.collidable;\n child.castsShadow = this.castsShadow;\n child.receivesShadow = this.receivesShadow;\n child.colorize = this.colorize;\n child.opacity = this.opacity;\n child.offset = this.offset;\n }\n child._setWorldMatrixDirty();\n child._setAABBDirty();\n this._numTriangles += child.numTriangles;\n return child;\n }\n\n /**\n * Removes the given child Node or {@link Mesh}.\n *\n * @param {Node|Mesh} child Child to remove.\n */\n removeChild(child) {\n for (let i = 0, len = this._children.length; i < len; i++) {\n if (this._children[i].id === child.id) {\n child._parentNode = null;\n this._children = this._children.splice(i, 1);\n child._setWorldMatrixDirty();\n child._setAABBDirty();\n this._setAABBDirty();\n this._numTriangles -= child.numTriangles;\n return;\n }\n }\n }\n\n /**\n * Removes all child Nodes and {@link Mesh}es.\n */\n removeChildren() {\n let child;\n for (let i = 0, len = this._children.length; i < len; i++) {\n child = this._children[i];\n child._parentNode = null;\n child._setWorldMatrixDirty();\n child._setAABBDirty();\n this._numTriangles -= child.numTriangles;\n }\n this._children = [];\n this._setAABBDirty();\n }\n\n /**\n * Number of child Nodes or {@link Mesh}es.\n *\n * @type {Number}\n */\n get numChildren() {\n return this._children.length;\n }\n\n /**\n * Array of child Nodes or {@link Mesh}es.\n *\n * @type {Array}\n */\n get children() {\n return this._children;\n }\n\n /**\n * The parent Node.\n *\n * The parent Node may also be set by passing the Node to the parent's {@link Node#addChild} method.\n *\n * @type {Node}\n */\n set parent(node) {\n if (_utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.isNumeric(node) || _utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.isString(node)) {\n const nodeId = node;\n node = this.scene.components[nodeId];\n if (!node) {\n this.warn(\"Node not found: \" + _utils_js__WEBPACK_IMPORTED_MODULE_0__.utils.inQuotes(nodeId));\n return;\n }\n if (!node.isNode) {\n this.error(\"Not a Node: \" + node.id);\n return;\n }\n }\n if (node.scene.id !== this.scene.id) {\n this.error(\"Node not in same Scene: \" + node.id);\n return;\n }\n if (this._parentNode && this._parentNode.id === node.id) {\n this.warn(\"Already a child of Node: \" + node.id);\n return;\n }\n node.addChild(this);\n }\n\n /**\n * The parent Node.\n *\n * @type {Node}\n */\n get parent() {\n return this._parentNode;\n }\n\n /**\n * Sets the Node's local translation.\n *\n * Default value is ````[0,0,0]````.\n *\n * @type {Number[]}\n */\n set position(value) {\n this._position.set(value || [0, 0, 0]);\n this._setLocalMatrixDirty();\n this._setAABBDirty();\n this.glRedraw();\n }\n\n /**\n * Gets the Node's local translation.\n *\n * Default value is ````[0,0,0]````.\n *\n * @type {Number[]}\n */\n get position() {\n return this._position;\n }\n\n /**\n * Sets the Node's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n *\n * Default value is ````[0,0,0]````.\n *\n * @type {Number[]}\n */\n set rotation(value) {\n this._rotation.set(value || [0, 0, 0]);\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n this._setLocalMatrixDirty();\n this._setAABBDirty();\n this.glRedraw();\n }\n\n /**\n * Gets the Node's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n *\n * Default value is ````[0,0,0]````.\n *\n * @type {Number[]}\n */\n get rotation() {\n return this._rotation;\n }\n\n /**\n * Sets the Node's local rotation quaternion.\n *\n * Default value is ````[0,0,0,1]````.\n *\n * @type {Number[]}\n */\n set quaternion(value) {\n this._quaternion.set(value || [0, 0, 0, 1]);\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.quaternionToEuler(this._quaternion, \"XYZ\", this._rotation);\n this._setLocalMatrixDirty();\n this._setAABBDirty();\n this.glRedraw();\n }\n\n /**\n * Gets the Node's local rotation quaternion.\n *\n * Default value is ````[0,0,0,1]````.\n *\n * @type {Number[]}\n */\n get quaternion() {\n return this._quaternion;\n }\n\n /**\n * Sets the Node's local scale.\n *\n * Default value is ````[1,1,1]````.\n *\n * @type {Number[]}\n */\n set scale(value) {\n this._scale.set(value || [1, 1, 1]);\n this._setLocalMatrixDirty();\n this._setAABBDirty();\n this.glRedraw();\n }\n\n /**\n * Gets the Node's local scale.\n *\n * Default value is ````[1,1,1]````.\n *\n * @type {Number[]}\n */\n get scale() {\n return this._scale;\n }\n\n /**\n * Sets the Node's local modeling transform matrix.\n *\n * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n *\n * @type {Number[]}\n */\n set matrix(value) {\n if (!this._localMatrix) {\n this._localMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\n }\n this._localMatrix.set(value || identityMat);\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.decomposeMat4(this._localMatrix, this._position, this._quaternion, this._scale);\n this._localMatrixDirty = false;\n this._setWorldMatrixDirty();\n this._setAABBDirty();\n this.glRedraw();\n }\n\n /**\n * Gets the Node's local modeling transform matrix.\n *\n * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n *\n * @type {Number[]}\n */\n get matrix() {\n if (this._localMatrixDirty) {\n if (!this._localMatrix) {\n this._localMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.identityMat4();\n }\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.composeMat4(this._position, this._quaternion, this._scale, this._localMatrix);\n this._localMatrixDirty = false;\n }\n return this._localMatrix;\n }\n\n /**\n * Gets the Node's World matrix.\n *\n * @property worldMatrix\n * @type {Number[]}\n */\n get worldMatrix() {\n if (this._worldMatrixDirty) {\n this._buildWorldMatrix();\n }\n return this._worldMatrix;\n }\n\n /**\n * Rotates the Node about the given local axis by the given increment.\n *\n * @param {Number[]} axis Local axis about which to rotate.\n * @param {Number} angle Angle increment in degrees.\n */\n rotate(axis, angle) {\n angleAxis[0] = axis[0];\n angleAxis[1] = axis[1];\n angleAxis[2] = axis[2];\n angleAxis[3] = angle * _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.DEGTORAD;\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.angleAxisToQuaternion(angleAxis, q1);\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.mulQuaternions(this.quaternion, q1, q2);\n this.quaternion = q2;\n this._setLocalMatrixDirty();\n this._setAABBDirty();\n this.glRedraw();\n return this;\n }\n\n /**\n * Rotates the Node about the given World-space axis by the given increment.\n *\n * @param {Number[]} axis Local axis about which to rotate.\n * @param {Number} angle Angle increment in degrees.\n */\n rotateOnWorldAxis(axis, angle) {\n angleAxis[0] = axis[0];\n angleAxis[1] = axis[1];\n angleAxis[2] = axis[2];\n angleAxis[3] = angle * _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.DEGTORAD;\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.angleAxisToQuaternion(angleAxis, q1);\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.mulQuaternions(q1, this.quaternion, q1);\n //this.quaternion.premultiply(q1);\n return this;\n }\n\n /**\n * Rotates the Node about the local X-axis by the given increment.\n *\n * @param {Number} angle Angle increment in degrees.\n */\n rotateX(angle) {\n return this.rotate(xAxis, angle);\n }\n\n /**\n * Rotates the Node about the local Y-axis by the given increment.\n *\n * @param {Number} angle Angle increment in degrees.\n */\n rotateY(angle) {\n return this.rotate(yAxis, angle);\n }\n\n /**\n * Rotates the Node about the local Z-axis by the given increment.\n *\n * @param {Number} angle Angle increment in degrees.\n */\n rotateZ(angle) {\n return this.rotate(zAxis, angle);\n }\n\n /**\n * Translates the Node along local space vector by the given increment.\n *\n * @param {Number[]} axis Normalized local space 3D vector along which to translate.\n * @param {Number} distance Distance to translate along the vector.\n */\n translate(axis, distance) {\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3ApplyQuaternion(this.quaternion, axis, veca);\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.mulVec3Scalar(veca, distance, vecb);\n _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.addVec3(this.position, vecb, this.position);\n this._setLocalMatrixDirty();\n this._setAABBDirty();\n this.glRedraw();\n return this;\n }\n\n /**\n * Translates the Node along the local X-axis by the given increment.\n *\n * @param {Number} distance Distance to translate along the X-axis.\n */\n translateX(distance) {\n return this.translate(xAxis, distance);\n }\n\n /**\n * Translates the Node along the local Y-axis by the given increment.\n *\n * @param {Number} distance Distance to translate along the Y-axis.\n */\n translateY(distance) {\n return this.translate(yAxis, distance);\n }\n\n /**\n * Translates the Node along the local Z-axis by the given increment.\n *\n * @param {Number} distance Distance to translate along the Z-axis.\n */\n translateZ(distance) {\n return this.translate(zAxis, distance);\n }\n\n //------------------------------------------------------------------------------------------------------------------\n // Component members\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n @private\n */\n get type() {\n return \"Node\";\n }\n\n /**\n * Destroys this Node.\n */\n destroy() {\n super.destroy();\n if (this._parentNode) {\n this._parentNode.removeChild(this);\n }\n if (this._isObject) {\n this.scene._deregisterObject(this);\n if (this._visible) {\n this.scene._objectVisibilityUpdated(this, false, false);\n }\n if (this._xrayed) {\n this.scene._objectXRayedUpdated(this, false, false);\n }\n if (this._selected) {\n this.scene._objectSelectedUpdated(this, false, false);\n }\n if (this._highlighted) {\n this.scene._objectHighlightedUpdated(this, false, false);\n }\n this.scene._objectColorizeUpdated(this, false);\n this.scene._objectOpacityUpdated(this, false);\n if (this.offset.some((v) => v !== 0))\n this.scene._objectOffsetUpdated(this, false);\n }\n if (this._isModel) {\n this.scene._deregisterModel(this);\n }\n if (this._children.length) {\n // Clone the _children before iterating, so our children don't mess us up when calling removeChild().\n const tempChildList = this._children.splice();\n let child;\n for (let i = 0, len = tempChildList.length; i < len; i++) {\n child = tempChildList[i];\n child.destroy();\n }\n }\n this._children = [];\n this._setAABBDirty();\n this.scene._aabbDirty = true;\n }\n\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/nodes/Node.js?");
4718
4738
 
4719
4739
  /***/ }),
4720
4740
 
@@ -4804,7 +4824,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4804
4824
  \*****************************************/
4805
4825
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4806
4826
 
4807
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Scene: () => (/* binding */ Scene)\n/* harmony export */ });\n/* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core.js */ \"./src/viewer/scene/core.js\");\n/* harmony import */ var _lod_LOD_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../lod/LOD.js */ \"./src/viewer/scene/lod/LOD.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _canvas_Canvas_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../canvas/Canvas.js */ \"./src/viewer/scene/canvas/Canvas.js\");\n/* harmony import */ var _webgl_Renderer_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../webgl/Renderer.js */ \"./src/viewer/scene/webgl/Renderer.js\");\n/* harmony import */ var _input_Input_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../input/Input.js */ \"./src/viewer/scene/input/Input.js\");\n/* harmony import */ var _viewport_Viewport_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../viewport/Viewport.js */ \"./src/viewer/scene/viewport/Viewport.js\");\n/* harmony import */ var _camera_Camera_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../camera/Camera.js */ \"./src/viewer/scene/camera/Camera.js\");\n/* harmony import */ var _lights_DirLight_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../lights/DirLight.js */ \"./src/viewer/scene/lights/DirLight.js\");\n/* harmony import */ var _lights_AmbientLight_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../lights/AmbientLight.js */ \"./src/viewer/scene/lights/AmbientLight.js\");\n/* harmony import */ var _geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _geometry_builders_buildBoxGeometry_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../geometry/builders/buildBoxGeometry.js */ \"./src/viewer/scene/geometry/builders/buildBoxGeometry.js\");\n/* harmony import */ var _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../materials/EmphasisMaterial.js */ \"./src/viewer/scene/materials/EmphasisMaterial.js\");\n/* harmony import */ var _materials_EdgeMaterial_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../materials/EdgeMaterial.js */ \"./src/viewer/scene/materials/EdgeMaterial.js\");\n/* harmony import */ var _metriqs_Metriqs_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../metriqs/Metriqs.js */ \"./src/viewer/scene/metriqs/Metriqs.js\");\n/* harmony import */ var _postfx_SAO_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../postfx/SAO.js */ \"./src/viewer/scene/postfx/SAO.js\");\n/* harmony import */ var _materials_PointsMaterial_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../materials/PointsMaterial.js */ \"./src/viewer/scene/materials/PointsMaterial.js\");\n/* harmony import */ var _materials_LinesMaterial_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../materials/LinesMaterial.js */ \"./src/viewer/scene/materials/LinesMaterial.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// Enables runtime check for redundant calls to object state update methods, eg. Scene#_objectVisibilityUpdated\nconst ASSERT_OBJECT_STATE_UPDATE = false;\n\n// Cached vars to avoid garbage collection\n\nfunction getEntityIDMap(scene, entityIds) {\n\tconst map = {};\n\tlet entityId;\n\tlet entity;\n\tfor (let i = 0, len = entityIds.length; i < len; i++) {\n\t\tentityId = entityIds[i];\n\t\tentity = scene.components[entityId];\n\t\tif (!entity) {\n\t\t\tscene.warn(\"pick(): Component not found: \" + entityId);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!entity.isEntity) {\n\t\t\tscene.warn(\"pick(): Component is not an Entity: \" + entityId);\n\t\t\tcontinue;\n\t\t}\n\t\tmap[entityId] = true;\n\t}\n\treturn map;\n}\n\n/**\n * Fired whenever a debug message is logged on a component within this Scene.\n * @event log\n * @param {String} value The debug message\n */\n\n/**\n * Fired whenever an error is logged on a component within this Scene.\n * @event error\n * @param {String} value The error message\n */\n\n/**\n * Fired whenever a warning is logged on a component within this Scene.\n * @event warn\n * @param {String} value The warning message\n */\n\n/**\n * @desc Contains the components that comprise a 3D scene.\n *\n * * A {@link Viewer} has a single Scene, which it provides in {@link Viewer#scene}.\n * * Plugins like {@link AxisGizmoPlugin} also have their own private Scenes.\n * * Each Scene has a corresponding {@link MetaScene}, which the Viewer provides in {@link Viewer#metaScene}.\n *\n * ## Getting a Viewer's Scene\n *\n * ````javascript\n * var scene = viewer.scene;\n * ````\n *\n * ## Creating and accessing Scene components\n *\n * As a brief introduction to creating Scene components, we'll create a {@link Mesh} that has a\n * {@link buildTorusGeometry} and a {@link PhongMaterial}:\n *\n * ````javascript\n * var teapotMesh = new Mesh(scene, {\n * id: \"myMesh\", // <<---------- ID automatically generated if not provided\n * geometry: new TorusGeometry(scene),\n * material: new PhongMaterial(scene, {\n * id: \"myMaterial\",\n * diffuse: [0.2, 0.2, 1.0]\n * })\n * });\n *\n * teapotMesh.scene.camera.eye = [45, 45, 45];\n * ````\n *\n * Find components by ID in their Scene's {@link Scene#components} map:\n *\n * ````javascript\n * var teapotMesh = scene.components[\"myMesh\"];\n * teapotMesh.visible = false;\n *\n * var teapotMaterial = scene.components[\"myMaterial\"];\n * teapotMaterial.diffuse = [1,0,0]; // Change to red\n * ````\n *\n * A Scene also has a map of component instances for each {@link Component} subtype:\n *\n * ````javascript\n * var meshes = scene.types[\"Mesh\"];\n * var teapotMesh = meshes[\"myMesh\"];\n * teapotMesh.xrayed = true;\n *\n * var phongMaterials = scene.types[\"PhongMaterial\"];\n * var teapotMaterial = phongMaterials[\"myMaterial\"];\n * teapotMaterial.diffuse = [0,1,0]; // Change to green\n * ````\n *\n * See {@link Node}, {@link Node} and {@link Model} for how to create and access more sophisticated content.\n *\n * ## Controlling the camera\n *\n * Use the Scene's {@link Camera} to control the current viewpoint and projection:\n *\n * ````javascript\n * var camera = myScene.camera;\n *\n * camera.eye = [-10,0,0];\n * camera.look = [-10,0,0];\n * camera.up = [0,1,0];\n *\n * camera.projection = \"perspective\";\n * camera.perspective.fov = 45;\n * //...\n * ````\n *\n * ## Managing the canvas\n *\n * The Scene's {@link Canvas} component provides various conveniences relevant to the WebGL canvas, such\n * as firing resize events etc:\n *\n * ````javascript\n * var canvas = scene.canvas;\n *\n * canvas.on(\"boundary\", function(boundary) {\n * //...\n * });\n * ````\n *\n * ## Picking\n *\n * Use {@link Scene#pick} to pick and raycast entites.\n *\n * For example, to pick a point on the surface of the closest entity at the given canvas coordinates:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * pickSurface: true,\n * canvasPos: [23, 131]\n * });\n *\n * if (pickResult) { // Picked an entity\n *\n * var entity = pickResult.entity;\n *\n * var primitive = pickResult.primitive; // Type of primitive that was picked, usually \"triangles\"\n * var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Mesh's Geometry's indices array\n * var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\n * var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\n * var viewPos = pickResult. ; // Float64Array containing the picked View-space position on the triangle\n * var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\n * var normal = pickResult.normal; // Float64Array containing the interpolated normal vector at the picked position on the triangle\n * var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\n * }\n * ````\n *\n * ## Pick masking\n *\n * We can use {@link Scene#pick}'s ````includeEntities```` and ````excludeEntities```` options to mask which {@link Mesh}es we attempt to pick.\n *\n * This is useful for picking through things, to pick only the Entities of interest.\n *\n * To pick only Entities ````\"gearbox#77.0\"```` and ````\"gearbox#79.0\"````, picking through any other Entities that are\n * in the way, as if they weren't there:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * canvasPos: [23, 131],\n * includeEntities: [\"gearbox#77.0\", \"gearbox#79.0\"]\n * });\n *\n * if (pickResult) {\n * // Entity will always be either \"gearbox#77.0\" or \"gearbox#79.0\"\n * var entity = pickResult.entity;\n * }\n * ````\n *\n * To pick any pickable Entity, except for ````\"gearbox#77.0\"```` and ````\"gearbox#79.0\"````, picking through those\n * Entities if they happen to be in the way:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * canvasPos: [23, 131],\n * excludeEntities: [\"gearbox#77.0\", \"gearbox#79.0\"]\n * });\n *\n * if (pickResult) {\n * // Entity will never be \"gearbox#77.0\" or \"gearbox#79.0\"\n * var entity = pickResult.entity;\n * }\n * ````\n *\n * See {@link Scene#pick} for more info on picking.\n *\n * ## Querying and tracking boundaries\n *\n * Getting a Scene's World-space axis-aligned boundary (AABB):\n *\n * ````javascript\n * var aabb = scene.aabb; // [xmin, ymin, zmin, xmax, ymax, zmax]\n * ````\n *\n * Subscribing to updates to the AABB, which occur whenever {@link Entity}s are transformed, their\n * {@link ReadableGeometry}s have been updated, or the {@link Camera} has moved:\n *\n * ````javascript\n * scene.on(\"boundary\", function() {\n * var aabb = scene.aabb;\n * });\n * ````\n *\n * Getting the AABB of the {@link Entity}s with the given IDs:\n *\n * ````JavaScript\n * scene.getAABB(); // Gets collective boundary of all Entities in the scene\n * scene.getAABB(\"saw\"); // Gets boundary of an Object\n * scene.getAABB([\"saw\", \"gearbox\"]); // Gets collective boundary of two Objects\n * ````\n *\n * See {@link Scene#getAABB} and {@link Entity} for more info on querying and tracking boundaries.\n *\n * ## Managing the viewport\n *\n * The Scene's {@link Viewport} component manages the WebGL viewport:\n *\n * ````javascript\n * var viewport = scene.viewport\n * viewport.boundary = [0, 0, 500, 400];;\n * ````\n *\n * ## Controlling rendering\n *\n * You can configure a Scene to perform multiple \"passes\" (renders) per frame. This is useful when we want to render the\n * scene to multiple viewports, such as for stereo effects.\n *\n * In the example, below, we'll configure the Scene to render twice on each frame, each time to different viewport. We'll do this\n * with a callback that intercepts the Scene before each render and sets its {@link Viewport} to a\n * different portion of the canvas. By default, the Scene will clear the canvas only before the first render, allowing the\n * two views to be shown on the canvas at the same time.\n *\n * ````Javascript\n * var viewport = scene.viewport;\n *\n * // Configure Scene to render twice for each frame\n * scene.passes = 2; // Default is 1\n * scene.clearEachPass = false; // Default is false\n *\n * // Render to a separate viewport on each render\n *\n * var viewport = scene.viewport;\n * viewport.autoBoundary = false;\n *\n * scene.on(\"rendering\", function (e) {\n * switch (e.pass) {\n * case 0:\n * viewport.boundary = [0, 0, 200, 200]; // xmin, ymin, width, height\n * break;\n *\n * case 1:\n * viewport.boundary = [200, 0, 200, 200];\n * break;\n * }\n * });\n *\n * // We can also intercept the Scene after each render,\n * // (though we're not using this for anything here)\n * scene.on(\"rendered\", function (e) {\n * switch (e.pass) {\n * case 0:\n * break;\n *\n * case 1:\n * break;\n * }\n * });\n * ````\n *\n * ## Gamma correction\n *\n * Within its shaders, xeokit performs shading calculations in linear space.\n *\n * By default, the Scene expects color textures (eg. {@link PhongMaterial#diffuseMap},\n * {@link MetallicMaterial#baseColorMap} and {@link SpecularMaterial#diffuseMap}) to\n * be in pre-multipled gamma space, so will convert those to linear space before they are used in shaders. Other textures are\n * always expected to be in linear space.\n *\n * By default, the Scene will also gamma-correct its rendered output.\n *\n * You can configure the Scene to expect all those color textures to be linear space, so that it does not gamma-correct them:\n *\n * ````javascript\n * scene.gammaInput = false;\n * ````\n *\n * You would still need to gamma-correct the output, though, if it's going straight to the canvas, so normally we would\n * leave that enabled:\n *\n * ````javascript\n * scene.gammaOutput = true;\n * ````\n *\n * See {@link Texture} for more information on texture encoding and gamma.\n *\n * @class Scene\n */\nclass Scene extends _Component_js__WEBPACK_IMPORTED_MODULE_4__.Component {\n\t/**\n @private\n */\n\tget type() {\n\t\treturn \"Scene\";\n\t}\n\n\t/**\n\t * @private\n\t * @constructor\n\t * @param {Viewer} viewer The Viewer this Scene belongs to.\n\t * @param {Object} cfg Scene configuration.\n\t * @param {String} [cfg.canvasId] ID of an existing HTML canvas for the {@link Scene#canvas} - either this or canvasElement is mandatory. When both values are given, the element reference is always preferred to the ID.\n\t * @param {HTMLCanvasElement} [cfg.canvasElement] Reference of an existing HTML canvas for the {@link Scene#canvas} - either this or canvasId is mandatory. When both values are given, the element reference is always preferred to the ID.\n\t * @param {HTMLElement} [cfg.keyboardEventsElement] Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document.\n\t * @param {number} [cfg.numCachedSectionPlanes=0] Enhances the efficiency of SectionPlane creation by proactively allocating Viewer resources for a specified quantity\n\t * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n\t * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n\t * responsiveness. It is important to consider that each SectionPlane imposes rendering performance, so it is recommended to set this value to a quantity that aligns with\n\t * your expected usage.\n\t * @throws {String} Throws an exception when both canvasId or canvasElement are missing or they aren't pointing to a valid HTMLCanvasElement.\n\t */\n\tconstructor(viewer, cfg = {}) {\n\t\tsuper(null, cfg);\n\n\t\tconst canvas = cfg.canvasElement || document.getElementById(cfg.canvasId);\n\n\t\tif (!(canvas instanceof HTMLCanvasElement)) {\n\t\t\tthrow \"Mandatory config expected: valid canvasId or canvasElement\";\n\t\t}\n\n\t\t/**\n\t\t * @type {{[key: string]: {wrapperFunc: Function, tickSubId: string}}}\n\t\t */\n\t\tthis._tickifiedFunctions = {};\n\n\t\tthis._transparent = !!cfg.transparent;\n\t\tconst alphaDepthMask = !!cfg.alphaDepthMask;\n\t\tthis._edgesEnabled = !!cfg.edgesEnabled;\n\n\t\tthis._aabbDirty = true;\n\n\t\t/**\n\t\t * The {@link Viewer} this Scene belongs to.\n\t\t * @type {Viewer}\n\t\t */\n\t\tthis.viewer = viewer;\n\n\t\t/** Decremented each frame, triggers occlusion test for occludable {@link Marker}s when zero.\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis.occlusionTestCountdown = 0;\n\n\t\t/**\n The number of models currently loading.\n\n @property loading\n @final\n @type {Number}\n */\n\t\tthis.loading = 0;\n\n\t\t/**\n The epoch time (in milliseconds since 1970) when this Scene was instantiated.\n\n @property timeCreated\n @final\n @type {Number}\n */\n\t\tthis.startTime = new Date().getTime();\n\n\t\t/**\n\t\t * Map of {@link Entity}s that represent models.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id} when {@link Entity#isModel} is ````true````.\n\t\t *\n\t\t * @property models\n\t\t * @final\n\t\t * @type {{String:Entity}}\n\t\t */\n\t\tthis.models = {};\n\n\t\t/**\n\t\t * Map of {@link Entity}s that represents objects.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id} when {@link Entity#isObject} is ````true````.\n\t\t *\n\t\t * @property objects\n\t\t * @final\n\t\t * @type {{String:Entity}}\n\t\t */\n\t\tthis.objects = {};\n\t\tthis._numObjects = 0;\n\n\t\t/**\n\t\t * Map of currently visible {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````, and is visible when {@link Entity#visible} is true.\n\t\t *\n\t\t * @property visibleObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.visibleObjects = {};\n\t\tthis._numVisibleObjects = 0;\n\n\t\t/**\n\t\t * Map of currently xrayed {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````, and is xrayed when {@link Entity#xrayed} is true.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property xrayedObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.xrayedObjects = {};\n\t\tthis._numXRayedObjects = 0;\n\n\t\t/**\n\t\t * Map of currently highlighted {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true```` is true, and is highlighted when {@link Entity#highlighted} is true.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property highlightedObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.highlightedObjects = {};\n\t\tthis._numHighlightedObjects = 0;\n\n\t\t/**\n\t\t * Map of currently selected {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is true, and is selected while {@link Entity#selected} is true.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property selectedObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.selectedObjects = {};\n\t\tthis._numSelectedObjects = 0;\n\n\t\t/**\n\t\t * Map of currently colorized {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property colorizedObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.colorizedObjects = {};\n\t\tthis._numColorizedObjects = 0;\n\n\t\t/**\n\t\t * Map of {@link Entity}s that represent objects whose opacity was updated.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property opacityObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.opacityObjects = {};\n\t\tthis._numOpacityObjects = 0;\n\n\t\t/**\n\t\t * Map of {@link Entity}s that represent objects whose {@link Entity#offset}s were updated.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property offsetObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.offsetObjects = {};\n\t\tthis._numOffsetObjects = 0;\n\n\t\t// Cached ID arrays, lazy-rebuilt as needed when stale after map updates\n\n\t\t/**\n Lazy-regenerated ID lists.\n */\n\t\tthis._modelIds = null;\n\t\tthis._objectIds = null;\n\t\tthis._visibleObjectIds = null;\n\t\tthis._xrayedObjectIds = null;\n\t\tthis._highlightedObjectIds = null;\n\t\tthis._selectedObjectIds = null;\n\t\tthis._colorizedObjectIds = null;\n\t\tthis._opacityObjectIds = null;\n\t\tthis._offsetObjectIds = null;\n\n\t\tthis._collidables = {}; // Components that contribute to the Scene AABB\n\t\tthis._compilables = {}; // Components that require shader compilation\n\n\t\tthis._needRecompile = false;\n\n\t\t/**\n\t\t * For each {@link Component} type, a map of IDs to {@link Component} instances of that type.\n\t\t *\n\t\t * @type {{String:{String:Component}}}\n\t\t */\n\t\tthis.types = {};\n\n\t\t/**\n\t\t * The {@link Component}s within this Scene, each mapped to its {@link Component#id}.\n\t\t *\n\t\t * *@type {{String:Component}}\n\t\t */\n\t\tthis.components = {};\n\n\t\t/**\n\t\t * The {@link SectionPlane}s in this Scene, each mapped to its {@link SectionPlane#id}.\n\t\t *\n\t\t * @type {{String:SectionPlane}}\n\t\t */\n\t\tthis.sectionPlanes = {};\n\n\t\t/**\n\t\t * The {@link Light}s in this Scene, each mapped to its {@link Light#id}.\n\t\t *\n\t\t * @type {{String:Light}}\n\t\t */\n\t\tthis.lights = {};\n\n\t\t/**\n\t\t * The {@link LightMap}s in this Scene, each mapped to its {@link LightMap#id}.\n\t\t *\n\t\t * @type {{String:LightMap}}\n\t\t */\n\t\tthis.lightMaps = {};\n\n\t\t/**\n\t\t * The {@link ReflectionMap}s in this Scene, each mapped to its {@link ReflectionMap#id}.\n\t\t *\n\t\t * @type {{String:ReflectionMap}}\n\t\t */\n\t\tthis.reflectionMaps = {};\n\n\t\t/**\n\t\t * The {@link Bitmap}s in this Scene, each mapped to its {@link Bitmap#id}.\n\t\t *\n\t\t * @type {{String:Bitmap}}\n\t\t */\n\t\tthis.bitmaps = {};\n\n\t\t/**\n\t\t * The {@link LineSet}s in this Scene, each mapped to its {@link LineSet#id}.\n\t\t *\n\t\t * @type {{String:LineSet}}\n\t\t */\n\t\tthis.lineSets = {};\n\n\t\t/**\n\t\t * The real world offset for this Scene\n\t\t *\n\t\t * @type {Number[]}\n\t\t */\n\t\tthis.realWorldOffset = cfg.realWorldOffset || new Float64Array([0, 0, 0]);\n\n\t\t/**\n\t\t * Manages the HTML5 canvas for this Scene.\n\t\t *\n\t\t * @type {Canvas}\n\t\t */\n\t\tthis.canvas = new _canvas_Canvas_js__WEBPACK_IMPORTED_MODULE_5__.Canvas(this, {\n\t\t\tdontClear: true, // Never destroy this component with Scene#clear();\n\t\t\tcanvas: canvas,\n\t\t\tspinnerElementId: cfg.spinnerElementId,\n\t\t\ttransparent: this._transparent,\n\t\t\twebgl2: cfg.webgl2 !== false,\n\t\t\tcontextAttr: cfg.contextAttr || {},\n\t\t\tbackgroundColor: cfg.backgroundColor,\n\t\t\tbackgroundColorFromAmbientLight: cfg.backgroundColorFromAmbientLight,\n\t\t\tpremultipliedAlpha: cfg.premultipliedAlpha,\n\t\t\tresolutionScale: cfg.resolutionScale\n\t\t});\n\n\t\tthis.canvas.on(\"boundary\", () => {\n\t\t\tthis.glRedraw();\n\t\t});\n\n\t\tthis.canvas.on(\"webglContextFailed\", () => {\n\t\t\talert(\"tctwins failed to find WebGL!\");\n\t\t});\n\n\t\tthis._renderer = new _webgl_Renderer_js__WEBPACK_IMPORTED_MODULE_6__.Renderer(this, {\n\t\t\ttransparent: this._transparent,\n\t\t\talphaDepthMask: alphaDepthMask,\n\t\t\tedgesEnabled: this._edgesEnabled\n\t\t});\n\n\t\tthis._sectionPlanesState = new (function () {\n\t\t\tthis.sectionPlanes = [];\n\n\t\t\tthis.clippingCaps = false;\n\n\t\t\tthis._numCachedSectionPlanes = 0;\n\n\t\t\tlet hash = null;\n\n\t\t\tthis.getHash = function () {\n\t\t\t\tif (hash) {\n\t\t\t\t\treturn hash;\n\t\t\t\t}\n\t\t\t\tconst numAllocatedSectionPlanes = this.getNumAllocatedSectionPlanes();\n\t\t\t\tconst sectionPlanes = this.sectionPlanes;\n\t\t\t\tif (numAllocatedSectionPlanes === 0) {\n\t\t\t\t\treturn (this.hash = \";\");\n\t\t\t\t}\n\t\t\t\tlet sectionPlane;\n\n\t\t\t\tconst hashParts = [];\n\t\t\t\tfor (let i = 0, len = numAllocatedSectionPlanes; i < len; i++) {\n\t\t\t\t\tsectionPlane = sectionPlanes[i];\n\t\t\t\t\thashParts.push(\"cp\");\n\t\t\t\t}\n\t\t\t\thashParts.push(\";\");\n\t\t\t\thash = hashParts.join(\"\");\n\t\t\t\treturn hash;\n\t\t\t};\n\n\t\t\tthis.addSectionPlane = function (sectionPlane) {\n\t\t\t\tthis.sectionPlanes.push(sectionPlane);\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.removeSectionPlane = function (sectionPlane) {\n\t\t\t\tfor (let i = 0, len = this.sectionPlanes.length; i < len; i++) {\n\t\t\t\t\tif (this.sectionPlanes[i].id === sectionPlane.id) {\n\t\t\t\t\t\tthis.sectionPlanes.splice(i, 1);\n\t\t\t\t\t\thash = null;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.setNumCachedSectionPlanes = function (numCachedSectionPlanes) {\n\t\t\t\tthis._numCachedSectionPlanes = numCachedSectionPlanes;\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.getNumCachedSectionPlanes = function () {\n\t\t\t\treturn this._numCachedSectionPlanes;\n\t\t\t};\n\n\t\t\tthis.getNumAllocatedSectionPlanes = function () {\n\t\t\t\tconst num = this.sectionPlanes.length;\n\t\t\t\treturn num > this._numCachedSectionPlanes ? num : this._numCachedSectionPlanes;\n\t\t\t};\n\t\t})();\n\n\t\tthis._sectionPlanesState.setNumCachedSectionPlanes(cfg.numCachedSectionPlanes || 0);\n\n\t\tthis._lightsState = new (function () {\n\t\t\tconst DEFAULT_AMBIENT = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec4([0, 0, 0, 0]);\n\t\t\tconst ambientColorIntensity = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec4();\n\n\t\t\tthis.lights = [];\n\t\t\tthis.reflectionMaps = [];\n\t\t\tthis.lightMaps = [];\n\n\t\t\tlet hash = null;\n\t\t\tlet ambientLight = null;\n\n\t\t\tthis.getHash = function () {\n\t\t\t\tif (hash) {\n\t\t\t\t\treturn hash;\n\t\t\t\t}\n\t\t\t\tconst hashParts = [];\n\t\t\t\tconst lights = this.lights;\n\t\t\t\tlet light;\n\t\t\t\tfor (let i = 0, len = lights.length; i < len; i++) {\n\t\t\t\t\tlight = lights[i];\n\t\t\t\t\thashParts.push(\"/\");\n\t\t\t\t\thashParts.push(light.type);\n\t\t\t\t\thashParts.push(light.space === \"world\" ? \"w\" : \"v\");\n\t\t\t\t\tif (light.castsShadow) {\n\t\t\t\t\t\thashParts.push(\"sh\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (this.lightMaps.length > 0) {\n\t\t\t\t\thashParts.push(\"/lm\");\n\t\t\t\t}\n\t\t\t\tif (this.reflectionMaps.length > 0) {\n\t\t\t\t\thashParts.push(\"/rm\");\n\t\t\t\t}\n\t\t\t\thashParts.push(\";\");\n\t\t\t\thash = hashParts.join(\"\");\n\t\t\t\treturn hash;\n\t\t\t};\n\n\t\t\tthis.addLight = function (state) {\n\t\t\t\tthis.lights.push(state);\n\t\t\t\tambientLight = null;\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.removeLight = function (state) {\n\t\t\t\tfor (let i = 0, len = this.lights.length; i < len; i++) {\n\t\t\t\t\tconst light = this.lights[i];\n\t\t\t\t\tif (light.id === state.id) {\n\t\t\t\t\t\tthis.lights.splice(i, 1);\n\t\t\t\t\t\tif (ambientLight && ambientLight.id === state.id) {\n\t\t\t\t\t\t\tambientLight = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\thash = null;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addReflectionMap = function (state) {\n\t\t\t\tthis.reflectionMaps.push(state);\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.removeReflectionMap = function (state) {\n\t\t\t\tfor (let i = 0, len = this.reflectionMaps.length; i < len; i++) {\n\t\t\t\t\tif (this.reflectionMaps[i].id === state.id) {\n\t\t\t\t\t\tthis.reflectionMaps.splice(i, 1);\n\t\t\t\t\t\thash = null;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addLightMap = function (state) {\n\t\t\t\tthis.lightMaps.push(state);\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.removeLightMap = function (state) {\n\t\t\t\tfor (let i = 0, len = this.lightMaps.length; i < len; i++) {\n\t\t\t\t\tif (this.lightMaps[i].id === state.id) {\n\t\t\t\t\t\tthis.lightMaps.splice(i, 1);\n\t\t\t\t\t\thash = null;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.getAmbientColorAndIntensity = function () {\n\t\t\t\tif (!ambientLight) {\n\t\t\t\t\tfor (let i = 0, len = this.lights.length; i < len; i++) {\n\t\t\t\t\t\tconst light = this.lights[i];\n\t\t\t\t\t\tif (light.type === \"ambient\") {\n\t\t\t\t\t\t\tambientLight = light;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (ambientLight) {\n\t\t\t\t\tconst color = ambientLight.color;\n\t\t\t\t\tconst intensity = ambientLight.intensity;\n\t\t\t\t\tambientColorIntensity[0] = color[0];\n\t\t\t\t\tambientColorIntensity[1] = color[1];\n\t\t\t\t\tambientColorIntensity[2] = color[2];\n\t\t\t\t\tambientColorIntensity[3] = intensity;\n\t\t\t\t\treturn ambientColorIntensity;\n\t\t\t\t} else {\n\t\t\t\t\treturn DEFAULT_AMBIENT;\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\n\t\t/**\n\t\t * Publishes input events that occur on this Scene's canvas.\n\t\t * @property input\n\t\t * @type {Input}\n\t\t * @final\n\t\t */\n\t\tthis.input = new _input_Input_js__WEBPACK_IMPORTED_MODULE_7__.Input(this, {\n\t\t\tdontClear: true, // Never destroy this component with Scene#clear();\n\t\t\telement: this.canvas.canvas,\n\t\t\tkeyboardEventsElement: cfg.keyboardEventsElement\n\t\t});\n\n\t\t/**\n\t\t * Configures this Scene's units of measurement and coordinate mapping between Real-space and World-space 3D coordinate systems.\n\t\t *\n\t\t * @property metrics\n\t\t * @type {Metrics}\n\t\t * @final\n\t\t */\n\t\tthis.metrics = new _metriqs_Metriqs_js__WEBPACK_IMPORTED_MODULE_17__.Metrics(this, {\n\t\t\tunits: cfg.units,\n\t\t\tscale: cfg.scale,\n\t\t\torigin: cfg.origin\n\t\t});\n\n\t\t/** Configures Scalable Ambient Obscurance (SAO) for this Scene.\n\t\t * @type {SAO}\n\t\t * @final\n\t\t */\n\t\tthis.sao = new _postfx_SAO_js__WEBPACK_IMPORTED_MODULE_18__.SAO(this, {\n\t\t\tenabled: cfg.saoEnabled\n\t\t});\n\n\t\tthis.ticksPerRender = cfg.ticksPerRender;\n\t\tthis.ticksPerOcclusionTest = cfg.ticksPerOcclusionTest;\n\t\tthis.passes = cfg.passes;\n\t\tthis.clearEachPass = cfg.clearEachPass;\n\t\tthis.gammaInput = cfg.gammaInput;\n\t\tthis.gammaOutput = cfg.gammaOutput;\n\t\tthis.gammaFactor = cfg.gammaFactor;\n\n\t\tthis._entityOffsetsEnabled = !!cfg.entityOffsetsEnabled;\n\t\tthis._logarithmicDepthBufferEnabled = !!cfg.logarithmicDepthBufferEnabled;\n\n\t\tthis._dtxEnabled = cfg.dtxEnabled !== false;\n\t\tthis._pbrEnabled = !!cfg.pbrEnabled;\n\t\tthis._colorTextureEnabled = cfg.colorTextureEnabled !== false;\n\t\tthis._dtxEnabled = !!cfg.dtxEnabled;\n\t\tthis._lodEnabled = cfg.lodEnabled !== false;\n\n\t\t// Register Scene on xeokit\n\t\t// Do this BEFORE we add components below\n\t\t_core_js__WEBPACK_IMPORTED_MODULE_0__.core._addScene(this);\n\n\t\tthis._initDefaults();\n\n\t\t// Global components\n\n\t\tthis._viewport = new _viewport_Viewport_js__WEBPACK_IMPORTED_MODULE_8__.Viewport(this, {\n\t\t\tid: \"default.viewport\",\n\t\t\tautoBoundary: true,\n\t\t\tdontClear: true // Never destroy this component with Scene#clear();\n\t\t});\n\n\t\tthis._camera = new _camera_Camera_js__WEBPACK_IMPORTED_MODULE_9__.Camera(this, {\n\t\t\tid: \"default.camera\",\n\t\t\tdontClear: true // Never destroy this component with Scene#clear();\n\t\t});\n\n\t\t// Default lights\n\n\t\tnew _lights_AmbientLight_js__WEBPACK_IMPORTED_MODULE_11__.AmbientLight(this, {\n\t\t\tcolor: [1.0, 1.0, 1.0],\n\t\t\tintensity: 0.7\n\t\t});\n\n\t\tnew _lights_DirLight_js__WEBPACK_IMPORTED_MODULE_10__.DirLight(this, {\n\t\t\tdir: [0.8, -0.5, -0.5],\n\t\t\tcolor: [0.67, 0.67, 1.0],\n\t\t\tintensity: 0.7,\n\t\t\tspace: \"world\"\n\t\t});\n\n\t\tnew _lights_DirLight_js__WEBPACK_IMPORTED_MODULE_10__.DirLight(this, {\n\t\t\tdir: [-0.8, -1.0, 0.5],\n\t\t\tcolor: [1, 1, 0.9],\n\t\t\tintensity: 0.9,\n\t\t\tspace: \"world\"\n\t\t});\n\n\t\tthis._camera.on(\"dirty\", () => {\n\t\t\tthis._renderer.imageDirty();\n\t\t});\n\n\t\tthis._lod = new _lod_LOD_js__WEBPACK_IMPORTED_MODULE_1__.LOD(this, {\n\t\t\tenabled: this._lodEnabled,\n\t\t\ttargetFPS: 30\n\t\t});\n\t}\n\n\t_initDefaults() {\n\t\t// Call this Scene's property accessors to lazy-init their properties\n\n\t\tlet dummy; // Keeps Codacy happy\n\n\t\tdummy = this.geometry;\n\t\tdummy = this.material;\n\t\tdummy = this.xrayMaterial;\n\t\tdummy = this.edgeMaterial;\n\t\tdummy = this.selectedMaterial;\n\t\tdummy = this.highlightMaterial;\n\t}\n\n\t_addComponent(component) {\n\t\tif (component.id) {\n\t\t\t// Manual ID\n\t\t\tif (this.components[component.id]) {\n\t\t\t\tthis.error(\n\t\t\t\t\t\"Component \" +\n\t\t\t\t\t\t_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.inQuotes(component.id) +\n\t\t\t\t\t\t\" already exists in Scene - ignoring ID, will randomly-generate instead\"\n\t\t\t\t);\n\t\t\t\tcomponent.id = null;\n\t\t\t}\n\t\t}\n\t\tif (!component.id) {\n\t\t\t// Auto ID\n\t\t\tif (window.nextID === undefined) {\n\t\t\t\twindow.nextID = 0;\n\t\t\t}\n\t\t\t//component.id = math.createUUID();\n\t\t\tcomponent.id = \"__\" + window.nextID++;\n\t\t\twhile (this.components[component.id]) {\n\t\t\t\tcomponent.id = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.createUUID();\n\t\t\t}\n\t\t}\n\t\tthis.components[component.id] = component;\n\n\t\t// Register for class type\n\t\tconst type = component.type;\n\t\tlet types = this.types[component.type];\n\t\tif (!types) {\n\t\t\ttypes = this.types[type] = {};\n\t\t}\n\t\ttypes[component.id] = component;\n\n\t\tif (component.compile) {\n\t\t\tthis._compilables[component.id] = component;\n\t\t}\n\t\tif (component.isDrawable) {\n\t\t\tthis._renderer.addDrawable(component.id, component);\n\t\t\tthis._collidables[component.id] = component;\n\t\t}\n\t}\n\n\t_removeComponent(component) {\n\t\tvar id = component.id;\n\t\tvar type = component.type;\n\t\tdelete this.components[id];\n\t\t// Unregister for types\n\t\tconst types = this.types[type];\n\t\tif (types) {\n\t\t\tdelete types[id];\n\t\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isEmptyObject(types)) {\n\t\t\t\tdelete this.types[type];\n\t\t\t}\n\t\t}\n\t\tif (component.compile) {\n\t\t\tdelete this._compilables[component.id];\n\t\t}\n\t\tif (component.isDrawable) {\n\t\t\tthis._renderer.removeDrawable(component.id);\n\t\t\tdelete this._collidables[component.id];\n\t\t}\n\t}\n\n\t// Methods below are called by various component types to register themselves on their\n\t// Scene. Violates Hollywood Principle, where we could just filter on type in _addComponent,\n\t// but this is faster than checking the type of each component in such a filter.\n\n\t_sectionPlaneCreated(sectionPlane) {\n\t\tthis.sectionPlanes[sectionPlane.id] = sectionPlane;\n\t\tthis.scene._sectionPlanesState.addSectionPlane(sectionPlane._state);\n\t\tthis.scene.fire(\"sectionPlaneCreated\", sectionPlane, true /* Don't retain event */);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_bitmapCreated(bitmap) {\n\t\tthis.bitmaps[bitmap.id] = bitmap;\n\t\tthis.scene.fire(\"bitmapCreated\", bitmap, true /* Don't retain event */);\n\t}\n\n\t_lineSetCreated(lineSet) {\n\t\tthis.lineSets[lineSet.id] = lineSet;\n\t\tthis.scene.fire(\"lineSetCreated\", lineSet, true /* Don't retain event */);\n\t}\n\n\t_lightCreated(light) {\n\t\tthis.lights[light.id] = light;\n\t\tthis.scene._lightsState.addLight(light._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_lightMapCreated(lightMap) {\n\t\tthis.lightMaps[lightMap.id] = lightMap;\n\t\tthis.scene._lightsState.addLightMap(lightMap._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_reflectionMapCreated(reflectionMap) {\n\t\tthis.reflectionMaps[reflectionMap.id] = reflectionMap;\n\t\tthis.scene._lightsState.addReflectionMap(reflectionMap._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_sectionPlaneDestroyed(sectionPlane) {\n\t\tdelete this.sectionPlanes[sectionPlane.id];\n\t\tthis.scene._sectionPlanesState.removeSectionPlane(sectionPlane._state);\n\t\tthis.scene.fire(\"sectionPlaneDestroyed\", sectionPlane, true /* Don't retain event */);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_bitmapDestroyed(bitmap) {\n\t\tdelete this.bitmaps[bitmap.id];\n\t\tthis.scene.fire(\"bitmapDestroyed\", bitmap, true /* Don't retain event */);\n\t}\n\n\t_lineSetDestroyed(lineSet) {\n\t\tdelete this.lineSets[lineSet.id];\n\t\tthis.scene.fire(\"lineSetDestroyed\", lineSet, true /* Don't retain event */);\n\t}\n\n\t_lightDestroyed(light) {\n\t\tdelete this.lights[light.id];\n\t\tthis.scene._lightsState.removeLight(light._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_lightMapDestroyed(lightMap) {\n\t\tdelete this.lightMaps[lightMap.id];\n\t\tthis.scene._lightsState.removeLightMap(lightMap._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_reflectionMapDestroyed(reflectionMap) {\n\t\tdelete this.reflectionMaps[reflectionMap.id];\n\t\tthis.scene._lightsState.removeReflectionMap(reflectionMap._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_registerModel(entity) {\n\t\tthis.models[entity.id] = entity;\n\t\tthis._modelIds = null; // Lazy regenerate\n\t}\n\n\t_deregisterModel(entity) {\n\t\tconst modelId = entity.id;\n\t\tdelete this.models[modelId];\n\t\tthis._modelIds = null; // Lazy regenerate\n\t\tthis.fire(\"modelUnloaded\", modelId);\n\t}\n\n\t_registerObject(entity) {\n\t\tthis.objects[entity.id] = entity;\n\t\tthis._numObjects++;\n\t\tthis._objectIds = null; // Lazy regenerate\n\t}\n\n\t_deregisterObject(entity) {\n\t\tdelete this.objects[entity.id];\n\t\tthis._numObjects--;\n\t\tthis._objectIds = null; // Lazy regenerate\n\t}\n\n\t_objectVisibilityUpdated(entity, notify = true) {\n\t\tif (entity.visible) {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.visibleObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object visibility update (visible=true)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.visibleObjects[entity.id] = entity;\n\t\t\tthis._numVisibleObjects++;\n\t\t} else {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.visibleObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object visibility update (visible=false)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete this.visibleObjects[entity.id];\n\t\t\tthis._numVisibleObjects--;\n\t\t}\n\t\tthis._visibleObjectIds = null; // Lazy regenerate\n\t\tif (notify) {\n\t\t\tthis.fire(\"objectVisibility\", entity, true);\n\t\t}\n\t}\n\n\t_deRegisterVisibleObject(entity) {\n\t\tdelete this.visibleObjects[entity.id];\n\t\tthis._numVisibleObjects--;\n\t\tthis._visibleObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectXRayedUpdated(entity, notify = true) {\n\t\tif (entity.xrayed) {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.xrayedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object xray update (xrayed=true)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.xrayedObjects[entity.id] = entity;\n\t\t\tthis._numXRayedObjects++;\n\t\t} else {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.xrayedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object xray update (xrayed=false)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete this.xrayedObjects[entity.id];\n\t\t\tthis._numXRayedObjects--;\n\t\t}\n\t\tthis._xrayedObjectIds = null; // Lazy regenerate\n\t\tif (notify) {\n\t\t\tthis.fire(\"objectXRayed\", entity, true);\n\t\t}\n\t}\n\n\t_deRegisterXRayedObject(entity) {\n\t\tdelete this.xrayedObjects[entity.id];\n\t\tthis._numXRayedObjects--;\n\t\tthis._xrayedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectHighlightedUpdated(entity) {\n\t\tif (entity.highlighted) {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.highlightedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object highlight update (highlighted=true)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.highlightedObjects[entity.id] = entity;\n\t\t\tthis._numHighlightedObjects++;\n\t\t} else {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.highlightedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object highlight update (highlighted=false)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete this.highlightedObjects[entity.id];\n\t\t\tthis._numHighlightedObjects--;\n\t\t}\n\t\tthis._highlightedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_deRegisterHighlightedObject(entity) {\n\t\tdelete this.highlightedObjects[entity.id];\n\t\tthis._numHighlightedObjects--;\n\t\tthis._highlightedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectSelectedUpdated(entity, notify = true) {\n\t\tif (entity.selected) {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.selectedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object select update (selected=true)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.selectedObjects[entity.id] = entity;\n\t\t\tthis._numSelectedObjects++;\n\t\t} else {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.selectedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object select update (selected=false)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete this.selectedObjects[entity.id];\n\t\t\tthis._numSelectedObjects--;\n\t\t}\n\t\tthis._selectedObjectIds = null; // Lazy regenerate\n\t\tif (notify) {\n\t\t\tthis.fire(\"objectSelected\", entity, true);\n\t\t}\n\t}\n\n\t_deRegisterSelectedObject(entity) {\n\t\tdelete this.selectedObjects[entity.id];\n\t\tthis._numSelectedObjects--;\n\t\tthis._selectedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectColorizeUpdated(entity, colorized) {\n\t\tif (colorized) {\n\t\t\tthis.colorizedObjects[entity.id] = entity;\n\t\t\tthis._numColorizedObjects++;\n\t\t} else {\n\t\t\tdelete this.colorizedObjects[entity.id];\n\t\t\tthis._numColorizedObjects--;\n\t\t}\n\t\tthis._colorizedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_deRegisterColorizedObject(entity) {\n\t\tdelete this.colorizedObjects[entity.id];\n\t\tthis._numColorizedObjects--;\n\t\tthis._colorizedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectOpacityUpdated(entity, opacityUpdated) {\n\t\tif (opacityUpdated) {\n\t\t\tthis.opacityObjects[entity.id] = entity;\n\t\t\tthis._numOpacityObjects++;\n\t\t} else {\n\t\t\tdelete this.opacityObjects[entity.id];\n\t\t\tthis._numOpacityObjects--;\n\t\t}\n\t\tthis._opacityObjectIds = null; // Lazy regenerate\n\t}\n\n\t_deRegisterOpacityObject(entity) {\n\t\tdelete this.opacityObjects[entity.id];\n\t\tthis._numOpacityObjects--;\n\t\tthis._opacityObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectOffsetUpdated(entity, offset) {\n\t\tif (!offset || (offset[0] === 0 && offset[1] === 0 && offset[2] === 0)) {\n\t\t\tthis.offsetObjects[entity.id] = entity;\n\t\t\tthis._numOffsetObjects++;\n\t\t} else {\n\t\t\tdelete this.offsetObjects[entity.id];\n\t\t\tthis._numOffsetObjects--;\n\t\t}\n\t\tthis._offsetObjectIds = null; // Lazy regenerate\n\t}\n\n\t_deRegisterOffsetObject(entity) {\n\t\tdelete this.offsetObjects[entity.id];\n\t\tthis._numOffsetObjects--;\n\t\tthis._offsetObjectIds = null; // Lazy regenerate\n\t}\n\n\t_webglContextLost() {\n\t\t// this.loading++;\n\t\tthis.canvas.spinner.processes++;\n\t\tfor (const id in this.components) {\n\t\t\tif (this.components.hasOwnProperty(id)) {\n\t\t\t\tconst component = this.components[id];\n\t\t\t\tif (component._webglContextLost) {\n\t\t\t\t\tcomponent._webglContextLost();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis._renderer.webglContextLost();\n\t}\n\n\t_webglContextRestored() {\n\t\tconst gl = this.canvas.gl;\n\t\tfor (const id in this.components) {\n\t\t\tif (this.components.hasOwnProperty(id)) {\n\t\t\t\tconst component = this.components[id];\n\t\t\t\tif (component._webglContextRestored) {\n\t\t\t\t\tcomponent._webglContextRestored(gl);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis._renderer.webglContextRestored(gl);\n\t\t//this.loading--;\n\t\tthis.canvas.spinner.processes--;\n\t}\n\n\t/**\n\t * Returns the capabilities of this Scene.\n\t *\n\t * @private\n\t * @returns {{astcSupported: boolean, etc1Supported: boolean, pvrtcSupported: boolean, etc2Supported: boolean, dxtSupported: boolean, bptcSupported: boolean}}\n\t */\n\tget capabilities() {\n\t\treturn this._renderer.capabilities;\n\t}\n\n\t/**\n\t * Whether {@link Entity#offset} is enabled.\n\t *\n\t * This is set via the {@link Viewer} constructor and is ````false```` by default.\n\t *\n\t * @returns {Boolean} True if {@link Entity#offset} is enabled.\n\t */\n\tget entityOffsetsEnabled() {\n\t\treturn this._entityOffsetsEnabled;\n\t}\n\n\t/**\n\t * Whether precision surface picking is enabled.\n\t *\n\t * This is set via the {@link Viewer} constructor and is ````false```` by default.\n\t *\n\t * The ````pickSurfacePrecision```` option for ````Scene#pick```` only works if this is set ````true````.\n\t *\n\t * Note that when ````true````, this configuration will increase the amount of browser memory used by the Viewer.\n\t *\n\t * @returns {Boolean} True if precision picking is enabled.\n\t */\n\tget pickSurfacePrecisionEnabled() {\n\t\treturn false; // Removed\n\t}\n\n\t/**\n\t * Whether logarithmic depth buffer is enabled.\n\t *\n\t * This is set via the {@link Viewer} constructor and is ````false```` by default.\n\t *\n\t * @returns {Boolean} True if logarithmic depth buffer is enabled.\n\t */\n\tget logarithmicDepthBufferEnabled() {\n\t\treturn this._logarithmicDepthBufferEnabled;\n\t}\n\n\t/**\n\t * Sets the number of {@link SectionPlane}s for which this Scene pre-caches resources.\n\t *\n\t * This property enhances the efficiency of SectionPlane creation by proactively allocating and caching Viewer resources for a specified quantity\n\t * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n\t * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n\t * responsiveness. It is important to consider that each SectionPlane impacts rendering performance, so it is recommended to set this value to a quantity that aligns with\n\t * your expected usage.\n\t *\n\t * Default is ````0````.\n\t */\n\tset numCachedSectionPlanes(numCachedSectionPlanes) {\n\t\tnumCachedSectionPlanes = numCachedSectionPlanes || 0;\n\t\tif (this._sectionPlanesState.getNumCachedSectionPlanes() !== numCachedSectionPlanes) {\n\t\t\tthis._sectionPlanesState.setNumCachedSectionPlanes(numCachedSectionPlanes);\n\t\t\tthis._needRecompile = true;\n\t\t\tthis.glRedraw();\n\t\t}\n\t}\n\n\t/**\n\t * Gets the number of {@link SectionPlane}s for which this Scene pre-caches resources.\n\t *\n\t * This property enhances the efficiency of SectionPlane creation by proactively allocating and caching Viewer resources for a specified quantity\n\t * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n\t * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n\t * responsiveness. It is important to consider that each SectionPlane impacts rendering performance, so it is recommended to set this value to a quantity that aligns with\n\t * your expected usage.\n\t *\n\t * Default is ````0````.\n\t *\n\t * @returns {number} The number of {@link SectionPlane}s for which this Scene pre-caches resources.\n\t */\n\tget numCachedSectionPlanes() {\n\t\treturn this._sectionPlanesState.getNumCachedSectionPlanes();\n\t}\n\n\t/**\n\t * Sets whether physically-based rendering is enabled.\n\t *\n\t * Default is ````false````.\n\t */\n\tset pbrEnabled(pbrEnabled) {\n\t\tthis._pbrEnabled = !!pbrEnabled;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets whether physically-based rendering is enabled.\n\t *\n\t * Default is ````false````.\n\t *\n\t * @returns {Boolean} True if quality rendering is enabled.\n\t */\n\tget pbrEnabled() {\n\t\treturn this._pbrEnabled;\n\t}\n\n\t/**\n\t * Sets whether data texture scene representation (DTX) is enabled for the {@link Scene}.\n\t *\n\t * Even when enabled, DTX will only work if supported.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tset dtxEnabled(value) {\n\t\tvalue = !!value;\n\t\tif (this._dtxEnabled === value) {\n\t\t\treturn;\n\t\t}\n\t\tthis._dtxEnabled = value;\n\t}\n\n\t/**\n\t * Gets whether data texture-based scene representation (DTX) is enabled for the {@link Scene}.\n\t *\n\t * Even when enabled, DTX will only apply if supported.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget dtxEnabled() {\n\t\treturn this._dtxEnabled;\n\t}\n\n\t/**\n\t * set showedges enable\n\t * @param {boolean} edgesEnabled\n\t */\n\tset edgesEnabled(edgesEnabled) {\n\t\tedgesEnabled = !!edgesEnabled;\n\t\tif (this._edgesEnabled === edgesEnabled) {\n\t\t\treturn;\n\t\t}\n\t\tthis._edgesEnabled = edgesEnabled;\n\t\tthis._renderer.setEdgesEnabled(edgesEnabled);\n\t}\n\n\t/**\n\t * @param {boolean} trans\n\t */\n\tget edgesEnabled() {\n\t\treturn this._edgesEnabled;\n\t}\n\n\t/**\n\t * set whether transparent of canvas background\n\t * @param {boolean} trans\n\t */\n\tset backgroundTransparent(trans) {\n\t\ttrans = !!trans;\n\t\t// if (this._transparent == trans) {\n\t\t// return;\n\t\t// }\n\t\tthis._transparent = trans;\n\t\tthis._renderer.setTransparentEnabled(trans);\n\t}\n\n\t/**\n\t * @returns {boolean} backgroundTransparent\n\t */\n\tget backgroundTransparent() {\n\t\treturn this._transparent;\n\t}\n\n\t/**\n\t * set background color\n\t * @param {[]} color\n\t */\n\tset backgroundColor(color) {\n\t\tthis.canvas.backgroundColor = color;\n\t\tthis._renderer.render({ force: true });\n\t}\n\n\t/**\n\t * return backgroundColor\n\t * @returns {boolean} backgroundColor\n\t */\n\tget backgroundColor() {\n\t\treturn this.canvas.backgroundColor();\n\t}\n\n\t/**\n\t * Sets whether basic color texture rendering is enabled.\n\t *\n\t * Default is ````true````.\n\t *\n\t * @returns {Boolean} True if basic color texture rendering is enabled.\n\t */\n\tset colorTextureEnabled(colorTextureEnabled) {\n\t\tthis._colorTextureEnabled = !!colorTextureEnabled;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets whether basic color texture rendering is enabled.\n\t *\n\t * Default is ````true````.\n\t *\n\t * @returns {Boolean} True if basic color texture rendering is enabled.\n\t */\n\tget colorTextureEnabled() {\n\t\treturn this._colorTextureEnabled;\n\t}\n\n\t/**\n\t * Performs an occlusion test on all {@link Marker}s in this {@link Scene}.\n\t *\n\t * Sets each {@link Marker#visible} ````true```` if the Marker is currently not occluded by any opaque {@link Entity}s\n\t * in the Scene, or ````false```` if an Entity is occluding it.\n\t */\n\tdoOcclusionTest() {\n\t\tif (this._needRecompile) {\n\t\t\tthis._recompile();\n\t\t\tthis._needRecompile = false;\n\t\t}\n\t\tthis._renderer.doOcclusionTest();\n\t}\n\n\t/**\n\t * Renders a single frame of this Scene.\n\t *\n\t * The Scene will periodically render itself after any updates, but you can call this method to force a render\n\t * if required.\n\t *\n\t * @param {Boolean} [forceRender=false] Forces a render when true, otherwise only renders if something has changed in this Scene\n\t * since the last render.\n\t */\n\trender(forceRender) {\n\t\tif (forceRender) {\n\t\t\t_core_js__WEBPACK_IMPORTED_MODULE_0__.core.runTasks();\n\t\t}\n\n\t\tconst renderEvent = {\n\t\t\tsceneId: null,\n\t\t\tpass: 0\n\t\t};\n\n\t\tif (this._needRecompile) {\n\t\t\tthis._recompile();\n\t\t\tthis._renderer.imageDirty();\n\t\t\tthis._needRecompile = false;\n\t\t}\n\n\t\tif (!forceRender && !this._renderer.needsRender()) {\n\t\t\treturn;\n\t\t}\n\n\t\trenderEvent.sceneId = this.id;\n\n\t\tconst passes = this._passes;\n\t\tconst clearEachPass = this._clearEachPass;\n\t\tlet pass;\n\t\tlet clear;\n\n\t\tfor (pass = 0; pass < passes; pass++) {\n\t\t\trenderEvent.pass = pass;\n\n\t\t\t/**\n\t\t\t * Fired when about to render a frame for a Scene.\n\t\t\t *\n\t\t\t * @event rendering\n\t\t\t * @param {String} sceneID The ID of this Scene.\n\t\t\t * @param {Number} pass Index of the pass we are about to render (see {@link Scene#passes}).\n\t\t\t */\n\t\t\tthis.fire(\"rendering\", renderEvent, true);\n\n\t\t\tclear = clearEachPass || pass === 0;\n\n\t\t\tthis._renderer.render({ pass: pass, clear: clear, force: forceRender });\n\n\t\t\t/**\n\t\t\t * Fired when we have just rendered a frame for a Scene.\n\t\t\t *\n\t\t\t * @event rendering\n\t\t\t * @param {String} sceneID The ID of this Scene.\n\t\t\t * @param {Number} pass Index of the pass we rendered (see {@link Scene#passes}).\n\t\t\t */\n\t\t\tthis.fire(\"rendered\", renderEvent, true);\n\t\t}\n\n\t\tthis._saveAmbientColor();\n\t}\n\n\t/**\n\t * @private\n\t */\n\tcompile() {\n\t\tif (this._needRecompile) {\n\t\t\tthis._recompile();\n\t\t\tthis._renderer.imageDirty();\n\t\t\tthis._needRecompile = false;\n\t\t}\n\t}\n\n\t_recompile() {\n\t\tfor (const id in this._compilables) {\n\t\t\tif (this._compilables.hasOwnProperty(id)) {\n\t\t\t\tthis._compilables[id].compile();\n\t\t\t}\n\t\t}\n\t\tthis._renderer.shadowsDirty();\n\t\tthis.fire(\"compile\", this, true);\n\t}\n\n\t_saveAmbientColor() {\n\t\tconst canvas = this.canvas;\n\t\tif (!canvas.transparent && !canvas.backgroundImage && !canvas.backgroundColor) {\n\t\t\tconst ambientColorIntensity = this._lightsState.getAmbientColorAndIntensity();\n\t\t\tif (\n\t\t\t\t!this._lastAmbientColor ||\n\t\t\t\tthis._lastAmbientColor[0] !== ambientColorIntensity[0] ||\n\t\t\t\tthis._lastAmbientColor[1] !== ambientColorIntensity[1] ||\n\t\t\t\tthis._lastAmbientColor[2] !== ambientColorIntensity[2] ||\n\t\t\t\tthis._lastAmbientColor[3] !== ambientColorIntensity[3]\n\t\t\t) {\n\t\t\t\tcanvas.backgroundColor = ambientColorIntensity;\n\t\t\t\tif (!this._lastAmbientColor) {\n\t\t\t\t\tthis._lastAmbientColor = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec4([0, 0, 0, 1]);\n\t\t\t\t}\n\t\t\t\tthis._lastAmbientColor.set(ambientColorIntensity);\n\t\t\t}\n\t\t} else {\n\t\t\tthis._lastAmbientColor = null;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#models}.\n\t *\n\t * @type {String[]}\n\t */\n\tget modelIds() {\n\t\tif (!this._modelIds) {\n\t\t\tthis._modelIds = Object.keys(this.models);\n\t\t}\n\t\treturn this._modelIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#objects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numObjects() {\n\t\treturn this._numObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#objects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget objectIds() {\n\t\tif (!this._objectIds) {\n\t\t\tthis._objectIds = Object.keys(this.objects);\n\t\t}\n\t\treturn this._objectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#visibleObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numVisibleObjects() {\n\t\treturn this._numVisibleObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#visibleObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget visibleObjectIds() {\n\t\tif (!this._visibleObjectIds) {\n\t\t\tthis._visibleObjectIds = Object.keys(this.visibleObjects);\n\t\t}\n\t\treturn this._visibleObjectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#xrayedObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numXRayedObjects() {\n\t\treturn this._numXRayedObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#xrayedObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget xrayedObjectIds() {\n\t\tif (!this._xrayedObjectIds) {\n\t\t\tthis._xrayedObjectIds = Object.keys(this.xrayedObjects);\n\t\t}\n\t\treturn this._xrayedObjectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#highlightedObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numHighlightedObjects() {\n\t\treturn this._numHighlightedObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#highlightedObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget highlightedObjectIds() {\n\t\tif (!this._highlightedObjectIds) {\n\t\t\tthis._highlightedObjectIds = Object.keys(this.highlightedObjects);\n\t\t}\n\t\treturn this._highlightedObjectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#selectedObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numSelectedObjects() {\n\t\treturn this._numSelectedObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#selectedObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget selectedObjectIds() {\n\t\tif (!this._selectedObjectIds) {\n\t\t\tthis._selectedObjectIds = Object.keys(this.selectedObjects);\n\t\t}\n\t\treturn this._selectedObjectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#colorizedObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numColorizedObjects() {\n\t\treturn this._numColorizedObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#colorizedObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget colorizedObjectIds() {\n\t\tif (!this._colorizedObjectIds) {\n\t\t\tthis._colorizedObjectIds = Object.keys(this.colorizedObjects);\n\t\t}\n\t\treturn this._colorizedObjectIds;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#opacityObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget opacityObjectIds() {\n\t\tif (!this._opacityObjectIds) {\n\t\t\tthis._opacityObjectIds = Object.keys(this.opacityObjects);\n\t\t}\n\t\treturn this._opacityObjectIds;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#offsetObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget offsetObjectIds() {\n\t\tif (!this._offsetObjectIds) {\n\t\t\tthis._offsetObjectIds = Object.keys(this.offsetObjects);\n\t\t}\n\t\treturn this._offsetObjectIds;\n\t}\n\n\t/**\n\t * Sets the number of \"ticks\" that happen between each render or this Scene.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tset ticksPerRender(value) {\n\t\tif (value === undefined || value === null) {\n\t\t\tvalue = 1;\n\t\t} else if (!_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isNumeric(value) || value <= 0) {\n\t\t\tthis.error(\"Unsupported value for 'ticksPerRender': '\" + value + \"' - should be an integer greater than zero.\");\n\t\t\tvalue = 1;\n\t\t}\n\t\tif (value === this._ticksPerRender) {\n\t\t\treturn;\n\t\t}\n\t\tthis._ticksPerRender = value;\n\t}\n\n\t/**\n\t * Gets the number of \"ticks\" that happen between each render or this Scene.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tget ticksPerRender() {\n\t\treturn this._ticksPerRender;\n\t}\n\n\t/**\n\t * Sets the number of \"ticks\" that happen between occlusion testing for {@link Marker}s.\n\t *\n\t * Default value is ````20````.\n\t *\n\t * @type {Number}\n\t */\n\tset ticksPerOcclusionTest(value) {\n\t\tif (value === undefined || value === null) {\n\t\t\tvalue = 20;\n\t\t} else if (!_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isNumeric(value) || value <= 0) {\n\t\t\tthis.error(\n\t\t\t\t\"Unsupported value for 'ticksPerOcclusionTest': '\" + value + \"' - should be an integer greater than zero.\"\n\t\t\t);\n\t\t\tvalue = 20;\n\t\t}\n\t\tif (value === this._ticksPerOcclusionTest) {\n\t\t\treturn;\n\t\t}\n\t\tthis._ticksPerOcclusionTest = value;\n\t}\n\n\t/**\n\t * Gets the number of \"ticks\" that happen between each render of this Scene.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tget ticksPerOcclusionTest() {\n\t\treturn this._ticksPerOcclusionTest;\n\t}\n\n\t/**\n\t * Sets the number of times this Scene renders per frame.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tset passes(value) {\n\t\tif (value === undefined || value === null) {\n\t\t\tvalue = 1;\n\t\t} else if (!_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isNumeric(value) || value <= 0) {\n\t\t\tthis.error(\"Unsupported value for 'passes': '\" + value + \"' - should be an integer greater than zero.\");\n\t\t\tvalue = 1;\n\t\t}\n\t\tif (value === this._passes) {\n\t\t\treturn;\n\t\t}\n\t\tthis._passes = value;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the number of times this Scene renders per frame.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tget passes() {\n\t\treturn this._passes;\n\t}\n\n\t/**\n\t * When {@link Scene#passes} is greater than ````1````, indicates whether or not to clear the canvas before each pass (````true````) or just before the first pass (````false````).\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tset clearEachPass(value) {\n\t\tvalue = !!value;\n\t\tif (value === this._clearEachPass) {\n\t\t\treturn;\n\t\t}\n\t\tthis._clearEachPass = value;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * When {@link Scene#passes} is greater than ````1````, indicates whether or not to clear the canvas before each pass (````true````) or just before the first pass (````false````).\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget clearEachPass() {\n\t\treturn this._clearEachPass;\n\t}\n\n\t/**\n\t * Sets whether or not {@link Scene} should expect all {@link Texture}s and colors to have pre-multiplied gamma.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tset gammaInput(value) {\n\t\tvalue = value !== false;\n\t\tif (value === this._renderer.gammaInput) {\n\t\t\treturn;\n\t\t}\n\t\tthis._renderer.gammaInput = value;\n\t\tthis._needRecompile = true;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets whether or not {@link Scene} should expect all {@link Texture}s and colors to have pre-multiplied gamma.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget gammaInput() {\n\t\treturn this._renderer.gammaInput;\n\t}\n\n\t/**\n\t * Sets whether or not to render pixels with pre-multiplied gama.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tset gammaOutput(value) {\n\t\tvalue = !!value;\n\t\tif (value === this._renderer.gammaOutput) {\n\t\t\treturn;\n\t\t}\n\t\tthis._renderer.gammaOutput = value;\n\t\tthis._needRecompile = true;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets whether or not to render pixels with pre-multiplied gama.\n\t *\n\t * Default value is ````true````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget gammaOutput() {\n\t\treturn this._renderer.gammaOutput;\n\t}\n\n\t/**\n\t * Sets the gamma factor to use when {@link Scene#gammaOutput} is set true.\n\t *\n\t * Default value is ````2.2````.\n\t *\n\t * @type {Number}\n\t */\n\tset gammaFactor(value) {\n\t\tvalue = value === undefined || value === null ? 2.2 : value;\n\t\tif (value === this._renderer.gammaFactor) {\n\t\t\treturn;\n\t\t}\n\t\tthis._renderer.gammaFactor = value;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the gamma factor to use when {@link Scene#gammaOutput} is set true.\n\t *\n\t * Default value is ````2.2````.\n\t *\n\t * @type {Number}\n\t */\n\tget gammaFactor() {\n\t\treturn this._renderer.gammaFactor;\n\t}\n\n\t/**\n\t * Gets the default {@link Geometry} for this Scene, which is a {@link ReadableGeometry} with a unit-sized box shape.\n\t *\n\t * Has {@link ReadableGeometry#id} set to \"default.geometry\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#geometry} set to this {@link ReadableGeometry} by default.\n\t *\n\t * @type {ReadableGeometry}\n\t */\n\tget geometry() {\n\t\treturn (\n\t\t\tthis.components[\"default.geometry\"] ||\n\t\t\t(0,_geometry_builders_buildBoxGeometry_js__WEBPACK_IMPORTED_MODULE_13__.buildBoxGeometry)(_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_12__.ReadableGeometry, this, {\n\t\t\t\tid: \"default.geometry\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default {@link Material} for this Scene, which is a {@link PhongMaterial}.\n\t *\n\t * Has {@link PhongMaterial#id} set to \"default.material\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#material} set to this {@link PhongMaterial} by default.\n\t *\n\t * @type {PhongMaterial}\n\t */\n\tget material() {\n\t\treturn (\n\t\t\tthis.components[\"default.material\"] ||\n\t\t\tnew _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_14__.PhongMaterial(this, {\n\t\t\t\tid: \"default.material\",\n\t\t\t\temissive: [0.4, 0.4, 0.4], // Visible by default on geometry without normals\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default xraying {@link EmphasisMaterial} for this Scene.\n\t *\n\t * Has {@link EmphasisMaterial#id} set to \"default.xrayMaterial\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#xrayMaterial} set to this {@link EmphasisMaterial} by default.\n\t *\n\t * {@link Mesh}s are xrayed while {@link Mesh#xrayed} is ````true````.\n\t *\n\t * @type {EmphasisMaterial}\n\t */\n\tget xrayMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.xrayMaterial\"] ||\n\t\t\tnew _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__.EmphasisMaterial(this, {\n\t\t\t\tid: \"default.xrayMaterial\",\n\t\t\t\tpreset: \"sepia\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default highlight {@link EmphasisMaterial} for this Scene.\n\t *\n\t * Has {@link EmphasisMaterial#id} set to \"default.highlightMaterial\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#highlightMaterial} set to this {@link EmphasisMaterial} by default.\n\t *\n\t * {@link Mesh}s are highlighted while {@link Mesh#highlighted} is ````true````.\n\t *\n\t * @type {EmphasisMaterial}\n\t */\n\tget highlightMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.highlightMaterial\"] ||\n\t\t\tnew _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__.EmphasisMaterial(this, {\n\t\t\t\tid: \"default.highlightMaterial\",\n\t\t\t\tpreset: \"yellowHighlight\",\n\t\t\t\tfillAlpha: 0.1,\n\t\t\t\tfillColor: [0.7, 0.9, 0.9],\n\t\t\t\tdontClear: false,\n\t\t\t\tedges: false,\n\t\t\t\tglowThrough: false\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default selection {@link EmphasisMaterial} for this Scene.\n\t *\n\t * Has {@link EmphasisMaterial#id} set to \"default.selectedMaterial\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#highlightMaterial} set to this {@link EmphasisMaterial} by default.\n\t *\n\t * {@link Mesh}s are highlighted while {@link Mesh#highlighted} is ````true````.\n\t *\n\t * @type {EmphasisMaterial}\n\t */\n\tget selectedMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.selectedMaterial\"] ||\n\t\t\tnew _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__.EmphasisMaterial(this, {\n\t\t\t\tid: \"default.selectedMaterial\",\n\t\t\t\tpreset: \"greenSelected\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default {@link EdgeMaterial} for this Scene.\n\t *\n\t * Has {@link EdgeMaterial#id} set to \"default.edgeMaterial\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#edgeMaterial} set to this {@link EdgeMaterial} by default.\n\t *\n\t * {@link Mesh}s have their edges emphasized while {@link Mesh#edges} is ````true````.\n\t *\n\t * @type {EdgeMaterial}\n\t */\n\tget edgeMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.edgeMaterial\"] ||\n\t\t\tnew _materials_EdgeMaterial_js__WEBPACK_IMPORTED_MODULE_16__.EdgeMaterial(this, {\n\t\t\t\tid: \"default.edgeMaterial\",\n\t\t\t\tpreset: \"default\",\n\t\t\t\tedgeColor: [0.0, 0.0, 0.0],\n\t\t\t\tedgeAlpha: 1.0,\n\t\t\t\tedgeWidth: 1,\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the {@link PointsMaterial} for this Scene.\n\t *\n\t * @type {PointsMaterial}\n\t */\n\tget pointsMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.pointsMaterial\"] ||\n\t\t\tnew _materials_PointsMaterial_js__WEBPACK_IMPORTED_MODULE_19__.PointsMaterial(this, {\n\t\t\t\tid: \"default.pointsMaterial\",\n\t\t\t\tpreset: \"default\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the {@link LinesMaterial} for this Scene.\n\t *\n\t * @type {LinesMaterial}\n\t */\n\tget linesMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.linesMaterial\"] ||\n\t\t\tnew _materials_LinesMaterial_js__WEBPACK_IMPORTED_MODULE_20__.LinesMaterial(this, {\n\t\t\t\tid: \"default.linesMaterial\",\n\t\t\t\tpreset: \"default\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the {@link Viewport} for this Scene.\n\t *\n\t * @type Viewport\n\t */\n\tget viewport() {\n\t\treturn this._viewport;\n\t}\n\n\t/**\n\t * Gets the {@link Camera} for this Scene.\n\t *\n\t * @type {Camera}\n\t */\n\tget camera() {\n\t\treturn this._camera;\n\t}\n\n\t/**\n\t * Gets the World-space 3D center of this Scene.\n\t *\n\t *@type {Number[]}\n\t */\n\tget center() {\n\t\tif (this._aabbDirty || !this._center) {\n\t\t\tif (!this._center || !this._center) {\n\t\t\t\tthis._center = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec3();\n\t\t\t}\n\t\t\tconst aabb = this.aabb;\n\t\t\tthis._center[0] = (aabb[0] + aabb[3]) / 2;\n\t\t\tthis._center[1] = (aabb[1] + aabb[4]) / 2;\n\t\t\tthis._center[2] = (aabb[2] + aabb[5]) / 2;\n\t\t}\n\t\treturn this._center;\n\t}\n\n\t/**\n\t * Gets the World-space axis-aligned 3D boundary (AABB) of this Scene.\n\t *\n\t * The AABB is represented by a six-element Float64Array containing the min/max extents of the axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n\t *\n\t * When the Scene has no content, will be ````[-100,-100,-100,100,100,100]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget aabb() {\n\t\tif (this._aabbDirty) {\n\t\t\tif (!this._aabb) {\n\t\t\t\tthis._aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.AABB3();\n\t\t\t}\n\t\t\tlet xmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\t\tlet ymin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\t\tlet zmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\t\tlet xmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\t\tlet ymax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\t\tlet zmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\t\tlet aabb;\n\t\t\tconst collidables = this._collidables;\n\t\t\tlet collidable;\n\t\t\tlet valid = false;\n\t\t\tfor (const collidableId in collidables) {\n\t\t\t\tif (collidables.hasOwnProperty(collidableId)) {\n\t\t\t\t\tcollidable = collidables[collidableId];\n\t\t\t\t\tif (collidable.collidable === false) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\taabb = collidable.aabb;\n\t\t\t\t\tif (aabb[0] < xmin) {\n\t\t\t\t\t\txmin = aabb[0];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[1] < ymin) {\n\t\t\t\t\t\tymin = aabb[1];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[2] < zmin) {\n\t\t\t\t\t\tzmin = aabb[2];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[3] > xmax) {\n\t\t\t\t\t\txmax = aabb[3];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[4] > ymax) {\n\t\t\t\t\t\tymax = aabb[4];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[5] > zmax) {\n\t\t\t\t\t\tzmax = aabb[5];\n\t\t\t\t\t}\n\t\t\t\t\tvalid = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!valid) {\n\t\t\t\txmin = -100;\n\t\t\t\tymin = -100;\n\t\t\t\tzmin = -100;\n\t\t\t\txmax = 100;\n\t\t\t\tymax = 100;\n\t\t\t\tzmax = 100;\n\t\t\t}\n\t\t\tthis._aabb[0] = xmin;\n\t\t\tthis._aabb[1] = ymin;\n\t\t\tthis._aabb[2] = zmin;\n\t\t\tthis._aabb[3] = xmax;\n\t\t\tthis._aabb[4] = ymax;\n\t\t\tthis._aabb[5] = zmax;\n\t\t\tthis._aabbDirty = false;\n\t\t}\n\t\treturn this._aabb;\n\t}\n\n\t_setAABBDirty() {\n\t\t//if (!this._aabbDirty) {\n\t\tthis._aabbDirty = true;\n\t\tthis.fire(\"boundary\");\n\t\t// }\n\t}\n\n\t/**\n * Attempts to pick an {@link Entity} in this Scene.\n *\n * Ignores {@link Entity}s with {@link Entity#pickable} set ````false````.\n *\n * When an {@link Entity} is picked, fires a \"pick\" event on the {@link Entity} with the pick result as parameters.\n *\n * Picking the {@link Entity} at the given canvas coordinates:\n\n * ````javascript\n * var pickResult = scene.pick({\n * canvasPos: [23, 131]\n * });\n *\n * if (pickResult) { // Picked an Entity\n * var entity = pickResult.entity;\n * }\n * ````\n *\n * Picking, with a ray cast through the canvas, hits an {@link Entity}:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * pickSurface: true,\n * canvasPos: [23, 131]\n * });\n *\n * if (pickResult) { // Picked an Entity\n *\n * var entity = pickResult.entity;\n *\n * if (pickResult.primitive === \"triangle\") {\n *\n * // Picked a triangle on the entity surface\n *\n * var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Entity's Geometry's indices array\n * var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\n * var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\n * var viewPos = pickResult.viewPos; // Float64Array containing the picked View-space position on the triangle\n * var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the interpolated World-space normal vector at the picked position on the triangle\n * var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\n *\n * } else if (pickResult.worldPos && pickResult.worldNormal) {\n *\n * // Picked a point and normal on the entity surface\n *\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the Entity surface\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the picked World-space normal vector on the Entity Surface\n * }\n * }\n * ````\n *\n * Picking the {@link Entity} that intersects an arbitrarily-aligned World-space ray:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * pickSurface: true, // Picking with arbitrarily-positioned ray\n * origin: [0,0,-5], // Ray origin\n * direction: [0,0,1] // Ray direction\n * });\n *\n * if (pickResult) { // Picked an Entity with the ray\n *\n * var entity = pickResult.entity;\n *\n * if (pickResult.primitive == \"triangle\") {\n *\n * // Picked a triangle on the entity surface\n *\n * var primitive = pickResult.primitive; // Type of primitive that was picked, usually \"triangles\"\n * var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Entity's Geometry's indices array\n * var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\n * var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\n * var viewPos = pickResult.viewPos; // Float64Array containing the picked View-space position on the triangle\n * var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the interpolated World-space normal vector at the picked position on the triangle\n * var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\n * var origin = pickResult.origin; // Float64Array containing the World-space ray origin\n * var direction = pickResult.direction; // Float64Array containing the World-space ray direction\n *\n * } else if (pickResult.worldPos && pickResult.worldNormal) {\n *\n * // Picked a point and normal on the entity surface\n *\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the Entity surface\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the picked World-space normal vector on the Entity Surface\n * }\n * }\n * ````\n *\n * @param {*} params Picking parameters.\n * @param {Boolean} [params.pickSurface=false] Whether to find the picked position on the surface of the Entity.\n * @param {Boolean} [params.pickSurfacePrecision=false] When picking an Entity surface position, indicates whether or not we want full-precision {@link PickResult#worldPos}. Only works when {@link Scene#pickSurfacePrecisionEnabled} is ````true````. If pick succeeds, the returned {@link PickResult} will have {@link PickResult#precision} set ````true````, to indicate that it contains full-precision surface pick results.\n * @param {Boolean} [params.pickSurfaceNormal=false] Whether to find the picked normal on the surface of the Entity. Only works if ````pickSurface```` is given.\n * @param {Number[]} [params.canvasPos] Canvas-space coordinates. When ray-picking, this will override the **origin** and ** direction** parameters and will cause the ray to be fired through the canvas at this position, directly along the negative View-space Z-axis.\n * @param {Number[]} [params.origin] World-space ray origin when ray-picking. Ignored when canvasPos given.\n * @param {Number[]} [params.direction] World-space ray direction when ray-picking. Also indicates the length of the ray. Ignored when canvasPos given.\n * @param {Number[]} [params.matrix] 4x4 transformation matrix to define the World-space ray origin and direction, as an alternative to ````origin```` and ````direction````.\n * @param {String[]} [params.includeEntities] IDs of {@link Entity}s to restrict picking to. When given, ignores {@link Entity}s whose IDs are not in this list.\n * @param {String[]} [params.excludeEntities] IDs of {@link Entity}s to ignore. When given, will pick *through* these {@link Entity}s, as if they were not there.\n * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels\n * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.\n * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.\n * @param {PickResult} [pickResult] Holds the results of the pick attempt. Will use the Scene's singleton PickResult if you don't supply your own.\n * @returns {PickResult} Holds results of the pick attempt, returned when an {@link Entity} is picked, else null. See method comments for description.\n */\n\tpick(params, pickResult) {\n\t\tif (this.canvas.boundary[2] === 0 || this.canvas.boundary[3] === 0) {\n\t\t\tthis.error(\"Picking not allowed while canvas has zero width or height\");\n\t\t\treturn null;\n\t\t}\n\n\t\tparams = params || {};\n\n\t\tparams.pickSurface = params.pickSurface || params.rayPick; // Backwards compatibility\n\n\t\tif (!params.canvasPos && !params.matrix && (!params.origin || !params.direction)) {\n\t\t\tthis.warn(\"picking without canvasPos, matrix, or ray origin and direction\");\n\t\t}\n\n\t\tconst includeEntities = params.includeEntities || params.include; // Backwards compat\n\t\tif (includeEntities) {\n\t\t\tparams.includeEntityIds = getEntityIDMap(this, includeEntities);\n\t\t}\n\n\t\tconst excludeEntities = params.excludeEntities || params.exclude; // Backwards compat\n\t\tif (excludeEntities) {\n\t\t\tparams.excludeEntityIds = getEntityIDMap(this, excludeEntities);\n\t\t}\n\n\t\tif (this._needRecompile) {\n\t\t\tthis._recompile();\n\t\t\tthis._renderer.imageDirty();\n\t\t\tthis._needRecompile = false;\n\t\t}\n\n\t\tif (params.snapToEdge || params.snapToVertex) {\n\t\t\tpickResult = this._renderer.snapPick(\n\t\t\t\tparams.canvasPos,\n\t\t\t\tparams.snapRadius || 30,\n\t\t\t\tparams.snapToVertex,\n\t\t\t\tparams.snapToEdge,\n\t\t\t\tpickResult\n\t\t\t);\n\t\t} else {\n\t\t\tpickResult = this._renderer.pick(params, pickResult);\n\t\t}\n\n\t\tif (pickResult) {\n\t\t\tif (pickResult.entity && pickResult.entity.fire) {\n\t\t\t\tpickResult.entity.fire(\"picked\", pickResult); // TODO: SceneModelEntity doesn't fire events\n\t\t\t}\n\t\t}\n\n\t\treturn pickResult;\n\t}\n\n\t/**\n\t * @param {Object} params Picking parameters.\n\t * @param {Number[]} [params.canvasPos] Canvas-space coordinates. When ray-picking, this will override the **origin** and ** direction** parameters and will cause the ray to be fired through the canvas at this position, directly along the negative View-space Z-axis.\n\t * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels\n\t * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.\n\t * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.\n\t * @deprecated\n\t */\n\tsnapPick(params) {\n\t\tif (undefined === this._warnSnapPickDeprecated) {\n\t\t\tthis._warnSnapPickDeprecated = true;\n\t\t\tthis.warn(\"Scene.snapPick() is deprecated since v2.4.2 - use Scene.pick() instead\");\n\t\t}\n\t\treturn this._renderer.snapPick(params.canvasPos, params.snapRadius || 30, params.snapToVertex, params.snapToEdge);\n\t}\n\n\t/**\n\t * Destroys all non-default {@link Component}s in this Scene.\n\t */\n\tclear() {\n\t\tvar component;\n\t\tfor (const id in this.components) {\n\t\t\tif (this.components.hasOwnProperty(id)) {\n\t\t\t\tcomponent = this.components[id];\n\t\t\t\tif (!component._dontClear) {\n\t\t\t\t\t// Don't destroy components like Camera, Input, Viewport etc.\n\t\t\t\t\tcomponent.destroy();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all {@link Light}s in this Scene..\n\t */\n\tclearLights() {\n\t\tconst ids = Object.keys(this.lights);\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tthis.lights[ids[i]].destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all {@link SectionPlane}s in this Scene.\n\t */\n\tclearSectionPlanes() {\n\t\tconst ids = Object.keys(this.sectionPlanes);\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tthis.sectionPlanes[ids[i]].destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all {@link Line}s in this Scene.\n\t */\n\tclearBitmaps() {\n\t\tconst ids = Object.keys(this.bitmaps);\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tthis.bitmaps[ids[i]].destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all {@link Line}s in this Scene.\n\t */\n\tclearLines() {\n\t\tconst ids = Object.keys(this.lineSets);\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tthis.lineSets[ids[i]].destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Gets the collective axis-aligned boundary (AABB) of a batch of {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * Each {@link Entity} on which {@link Entity#isObject} is registered by {@link Entity#id} in {@link Scene#visibleObjects}.\n\t *\n\t * Each {@link Entity} is only included in the AABB when {@link Entity#collidable} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @returns {[Number, Number, Number, Number, Number, Number]} An axis-aligned World-space bounding box, given as elements ````[xmin, ymin, zmin, xmax, ymax, zmax]````.\n\t */\n\tgetAABB(ids) {\n\t\tif (ids === undefined) {\n\t\t\treturn this.aabb;\n\t\t}\n\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isString(ids)) {\n\t\t\tconst entity = this.objects[ids];\n\t\t\tif (entity && entity.aabb) {\n\t\t\t\t// A Component subclass with an AABB\n\t\t\t\treturn entity.aabb;\n\t\t\t}\n\t\t\tids = [ids]; // Must be an entity type\n\t\t}\n\t\tif (ids.length === 0) {\n\t\t\treturn this.aabb;\n\t\t}\n\t\tlet xmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\tlet ymin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\tlet zmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\tlet xmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\tlet ymax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\tlet zmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\tlet valid;\n\t\tthis.withObjects(ids, (entity) => {\n\t\t\tif (entity.collidable) {\n\t\t\t\tconst aabb = entity.aabb;\n\t\t\t\tif (aabb[0] < xmin) {\n\t\t\t\t\txmin = aabb[0];\n\t\t\t\t}\n\t\t\t\tif (aabb[1] < ymin) {\n\t\t\t\t\tymin = aabb[1];\n\t\t\t\t}\n\t\t\t\tif (aabb[2] < zmin) {\n\t\t\t\t\tzmin = aabb[2];\n\t\t\t\t}\n\t\t\t\tif (aabb[3] > xmax) {\n\t\t\t\t\txmax = aabb[3];\n\t\t\t\t}\n\t\t\t\tif (aabb[4] > ymax) {\n\t\t\t\t\tymax = aabb[4];\n\t\t\t\t}\n\t\t\t\tif (aabb[5] > zmax) {\n\t\t\t\t\tzmax = aabb[5];\n\t\t\t\t}\n\t\t\t\tvalid = true;\n\t\t\t}\n\t\t});\n\t\tif (valid) {\n\t\t\tconst aabb2 = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.AABB3();\n\t\t\taabb2[0] = xmin;\n\t\t\taabb2[1] = ymin;\n\t\t\taabb2[2] = zmin;\n\t\t\taabb2[3] = xmax;\n\t\t\taabb2[4] = ymax;\n\t\t\taabb2[5] = zmax;\n\t\t\treturn aabb2;\n\t\t} else {\n\t\t\treturn this.aabb; // Scene AABB\n\t\t}\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#visible} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#visible} are ````true```` is\n\t * registered by {@link Entity#id} in {@link Scene#visibleObjects}.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} visible Whether or not to set visible.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsVisible(ids, visible) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.visible !== visible;\n\t\t\tentity.visible = visible;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#collidable} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} collidable Whether or not to set collidable.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsCollidable(ids, collidable) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.collidable !== collidable;\n\t\t\tentity.collidable = collidable;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#culled} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} culled Whether or not to cull.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsCulled(ids, culled) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.culled !== culled;\n\t\t\tentity.culled = culled;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#selected} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#selected} are ````true```` is\n\t * registered by {@link Entity#id} in {@link Scene#selectedObjects}.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} selected Whether or not to select.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsSelected(ids, selected) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.selected !== selected;\n\t\t\tentity.selected = selected;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#highlighted} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#highlighted} are ````true```` is\n\t * registered by {@link Entity#id} in {@link Scene#highlightedObjects}.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} highlighted Whether or not to highlight.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsHighlighted(ids, highlighted) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.highlighted !== highlighted;\n\t\t\tentity.highlighted = highlighted;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#xrayed} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} xrayed Whether or not to xray.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsXRayed(ids, xrayed) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.xrayed !== xrayed;\n\t\t\tentity.xrayed = xrayed;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#edges} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} edges Whether or not to show edges.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsEdges(ids, edges) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.edges !== edges;\n\t\t\tentity.edges = edges;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#colorize} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Number[]} [colorize=(1,1,1)] RGB colorize factors, multiplied by the rendered pixel colors.\n\t * @returns {Boolean} True if any {@link Entity}s changed opacity, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsColorized(ids, colorize) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tentity.colorize = colorize;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#opacity} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Number} [opacity=1.0] Opacity factor, multiplied by the rendered pixel alphas.\n\t * @returns {Boolean} True if any {@link Entity}s changed opacity, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsOpacity(ids, opacity) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.opacity !== opacity;\n\t\t\tentity.opacity = opacity;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#pickable} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} pickable Whether or not to set pickable.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsPickable(ids, pickable) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.pickable !== pickable;\n\t\t\tentity.pickable = pickable;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#offset} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Number[]} [offset] 3D offset vector.\n\t */\n\tsetObjectsOffset(ids, offset) {\n\t\tthis.withObjects(ids, (entity) => {\n\t\t\tentity.offset = offset;\n\t\t});\n\t}\n\n\t/**\n\t * Iterates with a callback over {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Function} callback Callback to execute on eacn {@link Entity}.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\twithObjects(ids, callback) {\n\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isString(ids)) {\n\t\t\tids = [ids];\n\t\t}\n\t\tlet changed = false;\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tconst id = ids[i];\n\t\t\tlet entity = this.objects[id];\n\t\t\tif (entity) {\n\t\t\t\tchanged = callback(entity) || changed;\n\t\t\t} else {\n\t\t\t\tconst modelIds = this.modelIds;\n\t\t\t\tfor (let i = 0, len = modelIds.length; i < len; i++) {\n\t\t\t\t\tconst modelId = modelIds[i];\n\t\t\t\t\tconst globalObjectId = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.globalizeObjectId(modelId, id);\n\t\t\t\t\tentity = this.objects[globalObjectId];\n\t\t\t\t\tif (entity) {\n\t\t\t\t\t\tchanged = callback(entity) || changed;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn changed;\n\t}\n\n\t/**\n\t * This method will \"tickify\" the provided `cb` function.\n\t *\n\t * This means, the function will be wrapped so:\n\t *\n\t * - it runs time-aligned to scene ticks\n\t * - it runs maximum once per scene-tick\n\t *\n\t * @param {Function} cb The function to tickify\n\t * @returns {Function}\n\t */\n\ttickify(cb) {\n\t\tconst cbString = cb.toString();\n\n\t\t/**\n\t\t * Check if the function is already tickified, and if so return the cached one.\n\t\t */\n\t\tif (cbString in this._tickifiedFunctions) {\n\t\t\treturn this._tickifiedFunctions[cbString].wrapperFunc;\n\t\t}\n\n\t\tlet alreadyRun = 0;\n\t\tlet needToRun = 0;\n\n\t\tlet lastArgs;\n\n\t\t/**\n\t\t * The provided `cb` function is replaced with a \"set-dirty\" function\n\t\t *\n\t\t * @type {Function}\n\t\t */\n\t\tconst wrapperFunc = function (...args) {\n\t\t\tlastArgs = args;\n\t\t\tneedToRun++;\n\t\t};\n\n\t\t/**\n\t\t * An each scene tick, if the \"dirty-flag\" is set, run the `cb` function.\n\t\t *\n\t\t * This will make it run time-aligned to the scene tick.\n\t\t */\n\t\tconst tickSubId = this.on(\"tick\", () => {\n\t\t\tconst tmp = needToRun;\n\t\t\tif (tmp > alreadyRun) {\n\t\t\t\talreadyRun = tmp;\n\t\t\t\tcb(...lastArgs);\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * And, store the list of subscribers.\n\t\t */\n\t\tthis._tickifiedFunctions[cbString] = { tickSubId, wrapperFunc };\n\n\t\treturn wrapperFunc;\n\t}\n\n\t/**\n\t * Destroys this Scene.\n\t */\n\tdestroy(callback) {\n\t\tsuper.destroy();\n\t\tfor (const id in this.components) {\n\t\t\tif (this.components.hasOwnProperty(id)) {\n\t\t\t\tthis.components[id].destroy();\n\t\t\t}\n\t\t}\n\t\t// this.canvas.destroy(); // canvas是scene的其中一个component,所有以不必再destroy\n\n\t\t// Memory leak prevention\n\t\tthis.components = null;\n\t\tthis.models = null;\n\t\tthis.objects = null;\n\t\tthis.visibleObjects = null;\n\t\tthis.xrayedObjects = null;\n\t\tthis.highlightedObjects = null;\n\t\tthis.selectedObjects = null;\n\t\tthis.colorizedObjects = null;\n\t\tthis.opacityObjects = null;\n\t\tthis.sectionPlanes = null;\n\t\tthis.lights = null;\n\t\tthis.lightMaps = null;\n\t\tthis.reflectionMaps = null;\n\t\tthis._objectIds = null;\n\t\tthis._visibleObjectIds = null;\n\t\tthis._xrayedObjectIds = null;\n\t\tthis._highlightedObjectIds = null;\n\t\tthis._selectedObjectIds = null;\n\t\tthis._colorizedObjectIds = null;\n\t\tthis.types = null;\n\t\tthis._renderer = null;\n\t\tthis.input = null;\n\t\tthis._viewport = null;\n\t\tthis._camera = null;\n\t\tthis.canvas = null;\n\t\tif (typeof callback === \"function\") {\n\t\t\tcallback();\n\t\t}\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/scene/Scene.js?");
4827
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Scene: () => (/* binding */ Scene)\n/* harmony export */ });\n/* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../core.js */ \"./src/viewer/scene/core.js\");\n/* harmony import */ var _lod_LOD_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../lod/LOD.js */ \"./src/viewer/scene/lod/LOD.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils.js */ \"./src/viewer/scene/utils.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _canvas_Canvas_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../canvas/Canvas.js */ \"./src/viewer/scene/canvas/Canvas.js\");\n/* harmony import */ var _webgl_Renderer_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../webgl/Renderer.js */ \"./src/viewer/scene/webgl/Renderer.js\");\n/* harmony import */ var _input_Input_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../input/Input.js */ \"./src/viewer/scene/input/Input.js\");\n/* harmony import */ var _viewport_Viewport_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../viewport/Viewport.js */ \"./src/viewer/scene/viewport/Viewport.js\");\n/* harmony import */ var _camera_Camera_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../camera/Camera.js */ \"./src/viewer/scene/camera/Camera.js\");\n/* harmony import */ var _lights_DirLight_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../lights/DirLight.js */ \"./src/viewer/scene/lights/DirLight.js\");\n/* harmony import */ var _lights_AmbientLight_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../lights/AmbientLight.js */ \"./src/viewer/scene/lights/AmbientLight.js\");\n/* harmony import */ var _geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _geometry_builders_buildBoxGeometry_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../geometry/builders/buildBoxGeometry.js */ \"./src/viewer/scene/geometry/builders/buildBoxGeometry.js\");\n/* harmony import */ var _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../materials/EmphasisMaterial.js */ \"./src/viewer/scene/materials/EmphasisMaterial.js\");\n/* harmony import */ var _materials_EdgeMaterial_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../materials/EdgeMaterial.js */ \"./src/viewer/scene/materials/EdgeMaterial.js\");\n/* harmony import */ var _metriqs_Metriqs_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../metriqs/Metriqs.js */ \"./src/viewer/scene/metriqs/Metriqs.js\");\n/* harmony import */ var _postfx_SAO_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../postfx/SAO.js */ \"./src/viewer/scene/postfx/SAO.js\");\n/* harmony import */ var _materials_PointsMaterial_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../materials/PointsMaterial.js */ \"./src/viewer/scene/materials/PointsMaterial.js\");\n/* harmony import */ var _materials_LinesMaterial_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../materials/LinesMaterial.js */ \"./src/viewer/scene/materials/LinesMaterial.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// Enables runtime check for redundant calls to object state update methods, eg. Scene#_objectVisibilityUpdated\nconst ASSERT_OBJECT_STATE_UPDATE = false;\n\n// Cached vars to avoid garbage collection\n\nfunction getEntityIDMap(scene, entityIds) {\n\tconst map = {};\n\tlet entityId;\n\tlet entity;\n\tfor (let i = 0, len = entityIds.length; i < len; i++) {\n\t\tentityId = entityIds[i];\n\t\tentity = scene.components[entityId];\n\t\tif (!entity) {\n\t\t\tscene.warn(\"pick(): Component not found: \" + entityId);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!entity.isEntity) {\n\t\t\tscene.warn(\"pick(): Component is not an Entity: \" + entityId);\n\t\t\tcontinue;\n\t\t}\n\t\tmap[entityId] = true;\n\t}\n\treturn map;\n}\n\n/**\n * Fired whenever a debug message is logged on a component within this Scene.\n * @event log\n * @param {String} value The debug message\n */\n\n/**\n * Fired whenever an error is logged on a component within this Scene.\n * @event error\n * @param {String} value The error message\n */\n\n/**\n * Fired whenever a warning is logged on a component within this Scene.\n * @event warn\n * @param {String} value The warning message\n */\n\n/**\n * @desc Contains the components that comprise a 3D scene.\n *\n * * A {@link Viewer} has a single Scene, which it provides in {@link Viewer#scene}.\n * * Plugins like {@link AxisGizmoPlugin} also have their own private Scenes.\n * * Each Scene has a corresponding {@link MetaScene}, which the Viewer provides in {@link Viewer#metaScene}.\n *\n * ## Getting a Viewer's Scene\n *\n * ````javascript\n * var scene = viewer.scene;\n * ````\n *\n * ## Creating and accessing Scene components\n *\n * As a brief introduction to creating Scene components, we'll create a {@link Mesh} that has a\n * {@link buildTorusGeometry} and a {@link PhongMaterial}:\n *\n * ````javascript\n * var teapotMesh = new Mesh(scene, {\n * id: \"myMesh\", // <<---------- ID automatically generated if not provided\n * geometry: new TorusGeometry(scene),\n * material: new PhongMaterial(scene, {\n * id: \"myMaterial\",\n * diffuse: [0.2, 0.2, 1.0]\n * })\n * });\n *\n * teapotMesh.scene.camera.eye = [45, 45, 45];\n * ````\n *\n * Find components by ID in their Scene's {@link Scene#components} map:\n *\n * ````javascript\n * var teapotMesh = scene.components[\"myMesh\"];\n * teapotMesh.visible = false;\n *\n * var teapotMaterial = scene.components[\"myMaterial\"];\n * teapotMaterial.diffuse = [1,0,0]; // Change to red\n * ````\n *\n * A Scene also has a map of component instances for each {@link Component} subtype:\n *\n * ````javascript\n * var meshes = scene.types[\"Mesh\"];\n * var teapotMesh = meshes[\"myMesh\"];\n * teapotMesh.xrayed = true;\n *\n * var phongMaterials = scene.types[\"PhongMaterial\"];\n * var teapotMaterial = phongMaterials[\"myMaterial\"];\n * teapotMaterial.diffuse = [0,1,0]; // Change to green\n * ````\n *\n * See {@link Node}, {@link Node} and {@link Model} for how to create and access more sophisticated content.\n *\n * ## Controlling the camera\n *\n * Use the Scene's {@link Camera} to control the current viewpoint and projection:\n *\n * ````javascript\n * var camera = myScene.camera;\n *\n * camera.eye = [-10,0,0];\n * camera.look = [-10,0,0];\n * camera.up = [0,1,0];\n *\n * camera.projection = \"perspective\";\n * camera.perspective.fov = 45;\n * //...\n * ````\n *\n * ## Managing the canvas\n *\n * The Scene's {@link Canvas} component provides various conveniences relevant to the WebGL canvas, such\n * as firing resize events etc:\n *\n * ````javascript\n * var canvas = scene.canvas;\n *\n * canvas.on(\"boundary\", function(boundary) {\n * //...\n * });\n * ````\n *\n * ## Picking\n *\n * Use {@link Scene#pick} to pick and raycast entites.\n *\n * For example, to pick a point on the surface of the closest entity at the given canvas coordinates:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * pickSurface: true,\n * canvasPos: [23, 131]\n * });\n *\n * if (pickResult) { // Picked an entity\n *\n * var entity = pickResult.entity;\n *\n * var primitive = pickResult.primitive; // Type of primitive that was picked, usually \"triangles\"\n * var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Mesh's Geometry's indices array\n * var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\n * var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\n * var viewPos = pickResult. ; // Float64Array containing the picked View-space position on the triangle\n * var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\n * var normal = pickResult.normal; // Float64Array containing the interpolated normal vector at the picked position on the triangle\n * var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\n * }\n * ````\n *\n * ## Pick masking\n *\n * We can use {@link Scene#pick}'s ````includeEntities```` and ````excludeEntities```` options to mask which {@link Mesh}es we attempt to pick.\n *\n * This is useful for picking through things, to pick only the Entities of interest.\n *\n * To pick only Entities ````\"gearbox#77.0\"```` and ````\"gearbox#79.0\"````, picking through any other Entities that are\n * in the way, as if they weren't there:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * canvasPos: [23, 131],\n * includeEntities: [\"gearbox#77.0\", \"gearbox#79.0\"]\n * });\n *\n * if (pickResult) {\n * // Entity will always be either \"gearbox#77.0\" or \"gearbox#79.0\"\n * var entity = pickResult.entity;\n * }\n * ````\n *\n * To pick any pickable Entity, except for ````\"gearbox#77.0\"```` and ````\"gearbox#79.0\"````, picking through those\n * Entities if they happen to be in the way:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * canvasPos: [23, 131],\n * excludeEntities: [\"gearbox#77.0\", \"gearbox#79.0\"]\n * });\n *\n * if (pickResult) {\n * // Entity will never be \"gearbox#77.0\" or \"gearbox#79.0\"\n * var entity = pickResult.entity;\n * }\n * ````\n *\n * See {@link Scene#pick} for more info on picking.\n *\n * ## Querying and tracking boundaries\n *\n * Getting a Scene's World-space axis-aligned boundary (AABB):\n *\n * ````javascript\n * var aabb = scene.aabb; // [xmin, ymin, zmin, xmax, ymax, zmax]\n * ````\n *\n * Subscribing to updates to the AABB, which occur whenever {@link Entity}s are transformed, their\n * {@link ReadableGeometry}s have been updated, or the {@link Camera} has moved:\n *\n * ````javascript\n * scene.on(\"boundary\", function() {\n * var aabb = scene.aabb;\n * });\n * ````\n *\n * Getting the AABB of the {@link Entity}s with the given IDs:\n *\n * ````JavaScript\n * scene.getAABB(); // Gets collective boundary of all Entities in the scene\n * scene.getAABB(\"saw\"); // Gets boundary of an Object\n * scene.getAABB([\"saw\", \"gearbox\"]); // Gets collective boundary of two Objects\n * ````\n *\n * See {@link Scene#getAABB} and {@link Entity} for more info on querying and tracking boundaries.\n *\n * ## Managing the viewport\n *\n * The Scene's {@link Viewport} component manages the WebGL viewport:\n *\n * ````javascript\n * var viewport = scene.viewport\n * viewport.boundary = [0, 0, 500, 400];;\n * ````\n *\n * ## Controlling rendering\n *\n * You can configure a Scene to perform multiple \"passes\" (renders) per frame. This is useful when we want to render the\n * scene to multiple viewports, such as for stereo effects.\n *\n * In the example, below, we'll configure the Scene to render twice on each frame, each time to different viewport. We'll do this\n * with a callback that intercepts the Scene before each render and sets its {@link Viewport} to a\n * different portion of the canvas. By default, the Scene will clear the canvas only before the first render, allowing the\n * two views to be shown on the canvas at the same time.\n *\n * ````Javascript\n * var viewport = scene.viewport;\n *\n * // Configure Scene to render twice for each frame\n * scene.passes = 2; // Default is 1\n * scene.clearEachPass = false; // Default is false\n *\n * // Render to a separate viewport on each render\n *\n * var viewport = scene.viewport;\n * viewport.autoBoundary = false;\n *\n * scene.on(\"rendering\", function (e) {\n * switch (e.pass) {\n * case 0:\n * viewport.boundary = [0, 0, 200, 200]; // xmin, ymin, width, height\n * break;\n *\n * case 1:\n * viewport.boundary = [200, 0, 200, 200];\n * break;\n * }\n * });\n *\n * // We can also intercept the Scene after each render,\n * // (though we're not using this for anything here)\n * scene.on(\"rendered\", function (e) {\n * switch (e.pass) {\n * case 0:\n * break;\n *\n * case 1:\n * break;\n * }\n * });\n * ````\n *\n * ## Gamma correction\n *\n * Within its shaders, xeokit performs shading calculations in linear space.\n *\n * By default, the Scene expects color textures (eg. {@link PhongMaterial#diffuseMap},\n * {@link MetallicMaterial#baseColorMap} and {@link SpecularMaterial#diffuseMap}) to\n * be in pre-multipled gamma space, so will convert those to linear space before they are used in shaders. Other textures are\n * always expected to be in linear space.\n *\n * By default, the Scene will also gamma-correct its rendered output.\n *\n * You can configure the Scene to expect all those color textures to be linear space, so that it does not gamma-correct them:\n *\n * ````javascript\n * scene.gammaInput = false;\n * ````\n *\n * You would still need to gamma-correct the output, though, if it's going straight to the canvas, so normally we would\n * leave that enabled:\n *\n * ````javascript\n * scene.gammaOutput = true;\n * ````\n *\n * See {@link Texture} for more information on texture encoding and gamma.\n *\n * @class Scene\n */\nclass Scene extends _Component_js__WEBPACK_IMPORTED_MODULE_4__.Component {\n\t/**\n @private\n */\n\tget type() {\n\t\treturn \"Scene\";\n\t}\n\n\t/**\n\t * @private\n\t * @constructor\n\t * @param {Viewer} viewer The Viewer this Scene belongs to.\n\t * @param {Object} cfg Scene configuration.\n\t * @param {String} [cfg.canvasId] ID of an existing HTML canvas for the {@link Scene#canvas} - either this or canvasElement is mandatory. When both values are given, the element reference is always preferred to the ID.\n\t * @param {HTMLCanvasElement} [cfg.canvasElement] Reference of an existing HTML canvas for the {@link Scene#canvas} - either this or canvasId is mandatory. When both values are given, the element reference is always preferred to the ID.\n\t * @param {HTMLElement} [cfg.keyboardEventsElement] Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document.\n\t * @param {number} [cfg.numCachedSectionPlanes=0] Enhances the efficiency of SectionPlane creation by proactively allocating Viewer resources for a specified quantity\n\t * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n\t * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n\t * responsiveness. It is important to consider that each SectionPlane imposes rendering performance, so it is recommended to set this value to a quantity that aligns with\n\t * your expected usage.\n\t * @throws {String} Throws an exception when both canvasId or canvasElement are missing or they aren't pointing to a valid HTMLCanvasElement.\n\t */\n\tconstructor(viewer, cfg = {}) {\n\t\tsuper(null, cfg);\n\n\t\tconst canvas = cfg.canvasElement || document.getElementById(cfg.canvasId);\n\n\t\tif (!(canvas instanceof HTMLCanvasElement)) {\n\t\t\tthrow \"Mandatory config expected: valid canvasId or canvasElement\";\n\t\t}\n\n\t\t/**\n\t\t * @type {{[key: string]: {wrapperFunc: Function, tickSubId: string}}}\n\t\t */\n\t\tthis._tickifiedFunctions = {};\n\n\t\tthis._transparent = !!cfg.transparent;\n\t\tconst alphaDepthMask = !!cfg.alphaDepthMask;\n\t\tthis._edgesEnabled = !!cfg.edgesEnabled;\n\n\t\tthis._aabbDirty = true;\n\t\tthis._aabbUpdate = false;\n\n\t\t/**\n\t\t * The {@link Viewer} this Scene belongs to.\n\t\t * @type {Viewer}\n\t\t */\n\t\tthis.viewer = viewer;\n\n\t\t/** Decremented each frame, triggers occlusion test for occludable {@link Marker}s when zero.\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis.occlusionTestCountdown = 0;\n\n\t\t/**\n The number of models currently loading.\n\n @property loading\n @final\n @type {Number}\n */\n\t\tthis.loading = 0;\n\n\t\t/**\n The epoch time (in milliseconds since 1970) when this Scene was instantiated.\n\n @property timeCreated\n @final\n @type {Number}\n */\n\t\tthis.startTime = new Date().getTime();\n\n\t\t/**\n\t\t * Map of {@link SceneModel}s that represent models.\n\t\t *\n\t\t * Each {@link SceneModel} is mapped here by {@link SceneModel#id} when {@link SceneModel#isModel} is ````true````.\n\t\t *\n\t\t * @property models\n\t\t * @final\n\t\t * @type {{String:SceneModel}}\n\t\t */\n\t\tthis.models = {};\n\n\t\t/**\n\t\t * Map of {@link Entity}s that represents objects.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id} when {@link Entity#isObject} is ````true````.\n\t\t *\n\t\t * @property objects\n\t\t * @final\n\t\t * @type {{String:Entity}}\n\t\t */\n\t\tthis.objects = {};\n\t\tthis._numObjects = 0;\n\n\t\t/**\n\t\t * Map of currently visible {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````, and is visible when {@link Entity#visible} is true.\n\t\t *\n\t\t * @property visibleObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.visibleObjects = {};\n\t\tthis._numVisibleObjects = 0;\n\n\t\t/**\n\t\t * Map of currently xrayed {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````, and is xrayed when {@link Entity#xrayed} is true.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property xrayedObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.xrayedObjects = {};\n\t\tthis._numXRayedObjects = 0;\n\n\t\t/**\n\t\t * Map of currently highlighted {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true```` is true, and is highlighted when {@link Entity#highlighted} is true.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property highlightedObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.highlightedObjects = {};\n\t\tthis._numHighlightedObjects = 0;\n\n\t\t/**\n\t\t * Map of currently selected {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is true, and is selected while {@link Entity#selected} is true.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property selectedObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.selectedObjects = {};\n\t\tthis._numSelectedObjects = 0;\n\n\t\t/**\n\t\t * Map of currently colorized {@link Entity}s that represent objects.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property colorizedObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.colorizedObjects = {};\n\t\tthis._numColorizedObjects = 0;\n\n\t\t/**\n\t\t * Map of {@link Entity}s that represent objects whose opacity was updated.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property opacityObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.opacityObjects = {};\n\t\tthis._numOpacityObjects = 0;\n\n\t\t/**\n\t\t * Map of {@link Entity}s that represent objects whose {@link Entity#offset}s were updated.\n\t\t *\n\t\t * An Entity represents an object if {@link Entity#isObject} is ````true````.\n\t\t *\n\t\t * Each {@link Entity} is mapped here by {@link Entity#id}.\n\t\t *\n\t\t * @property offsetObjects\n\t\t * @final\n\t\t * @type {{String:Object}}\n\t\t */\n\t\tthis.offsetObjects = {};\n\t\tthis._numOffsetObjects = 0;\n\n\t\t// Cached ID arrays, lazy-rebuilt as needed when stale after map updates\n\n\t\t/**\n Lazy-regenerated ID lists.\n */\n\t\tthis._modelIds = null;\n\t\tthis._objectIds = null;\n\t\tthis._visibleObjectIds = null;\n\t\tthis._xrayedObjectIds = null;\n\t\tthis._highlightedObjectIds = null;\n\t\tthis._selectedObjectIds = null;\n\t\tthis._colorizedObjectIds = null;\n\t\tthis._opacityObjectIds = null;\n\t\tthis._offsetObjectIds = null;\n\n\t\tthis._collidables = {}; // Components that contribute to the Scene AABB\n\t\tthis._compilables = {}; // Components that require shader compilation\n\n\t\tthis._needRecompile = false;\n\n\t\t/**\n\t\t * For each {@link Component} type, a map of IDs to {@link Component} instances of that type.\n\t\t *\n\t\t * @type {{String:{String:Component}}}\n\t\t */\n\t\tthis.types = {};\n\n\t\t/**\n\t\t * The {@link Component}s within this Scene, each mapped to its {@link Component#id}.\n\t\t *\n\t\t * *@type {{String:Component}}\n\t\t */\n\t\tthis.components = {};\n\n\t\t/**\n\t\t * The {@link SectionPlane}s in this Scene, each mapped to its {@link SectionPlane#id}.\n\t\t *\n\t\t * @type {{String:SectionPlane}}\n\t\t */\n\t\tthis.sectionPlanes = {};\n\n\t\t/**\n\t\t * The {@link Light}s in this Scene, each mapped to its {@link Light#id}.\n\t\t *\n\t\t * @type {{String:Light}}\n\t\t */\n\t\tthis.lights = {};\n\n\t\t/**\n\t\t * The {@link LightMap}s in this Scene, each mapped to its {@link LightMap#id}.\n\t\t *\n\t\t * @type {{String:LightMap}}\n\t\t */\n\t\tthis.lightMaps = {};\n\n\t\t/**\n\t\t * The {@link ReflectionMap}s in this Scene, each mapped to its {@link ReflectionMap#id}.\n\t\t *\n\t\t * @type {{String:ReflectionMap}}\n\t\t */\n\t\tthis.reflectionMaps = {};\n\n\t\t/**\n\t\t * The {@link Bitmap}s in this Scene, each mapped to its {@link Bitmap#id}.\n\t\t *\n\t\t * @type {{String:Bitmap}}\n\t\t */\n\t\tthis.bitmaps = {};\n\n\t\t/**\n\t\t * The {@link LineSet}s in this Scene, each mapped to its {@link LineSet#id}.\n\t\t *\n\t\t * @type {{String:LineSet}}\n\t\t */\n\t\tthis.lineSets = {};\n\n\t\t/**\n\t\t * The real world offset for this Scene\n\t\t *\n\t\t * @type {Number[]}\n\t\t */\n\t\tthis.realWorldOffset = cfg.realWorldOffset || new Float64Array([0, 0, 0]);\n\n\t\t/**\n\t\t * Manages the HTML5 canvas for this Scene.\n\t\t *\n\t\t * @type {Canvas}\n\t\t */\n\t\tthis.canvas = new _canvas_Canvas_js__WEBPACK_IMPORTED_MODULE_5__.Canvas(this, {\n\t\t\tdontClear: true, // Never destroy this component with Scene#clear();\n\t\t\tcanvas: canvas,\n\t\t\tspinnerElementId: cfg.spinnerElementId,\n\t\t\ttransparent: this._transparent,\n\t\t\twebgl2: cfg.webgl2 !== false,\n\t\t\tcontextAttr: cfg.contextAttr || {},\n\t\t\tbackgroundColor: cfg.backgroundColor,\n\t\t\tbackgroundColorFromAmbientLight: cfg.backgroundColorFromAmbientLight,\n\t\t\tpremultipliedAlpha: cfg.premultipliedAlpha,\n\t\t\tresolutionScale: cfg.resolutionScale\n\t\t});\n\n\t\tthis.canvas.on(\"boundary\", () => {\n\t\t\tthis.glRedraw();\n\t\t});\n\n\t\tthis.canvas.on(\"webglContextFailed\", () => {\n\t\t\talert(\"tctwins failed to find WebGL!\");\n\t\t});\n\n\t\tthis._renderer = new _webgl_Renderer_js__WEBPACK_IMPORTED_MODULE_6__.Renderer(this, {\n\t\t\ttransparent: this._transparent,\n\t\t\talphaDepthMask: alphaDepthMask,\n\t\t\tedgesEnabled: this._edgesEnabled\n\t\t});\n\n\t\tthis._sectionPlanesState = new (function () {\n\t\t\tthis.sectionPlanes = [];\n\n\t\t\tthis.clippingCaps = false;\n\n\t\t\tthis._numCachedSectionPlanes = 0;\n\n\t\t\tlet hash = null;\n\n\t\t\tthis.getHash = function () {\n\t\t\t\tif (hash) {\n\t\t\t\t\treturn hash;\n\t\t\t\t}\n\t\t\t\tconst numAllocatedSectionPlanes = this.getNumAllocatedSectionPlanes();\n\t\t\t\tconst sectionPlanes = this.sectionPlanes;\n\t\t\t\tif (numAllocatedSectionPlanes === 0) {\n\t\t\t\t\treturn (this.hash = \";\");\n\t\t\t\t}\n\t\t\t\tlet sectionPlane;\n\n\t\t\t\tconst hashParts = [];\n\t\t\t\tfor (let i = 0, len = numAllocatedSectionPlanes; i < len; i++) {\n\t\t\t\t\tsectionPlane = sectionPlanes[i];\n\t\t\t\t\thashParts.push(\"cp\");\n\t\t\t\t}\n\t\t\t\thashParts.push(\";\");\n\t\t\t\thash = hashParts.join(\"\");\n\t\t\t\treturn hash;\n\t\t\t};\n\n\t\t\tthis.addSectionPlane = function (sectionPlane) {\n\t\t\t\tthis.sectionPlanes.push(sectionPlane);\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.removeSectionPlane = function (sectionPlane) {\n\t\t\t\tfor (let i = 0, len = this.sectionPlanes.length; i < len; i++) {\n\t\t\t\t\tif (this.sectionPlanes[i].id === sectionPlane.id) {\n\t\t\t\t\t\tthis.sectionPlanes.splice(i, 1);\n\t\t\t\t\t\thash = null;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.setNumCachedSectionPlanes = function (numCachedSectionPlanes) {\n\t\t\t\tthis._numCachedSectionPlanes = numCachedSectionPlanes;\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.getNumCachedSectionPlanes = function () {\n\t\t\t\treturn this._numCachedSectionPlanes;\n\t\t\t};\n\n\t\t\tthis.getNumAllocatedSectionPlanes = function () {\n\t\t\t\tconst num = this.sectionPlanes.length;\n\t\t\t\treturn num > this._numCachedSectionPlanes ? num : this._numCachedSectionPlanes;\n\t\t\t};\n\t\t})();\n\n\t\tthis._sectionPlanesState.setNumCachedSectionPlanes(cfg.numCachedSectionPlanes || 0);\n\n\t\tthis._lightsState = new (function () {\n\t\t\tconst DEFAULT_AMBIENT = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec4([0, 0, 0, 0]);\n\t\t\tconst ambientColorIntensity = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec4();\n\n\t\t\tthis.lights = [];\n\t\t\tthis.reflectionMaps = [];\n\t\t\tthis.lightMaps = [];\n\n\t\t\tlet hash = null;\n\t\t\tlet ambientLight = null;\n\n\t\t\tthis.getHash = function () {\n\t\t\t\tif (hash) {\n\t\t\t\t\treturn hash;\n\t\t\t\t}\n\t\t\t\tconst hashParts = [];\n\t\t\t\tconst lights = this.lights;\n\t\t\t\tlet light;\n\t\t\t\tfor (let i = 0, len = lights.length; i < len; i++) {\n\t\t\t\t\tlight = lights[i];\n\t\t\t\t\thashParts.push(\"/\");\n\t\t\t\t\thashParts.push(light.type);\n\t\t\t\t\thashParts.push(light.space === \"world\" ? \"w\" : \"v\");\n\t\t\t\t\tif (light.castsShadow) {\n\t\t\t\t\t\thashParts.push(\"sh\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (this.lightMaps.length > 0) {\n\t\t\t\t\thashParts.push(\"/lm\");\n\t\t\t\t}\n\t\t\t\tif (this.reflectionMaps.length > 0) {\n\t\t\t\t\thashParts.push(\"/rm\");\n\t\t\t\t}\n\t\t\t\thashParts.push(\";\");\n\t\t\t\thash = hashParts.join(\"\");\n\t\t\t\treturn hash;\n\t\t\t};\n\n\t\t\tthis.addLight = function (state) {\n\t\t\t\tthis.lights.push(state);\n\t\t\t\tambientLight = null;\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.removeLight = function (state) {\n\t\t\t\tfor (let i = 0, len = this.lights.length; i < len; i++) {\n\t\t\t\t\tconst light = this.lights[i];\n\t\t\t\t\tif (light.id === state.id) {\n\t\t\t\t\t\tthis.lights.splice(i, 1);\n\t\t\t\t\t\tif (ambientLight && ambientLight.id === state.id) {\n\t\t\t\t\t\t\tambientLight = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\thash = null;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addReflectionMap = function (state) {\n\t\t\t\tthis.reflectionMaps.push(state);\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.removeReflectionMap = function (state) {\n\t\t\t\tfor (let i = 0, len = this.reflectionMaps.length; i < len; i++) {\n\t\t\t\t\tif (this.reflectionMaps[i].id === state.id) {\n\t\t\t\t\t\tthis.reflectionMaps.splice(i, 1);\n\t\t\t\t\t\thash = null;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addLightMap = function (state) {\n\t\t\t\tthis.lightMaps.push(state);\n\t\t\t\thash = null;\n\t\t\t};\n\n\t\t\tthis.removeLightMap = function (state) {\n\t\t\t\tfor (let i = 0, len = this.lightMaps.length; i < len; i++) {\n\t\t\t\t\tif (this.lightMaps[i].id === state.id) {\n\t\t\t\t\t\tthis.lightMaps.splice(i, 1);\n\t\t\t\t\t\thash = null;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.getAmbientColorAndIntensity = function () {\n\t\t\t\tif (!ambientLight) {\n\t\t\t\t\tfor (let i = 0, len = this.lights.length; i < len; i++) {\n\t\t\t\t\t\tconst light = this.lights[i];\n\t\t\t\t\t\tif (light.type === \"ambient\") {\n\t\t\t\t\t\t\tambientLight = light;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (ambientLight) {\n\t\t\t\t\tconst color = ambientLight.color;\n\t\t\t\t\tconst intensity = ambientLight.intensity;\n\t\t\t\t\tambientColorIntensity[0] = color[0];\n\t\t\t\t\tambientColorIntensity[1] = color[1];\n\t\t\t\t\tambientColorIntensity[2] = color[2];\n\t\t\t\t\tambientColorIntensity[3] = intensity;\n\t\t\t\t\treturn ambientColorIntensity;\n\t\t\t\t} else {\n\t\t\t\t\treturn DEFAULT_AMBIENT;\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\n\t\t/**\n\t\t * Publishes input events that occur on this Scene's canvas.\n\t\t * @property input\n\t\t * @type {Input}\n\t\t * @final\n\t\t */\n\t\tthis.input = new _input_Input_js__WEBPACK_IMPORTED_MODULE_7__.Input(this, {\n\t\t\tdontClear: true, // Never destroy this component with Scene#clear();\n\t\t\telement: this.canvas.canvas,\n\t\t\tkeyboardEventsElement: cfg.keyboardEventsElement\n\t\t});\n\n\t\t/**\n\t\t * Configures this Scene's units of measurement and coordinate mapping between Real-space and World-space 3D coordinate systems.\n\t\t *\n\t\t * @property metrics\n\t\t * @type {Metrics}\n\t\t * @final\n\t\t */\n\t\tthis.metrics = new _metriqs_Metriqs_js__WEBPACK_IMPORTED_MODULE_17__.Metrics(this, {\n\t\t\tunits: cfg.units,\n\t\t\tscale: cfg.scale,\n\t\t\torigin: cfg.origin\n\t\t});\n\n\t\t/** Configures Scalable Ambient Obscurance (SAO) for this Scene.\n\t\t * @type {SAO}\n\t\t * @final\n\t\t */\n\t\tthis.sao = new _postfx_SAO_js__WEBPACK_IMPORTED_MODULE_18__.SAO(this, {\n\t\t\tenabled: cfg.saoEnabled\n\t\t});\n\n\t\tthis.ticksPerRender = cfg.ticksPerRender;\n\t\tthis.ticksPerOcclusionTest = cfg.ticksPerOcclusionTest;\n\t\tthis.passes = cfg.passes;\n\t\tthis.clearEachPass = cfg.clearEachPass;\n\t\tthis.gammaInput = cfg.gammaInput;\n\t\tthis.gammaOutput = cfg.gammaOutput;\n\t\tthis.gammaFactor = cfg.gammaFactor;\n\n\t\tthis._entityOffsetsEnabled = !!cfg.entityOffsetsEnabled;\n\t\tthis._logarithmicDepthBufferEnabled = !!cfg.logarithmicDepthBufferEnabled;\n\n\t\tthis._dtxEnabled = cfg.dtxEnabled !== false;\n\t\tthis._pbrEnabled = !!cfg.pbrEnabled;\n\t\tthis._colorTextureEnabled = cfg.colorTextureEnabled !== false;\n\t\tthis._dtxEnabled = !!cfg.dtxEnabled;\n\t\tthis._lodEnabled = cfg.lodEnabled !== false;\n\n\t\t// Register Scene on xeokit\n\t\t// Do this BEFORE we add components below\n\t\t_core_js__WEBPACK_IMPORTED_MODULE_0__.core._addScene(this);\n\n\t\tthis._initDefaults();\n\n\t\t// Global components\n\n\t\tthis._viewport = new _viewport_Viewport_js__WEBPACK_IMPORTED_MODULE_8__.Viewport(this, {\n\t\t\tid: \"default.viewport\",\n\t\t\tautoBoundary: true,\n\t\t\tdontClear: true // Never destroy this component with Scene#clear();\n\t\t});\n\n\t\tthis._camera = new _camera_Camera_js__WEBPACK_IMPORTED_MODULE_9__.Camera(this, {\n\t\t\tid: \"default.camera\",\n\t\t\tdontClear: true // Never destroy this component with Scene#clear();\n\t\t});\n\n\t\t// Default lights\n\n\t\tnew _lights_AmbientLight_js__WEBPACK_IMPORTED_MODULE_11__.AmbientLight(this, {\n\t\t\tcolor: [1.0, 1.0, 1.0],\n\t\t\tintensity: 0.6\n\t\t});\n\n\t\tnew _lights_DirLight_js__WEBPACK_IMPORTED_MODULE_10__.DirLight(this, {\n\t\t\tdir: [0.8, -0.5, -0.5],\n\t\t\tcolor: [0.67, 0.67, 1.0],\n\t\t\tintensity: 0.6,\n\t\t\tspace: \"world\"\n\t\t});\n\n\t\tnew _lights_DirLight_js__WEBPACK_IMPORTED_MODULE_10__.DirLight(this, {\n\t\t\tdir: [-0.8, -1.0, 0.5],\n\t\t\tcolor: [1, 1, 0.9],\n\t\t\tintensity: 0.8,\n\t\t\tspace: \"world\"\n\t\t});\n\n\t\tthis._camera.on(\"dirty\", () => {\n\t\t\tthis._renderer.imageDirty();\n\t\t});\n\n\t\tthis._lod = new _lod_LOD_js__WEBPACK_IMPORTED_MODULE_1__.LOD(this, {\n\t\t\tenabled: this._lodEnabled,\n\t\t\ttargetFPS: 30\n\t\t});\n\t}\n\n\t_initDefaults() {\n\t\t// Call this Scene's property accessors to lazy-init their properties\n\n\t\tlet dummy; // Keeps Codacy happy\n\n\t\tdummy = this.geometry;\n\t\tdummy = this.material;\n\t\tdummy = this.xrayMaterial;\n\t\tdummy = this.edgeMaterial;\n\t\tdummy = this.selectedMaterial;\n\t\tdummy = this.highlightMaterial;\n\t}\n\n\t_addComponent(component) {\n\t\tif (component.id) {\n\t\t\t// Manual ID\n\t\t\tif (this.components[component.id]) {\n\t\t\t\tthis.error(\n\t\t\t\t\t\"Component \" +\n\t\t\t\t\t\t_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.inQuotes(component.id) +\n\t\t\t\t\t\t\" already exists in Scene - ignoring ID, will randomly-generate instead\"\n\t\t\t\t);\n\t\t\t\tcomponent.id = null;\n\t\t\t}\n\t\t}\n\t\tif (!component.id) {\n\t\t\t// Auto ID\n\t\t\tif (window.nextID === undefined) {\n\t\t\t\twindow.nextID = 0;\n\t\t\t}\n\t\t\t//component.id = math.createUUID();\n\t\t\tcomponent.id = \"__\" + window.nextID++;\n\t\t\twhile (this.components[component.id]) {\n\t\t\t\tcomponent.id = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.createUUID();\n\t\t\t}\n\t\t}\n\t\tthis.components[component.id] = component;\n\n\t\t// Register for class type\n\t\tconst type = component.type;\n\t\tlet types = this.types[component.type];\n\t\tif (!types) {\n\t\t\ttypes = this.types[type] = {};\n\t\t}\n\t\ttypes[component.id] = component;\n\n\t\tif (component.compile) {\n\t\t\tthis._compilables[component.id] = component;\n\t\t}\n\t\tif (component.isDrawable) {\n\t\t\tthis._renderer.addDrawable(component.id, component);\n\t\t\tthis._collidables[component.id] = component;\n\t\t}\n\t}\n\n\t_removeComponent(component) {\n\t\tvar id = component.id;\n\t\tvar type = component.type;\n\t\tdelete this.components[id];\n\t\t// Unregister for types\n\t\tconst types = this.types[type];\n\t\tif (types) {\n\t\t\tdelete types[id];\n\t\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isEmptyObject(types)) {\n\t\t\t\tdelete this.types[type];\n\t\t\t}\n\t\t}\n\t\tif (component.compile) {\n\t\t\tdelete this._compilables[component.id];\n\t\t}\n\t\tif (component.isDrawable) {\n\t\t\tthis._renderer.removeDrawable(component.id);\n\t\t\tdelete this._collidables[component.id];\n\t\t}\n\t}\n\n\t// Methods below are called by various component types to register themselves on their\n\t// Scene. Violates Hollywood Principle, where we could just filter on type in _addComponent,\n\t// but this is faster than checking the type of each component in such a filter.\n\n\t_sectionPlaneCreated(sectionPlane) {\n\t\tthis.sectionPlanes[sectionPlane.id] = sectionPlane;\n\t\tthis.scene._sectionPlanesState.addSectionPlane(sectionPlane._state);\n\t\tthis.scene.fire(\"sectionPlaneCreated\", sectionPlane, true /* Don't retain event */);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_bitmapCreated(bitmap) {\n\t\tthis.bitmaps[bitmap.id] = bitmap;\n\t\tthis.scene.fire(\"bitmapCreated\", bitmap, true /* Don't retain event */);\n\t}\n\n\t_lineSetCreated(lineSet) {\n\t\tthis.lineSets[lineSet.id] = lineSet;\n\t\tthis.scene.fire(\"lineSetCreated\", lineSet, true /* Don't retain event */);\n\t}\n\n\t_lightCreated(light) {\n\t\tthis.lights[light.id] = light;\n\t\tthis.scene._lightsState.addLight(light._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_lightMapCreated(lightMap) {\n\t\tthis.lightMaps[lightMap.id] = lightMap;\n\t\tthis.scene._lightsState.addLightMap(lightMap._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_reflectionMapCreated(reflectionMap) {\n\t\tthis.reflectionMaps[reflectionMap.id] = reflectionMap;\n\t\tthis.scene._lightsState.addReflectionMap(reflectionMap._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_sectionPlaneDestroyed(sectionPlane) {\n\t\tdelete this.sectionPlanes[sectionPlane.id];\n\t\tthis.scene._sectionPlanesState.removeSectionPlane(sectionPlane._state);\n\t\tthis.scene.fire(\"sectionPlaneDestroyed\", sectionPlane, true /* Don't retain event */);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_bitmapDestroyed(bitmap) {\n\t\tdelete this.bitmaps[bitmap.id];\n\t\tthis.scene.fire(\"bitmapDestroyed\", bitmap, true /* Don't retain event */);\n\t}\n\n\t_lineSetDestroyed(lineSet) {\n\t\tdelete this.lineSets[lineSet.id];\n\t\tthis.scene.fire(\"lineSetDestroyed\", lineSet, true /* Don't retain event */);\n\t}\n\n\t_lightDestroyed(light) {\n\t\tdelete this.lights[light.id];\n\t\tthis.scene._lightsState.removeLight(light._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_lightMapDestroyed(lightMap) {\n\t\tdelete this.lightMaps[lightMap.id];\n\t\tthis.scene._lightsState.removeLightMap(lightMap._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_reflectionMapDestroyed(reflectionMap) {\n\t\tdelete this.reflectionMaps[reflectionMap.id];\n\t\tthis.scene._lightsState.removeReflectionMap(reflectionMap._state);\n\t\tthis._needRecompile = true;\n\t}\n\n\t_registerModel(model) {\n\t\tthis.models[model.id] = model;\n\t\tthis._modelIds = null; // Lazy regenerate\n\t}\n\n\t_deregisterModel(model) {\n\t\tconst modelId = model.id;\n\t\tdelete this.models[modelId];\n\t\tthis._modelIds = null; // Lazy regenerate\n\t\tthis.fire(\"modelUnloaded\", modelId);\n\t}\n\n\t_registerObject(entity) {\n\t\tthis.objects[entity.id] = entity;\n\t\tthis._numObjects++;\n\t\tthis._objectIds = null; // Lazy regenerate\n\t}\n\n\t_deregisterObject(entity) {\n\t\tdelete this.objects[entity.id];\n\t\tthis._numObjects--;\n\t\tthis._objectIds = null; // Lazy regenerate\n\t}\n\n\t_objectVisibilityUpdated(entity, notify = true) {\n\t\tif (entity.visible) {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.visibleObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object visibility update (visible=true)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.visibleObjects[entity.id] = entity;\n\t\t\tthis._numVisibleObjects++;\n\t\t} else {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.visibleObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object visibility update (visible=false)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete this.visibleObjects[entity.id];\n\t\t\tthis._numVisibleObjects--;\n\t\t}\n\t\tthis._visibleObjectIds = null; // Lazy regenerate\n\t\tif (notify) {\n\t\t\tthis.fire(\"objectVisibility\", entity, true);\n\t\t}\n\t}\n\n\t_deRegisterVisibleObject(entity) {\n\t\tdelete this.visibleObjects[entity.id];\n\t\tthis._numVisibleObjects--;\n\t\tthis._visibleObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectXRayedUpdated(entity, notify = true) {\n\t\tif (entity.xrayed) {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.xrayedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object xray update (xrayed=true)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.xrayedObjects[entity.id] = entity;\n\t\t\tthis._numXRayedObjects++;\n\t\t} else {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.xrayedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object xray update (xrayed=false)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete this.xrayedObjects[entity.id];\n\t\t\tthis._numXRayedObjects--;\n\t\t}\n\t\tthis._xrayedObjectIds = null; // Lazy regenerate\n\t\tif (notify) {\n\t\t\tthis.fire(\"objectXRayed\", entity, true);\n\t\t}\n\t}\n\n\t_deRegisterXRayedObject(entity) {\n\t\tdelete this.xrayedObjects[entity.id];\n\t\tthis._numXRayedObjects--;\n\t\tthis._xrayedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectHighlightedUpdated(entity) {\n\t\tif (entity.highlighted) {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.highlightedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object highlight update (highlighted=true)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.highlightedObjects[entity.id] = entity;\n\t\t\tthis._numHighlightedObjects++;\n\t\t} else {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.highlightedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object highlight update (highlighted=false)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete this.highlightedObjects[entity.id];\n\t\t\tthis._numHighlightedObjects--;\n\t\t}\n\t\tthis._highlightedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_deRegisterHighlightedObject(entity) {\n\t\tdelete this.highlightedObjects[entity.id];\n\t\tthis._numHighlightedObjects--;\n\t\tthis._highlightedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectSelectedUpdated(entity, notify = true) {\n\t\tif (entity.selected) {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && this.selectedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object select update (selected=true)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.selectedObjects[entity.id] = entity;\n\t\t\tthis._numSelectedObjects++;\n\t\t} else {\n\t\t\tif (ASSERT_OBJECT_STATE_UPDATE && !this.selectedObjects[entity.id]) {\n\t\t\t\tconsole.error(\"Redundant object select update (selected=false)\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete this.selectedObjects[entity.id];\n\t\t\tthis._numSelectedObjects--;\n\t\t}\n\t\tthis._selectedObjectIds = null; // Lazy regenerate\n\t\tif (notify) {\n\t\t\tthis.fire(\"objectSelected\", entity, true);\n\t\t}\n\t}\n\n\t_deRegisterSelectedObject(entity) {\n\t\tdelete this.selectedObjects[entity.id];\n\t\tthis._numSelectedObjects--;\n\t\tthis._selectedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectColorizeUpdated(entity, colorized) {\n\t\tif (colorized) {\n\t\t\tthis.colorizedObjects[entity.id] = entity;\n\t\t\tthis._numColorizedObjects++;\n\t\t} else {\n\t\t\tdelete this.colorizedObjects[entity.id];\n\t\t\tthis._numColorizedObjects--;\n\t\t}\n\t\tthis._colorizedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_deRegisterColorizedObject(entity) {\n\t\tdelete this.colorizedObjects[entity.id];\n\t\tthis._numColorizedObjects--;\n\t\tthis._colorizedObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectOpacityUpdated(entity, opacityUpdated) {\n\t\tif (opacityUpdated) {\n\t\t\tthis.opacityObjects[entity.id] = entity;\n\t\t\tthis._numOpacityObjects++;\n\t\t} else {\n\t\t\tdelete this.opacityObjects[entity.id];\n\t\t\tthis._numOpacityObjects--;\n\t\t}\n\t\tthis._opacityObjectIds = null; // Lazy regenerate\n\t}\n\n\t_deRegisterOpacityObject(entity) {\n\t\tdelete this.opacityObjects[entity.id];\n\t\tthis._numOpacityObjects--;\n\t\tthis._opacityObjectIds = null; // Lazy regenerate\n\t}\n\n\t_objectOffsetUpdated(entity, offset) {\n\t\tif (!offset || (offset[0] === 0 && offset[1] === 0 && offset[2] === 0)) {\n\t\t\tthis.offsetObjects[entity.id] = entity;\n\t\t\tthis._numOffsetObjects++;\n\t\t} else {\n\t\t\tdelete this.offsetObjects[entity.id];\n\t\t\tthis._numOffsetObjects--;\n\t\t}\n\t\tthis._offsetObjectIds = null; // Lazy regenerate\n\t}\n\n\t_deRegisterOffsetObject(entity) {\n\t\tdelete this.offsetObjects[entity.id];\n\t\tthis._numOffsetObjects--;\n\t\tthis._offsetObjectIds = null; // Lazy regenerate\n\t}\n\n\t_webglContextLost() {\n\t\t// this.loading++;\n\t\tthis.canvas.spinner.processes++;\n\t\tfor (const id in this.components) {\n\t\t\tif (this.components.hasOwnProperty(id)) {\n\t\t\t\tconst component = this.components[id];\n\t\t\t\tif (component._webglContextLost) {\n\t\t\t\t\tcomponent._webglContextLost();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis._renderer.webglContextLost();\n\t}\n\n\t_webglContextRestored() {\n\t\tconst gl = this.canvas.gl;\n\t\tfor (const id in this.components) {\n\t\t\tif (this.components.hasOwnProperty(id)) {\n\t\t\t\tconst component = this.components[id];\n\t\t\t\tif (component._webglContextRestored) {\n\t\t\t\t\tcomponent._webglContextRestored(gl);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis._renderer.webglContextRestored(gl);\n\t\t//this.loading--;\n\t\tthis.canvas.spinner.processes--;\n\t}\n\n\t/**\n\t * Returns the capabilities of this Scene.\n\t *\n\t * @private\n\t * @returns {{astcSupported: boolean, etc1Supported: boolean, pvrtcSupported: boolean, etc2Supported: boolean, dxtSupported: boolean, bptcSupported: boolean}}\n\t */\n\tget capabilities() {\n\t\treturn this._renderer.capabilities;\n\t}\n\n\t/**\n\t * Whether {@link Entity#offset} is enabled.\n\t *\n\t * This is set via the {@link Viewer} constructor and is ````false```` by default.\n\t *\n\t * @returns {Boolean} True if {@link Entity#offset} is enabled.\n\t */\n\tget entityOffsetsEnabled() {\n\t\treturn this._entityOffsetsEnabled;\n\t}\n\n\t/**\n\t * Whether precision surface picking is enabled.\n\t *\n\t * This is set via the {@link Viewer} constructor and is ````false```` by default.\n\t *\n\t * The ````pickSurfacePrecision```` option for ````Scene#pick```` only works if this is set ````true````.\n\t *\n\t * Note that when ````true````, this configuration will increase the amount of browser memory used by the Viewer.\n\t *\n\t * @returns {Boolean} True if precision picking is enabled.\n\t */\n\tget pickSurfacePrecisionEnabled() {\n\t\treturn false; // Removed\n\t}\n\n\t/**\n\t * Whether logarithmic depth buffer is enabled.\n\t *\n\t * This is set via the {@link Viewer} constructor and is ````false```` by default.\n\t *\n\t * @returns {Boolean} True if logarithmic depth buffer is enabled.\n\t */\n\tget logarithmicDepthBufferEnabled() {\n\t\treturn this._logarithmicDepthBufferEnabled;\n\t}\n\n\t/**\n\t * Sets the number of {@link SectionPlane}s for which this Scene pre-caches resources.\n\t *\n\t * This property enhances the efficiency of SectionPlane creation by proactively allocating and caching Viewer resources for a specified quantity\n\t * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n\t * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n\t * responsiveness. It is important to consider that each SectionPlane impacts rendering performance, so it is recommended to set this value to a quantity that aligns with\n\t * your expected usage.\n\t *\n\t * Default is ````0````.\n\t */\n\tset numCachedSectionPlanes(numCachedSectionPlanes) {\n\t\tnumCachedSectionPlanes = numCachedSectionPlanes || 0;\n\t\tif (this._sectionPlanesState.getNumCachedSectionPlanes() !== numCachedSectionPlanes) {\n\t\t\tthis._sectionPlanesState.setNumCachedSectionPlanes(numCachedSectionPlanes);\n\t\t\tthis._needRecompile = true;\n\t\t\tthis.glRedraw();\n\t\t}\n\t}\n\n\t/**\n\t * Gets the number of {@link SectionPlane}s for which this Scene pre-caches resources.\n\t *\n\t * This property enhances the efficiency of SectionPlane creation by proactively allocating and caching Viewer resources for a specified quantity\n\t * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n\t * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n\t * responsiveness. It is important to consider that each SectionPlane impacts rendering performance, so it is recommended to set this value to a quantity that aligns with\n\t * your expected usage.\n\t *\n\t * Default is ````0````.\n\t *\n\t * @returns {number} The number of {@link SectionPlane}s for which this Scene pre-caches resources.\n\t */\n\tget numCachedSectionPlanes() {\n\t\treturn this._sectionPlanesState.getNumCachedSectionPlanes();\n\t}\n\n\t/**\n\t * Sets whether physically-based rendering is enabled.\n\t *\n\t * Default is ````false````.\n\t */\n\tset pbrEnabled(pbrEnabled) {\n\t\tthis._pbrEnabled = !!pbrEnabled;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets whether physically-based rendering is enabled.\n\t *\n\t * Default is ````false````.\n\t *\n\t * @returns {Boolean} True if quality rendering is enabled.\n\t */\n\tget pbrEnabled() {\n\t\treturn this._pbrEnabled;\n\t}\n\n\t/**\n\t * Sets whether data texture scene representation (DTX) is enabled for the {@link Scene}.\n\t *\n\t * Even when enabled, DTX will only work if supported.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tset dtxEnabled(value) {\n\t\tvalue = !!value;\n\t\tif (this._dtxEnabled === value) {\n\t\t\treturn;\n\t\t}\n\t\tthis._dtxEnabled = value;\n\t}\n\n\t/**\n\t * Gets whether data texture-based scene representation (DTX) is enabled for the {@link Scene}.\n\t *\n\t * Even when enabled, DTX will only apply if supported.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget dtxEnabled() {\n\t\treturn this._dtxEnabled;\n\t}\n\n\t/**\n\t * set showedges enable\n\t * @param {boolean} edgesEnabled\n\t */\n\tset edgesEnabled(edgesEnabled) {\n\t\tedgesEnabled = !!edgesEnabled;\n\t\tif (this._edgesEnabled === edgesEnabled) {\n\t\t\treturn;\n\t\t}\n\t\tthis._edgesEnabled = edgesEnabled;\n\t\tthis._renderer.setEdgesEnabled(edgesEnabled);\n\t}\n\n\t/**\n\t * @param {boolean} trans\n\t */\n\tget edgesEnabled() {\n\t\treturn this._edgesEnabled;\n\t}\n\n\t/**\n\t * set whether transparent of canvas background\n\t * @param {boolean} trans\n\t */\n\tset backgroundTransparent(trans) {\n\t\ttrans = !!trans;\n\t\t// if (this._transparent == trans) {\n\t\t// return;\n\t\t// }\n\t\tthis._transparent = trans;\n\t\tthis._renderer.setTransparentEnabled(trans);\n\t}\n\n\t/**\n\t * @returns {boolean} backgroundTransparent\n\t */\n\tget backgroundTransparent() {\n\t\treturn this._transparent;\n\t}\n\n\t/**\n\t * set background color\n\t * @param {[]} color\n\t */\n\tset backgroundColor(color) {\n\t\tthis.canvas.backgroundColor = color;\n\t\tthis._renderer.render({ force: true });\n\t}\n\n\t/**\n\t * return backgroundColor\n\t * @returns {boolean} backgroundColor\n\t */\n\tget backgroundColor() {\n\t\treturn this.canvas.backgroundColor();\n\t}\n\n\t/**\n\t * Sets whether basic color texture rendering is enabled.\n\t *\n\t * Default is ````true````.\n\t *\n\t * @returns {Boolean} True if basic color texture rendering is enabled.\n\t */\n\tset colorTextureEnabled(colorTextureEnabled) {\n\t\tthis._colorTextureEnabled = !!colorTextureEnabled;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets whether basic color texture rendering is enabled.\n\t *\n\t * Default is ````true````.\n\t *\n\t * @returns {Boolean} True if basic color texture rendering is enabled.\n\t */\n\tget colorTextureEnabled() {\n\t\treturn this._colorTextureEnabled;\n\t}\n\n\t/**\n\t * Performs an occlusion test on all {@link Marker}s in this {@link Scene}.\n\t *\n\t * Sets each {@link Marker#visible} ````true```` if the Marker is currently not occluded by any opaque {@link Entity}s\n\t * in the Scene, or ````false```` if an Entity is occluding it.\n\t */\n\tdoOcclusionTest() {\n\t\tif (this._needRecompile) {\n\t\t\tthis._recompile();\n\t\t\tthis._needRecompile = false;\n\t\t}\n\t\tthis._renderer.doOcclusionTest();\n\t}\n\n\t/**\n\t * Renders a single frame of this Scene.\n\t *\n\t * The Scene will periodically render itself after any updates, but you can call this method to force a render\n\t * if required.\n\t *\n\t * @param {Boolean} [forceRender=false] Forces a render when true, otherwise only renders if something has changed in this Scene\n\t * since the last render.\n\t */\n\trender(forceRender) {\n\t\tif (forceRender) {\n\t\t\t_core_js__WEBPACK_IMPORTED_MODULE_0__.core.runTasks();\n\t\t}\n\n\t\tconst renderEvent = {\n\t\t\tsceneId: null,\n\t\t\tpass: 0\n\t\t};\n\n\t\tif (this._needRecompile) {\n\t\t\tthis._recompile();\n\t\t\tthis._renderer.imageDirty();\n\t\t\tthis._needRecompile = false;\n\t\t}\n\n\t\tif (!forceRender && !this._renderer.needsRender()) {\n\t\t\treturn;\n\t\t}\n\n\t\trenderEvent.sceneId = this.id;\n\n\t\tconst passes = this._passes;\n\t\tconst clearEachPass = this._clearEachPass;\n\t\tlet pass;\n\t\tlet clear;\n\n\t\tfor (pass = 0; pass < passes; pass++) {\n\t\t\trenderEvent.pass = pass;\n\n\t\t\t/**\n\t\t\t * Fired when about to render a frame for a Scene.\n\t\t\t *\n\t\t\t * @event rendering\n\t\t\t * @param {String} sceneID The ID of this Scene.\n\t\t\t * @param {Number} pass Index of the pass we are about to render (see {@link Scene#passes}).\n\t\t\t */\n\t\t\tthis.fire(\"rendering\", renderEvent, true);\n\n\t\t\tclear = clearEachPass || pass === 0;\n\n\t\t\tthis._renderer.render({ pass: pass, clear: clear, force: forceRender });\n\n\t\t\t/**\n\t\t\t * Fired when we have just rendered a frame for a Scene.\n\t\t\t *\n\t\t\t * @event rendering\n\t\t\t * @param {String} sceneID The ID of this Scene.\n\t\t\t * @param {Number} pass Index of the pass we rendered (see {@link Scene#passes}).\n\t\t\t */\n\t\t\tthis.fire(\"rendered\", renderEvent, true);\n\t\t}\n\n\t\tthis._saveAmbientColor();\n\t}\n\n\t/**\n\t * @private\n\t */\n\tcompile() {\n\t\tif (this._needRecompile) {\n\t\t\tthis._recompile();\n\t\t\tthis._renderer.imageDirty();\n\t\t\tthis._needRecompile = false;\n\t\t}\n\t}\n\n\t_recompile() {\n\t\tfor (const id in this._compilables) {\n\t\t\tif (this._compilables.hasOwnProperty(id)) {\n\t\t\t\tthis._compilables[id].compile();\n\t\t\t}\n\t\t}\n\t\tthis._renderer.shadowsDirty();\n\t\tthis.fire(\"compile\", this, true);\n\t}\n\n\t_saveAmbientColor() {\n\t\tconst canvas = this.canvas;\n\t\tif (!canvas.transparent && !canvas.backgroundImage && !canvas.backgroundColor) {\n\t\t\tconst ambientColorIntensity = this._lightsState.getAmbientColorAndIntensity();\n\t\t\tif (\n\t\t\t\t!this._lastAmbientColor ||\n\t\t\t\tthis._lastAmbientColor[0] !== ambientColorIntensity[0] ||\n\t\t\t\tthis._lastAmbientColor[1] !== ambientColorIntensity[1] ||\n\t\t\t\tthis._lastAmbientColor[2] !== ambientColorIntensity[2] ||\n\t\t\t\tthis._lastAmbientColor[3] !== ambientColorIntensity[3]\n\t\t\t) {\n\t\t\t\tcanvas.backgroundColor = ambientColorIntensity;\n\t\t\t\tif (!this._lastAmbientColor) {\n\t\t\t\t\tthis._lastAmbientColor = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec4([0, 0, 0, 1]);\n\t\t\t\t}\n\t\t\t\tthis._lastAmbientColor.set(ambientColorIntensity);\n\t\t\t}\n\t\t} else {\n\t\t\tthis._lastAmbientColor = null;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#models}.\n\t *\n\t * @type {String[]}\n\t */\n\tget modelIds() {\n\t\tif (!this._modelIds) {\n\t\t\tthis._modelIds = Object.keys(this.models);\n\t\t}\n\t\treturn this._modelIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#objects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numObjects() {\n\t\treturn this._numObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#objects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget objectIds() {\n\t\tif (!this._objectIds) {\n\t\t\tthis._objectIds = Object.keys(this.objects);\n\t\t}\n\t\treturn this._objectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#visibleObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numVisibleObjects() {\n\t\treturn this._numVisibleObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#visibleObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget visibleObjectIds() {\n\t\tif (!this._visibleObjectIds) {\n\t\t\tthis._visibleObjectIds = Object.keys(this.visibleObjects);\n\t\t}\n\t\treturn this._visibleObjectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#xrayedObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numXRayedObjects() {\n\t\treturn this._numXRayedObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#xrayedObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget xrayedObjectIds() {\n\t\tif (!this._xrayedObjectIds) {\n\t\t\tthis._xrayedObjectIds = Object.keys(this.xrayedObjects);\n\t\t}\n\t\treturn this._xrayedObjectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#highlightedObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numHighlightedObjects() {\n\t\treturn this._numHighlightedObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#highlightedObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget highlightedObjectIds() {\n\t\tif (!this._highlightedObjectIds) {\n\t\t\tthis._highlightedObjectIds = Object.keys(this.highlightedObjects);\n\t\t}\n\t\treturn this._highlightedObjectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#selectedObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numSelectedObjects() {\n\t\treturn this._numSelectedObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#selectedObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget selectedObjectIds() {\n\t\tif (!this._selectedObjectIds) {\n\t\t\tthis._selectedObjectIds = Object.keys(this.selectedObjects);\n\t\t}\n\t\treturn this._selectedObjectIds;\n\t}\n\n\t/**\n\t * Gets the number of {@link Entity}s in {@link Scene#colorizedObjects}.\n\t *\n\t * @type {Number}\n\t */\n\tget numColorizedObjects() {\n\t\treturn this._numColorizedObjects;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#colorizedObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget colorizedObjectIds() {\n\t\tif (!this._colorizedObjectIds) {\n\t\t\tthis._colorizedObjectIds = Object.keys(this.colorizedObjects);\n\t\t}\n\t\treturn this._colorizedObjectIds;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#opacityObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget opacityObjectIds() {\n\t\tif (!this._opacityObjectIds) {\n\t\t\tthis._opacityObjectIds = Object.keys(this.opacityObjects);\n\t\t}\n\t\treturn this._opacityObjectIds;\n\t}\n\n\t/**\n\t * Gets the IDs of the {@link Entity}s in {@link Scene#offsetObjects}.\n\t *\n\t * @type {String[]}\n\t */\n\tget offsetObjectIds() {\n\t\tif (!this._offsetObjectIds) {\n\t\t\tthis._offsetObjectIds = Object.keys(this.offsetObjects);\n\t\t}\n\t\treturn this._offsetObjectIds;\n\t}\n\n\t/**\n\t * Sets the number of \"ticks\" that happen between each render or this Scene.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tset ticksPerRender(value) {\n\t\tif (value === undefined || value === null) {\n\t\t\tvalue = 1;\n\t\t} else if (!_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isNumeric(value) || value <= 0) {\n\t\t\tthis.error(\"Unsupported value for 'ticksPerRender': '\" + value + \"' - should be an integer greater than zero.\");\n\t\t\tvalue = 1;\n\t\t}\n\t\tif (value === this._ticksPerRender) {\n\t\t\treturn;\n\t\t}\n\t\tthis._ticksPerRender = value;\n\t}\n\n\t/**\n\t * Gets the number of \"ticks\" that happen between each render or this Scene.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tget ticksPerRender() {\n\t\treturn this._ticksPerRender;\n\t}\n\n\t/**\n\t * Sets the number of \"ticks\" that happen between occlusion testing for {@link Marker}s.\n\t *\n\t * Default value is ````20````.\n\t *\n\t * @type {Number}\n\t */\n\tset ticksPerOcclusionTest(value) {\n\t\tif (value === undefined || value === null) {\n\t\t\tvalue = 20;\n\t\t} else if (!_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isNumeric(value) || value <= 0) {\n\t\t\tthis.error(\n\t\t\t\t\"Unsupported value for 'ticksPerOcclusionTest': '\" + value + \"' - should be an integer greater than zero.\"\n\t\t\t);\n\t\t\tvalue = 20;\n\t\t}\n\t\tif (value === this._ticksPerOcclusionTest) {\n\t\t\treturn;\n\t\t}\n\t\tthis._ticksPerOcclusionTest = value;\n\t}\n\n\t/**\n\t * Gets the number of \"ticks\" that happen between each render of this Scene.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tget ticksPerOcclusionTest() {\n\t\treturn this._ticksPerOcclusionTest;\n\t}\n\n\t/**\n\t * Sets the number of times this Scene renders per frame.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tset passes(value) {\n\t\tif (value === undefined || value === null) {\n\t\t\tvalue = 1;\n\t\t} else if (!_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isNumeric(value) || value <= 0) {\n\t\t\tthis.error(\"Unsupported value for 'passes': '\" + value + \"' - should be an integer greater than zero.\");\n\t\t\tvalue = 1;\n\t\t}\n\t\tif (value === this._passes) {\n\t\t\treturn;\n\t\t}\n\t\tthis._passes = value;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the number of times this Scene renders per frame.\n\t *\n\t * Default value is ````1````.\n\t *\n\t * @type {Number}\n\t */\n\tget passes() {\n\t\treturn this._passes;\n\t}\n\n\t/**\n\t * When {@link Scene#passes} is greater than ````1````, indicates whether or not to clear the canvas before each pass (````true````) or just before the first pass (````false````).\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tset clearEachPass(value) {\n\t\tvalue = !!value;\n\t\tif (value === this._clearEachPass) {\n\t\t\treturn;\n\t\t}\n\t\tthis._clearEachPass = value;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * When {@link Scene#passes} is greater than ````1````, indicates whether or not to clear the canvas before each pass (````true````) or just before the first pass (````false````).\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget clearEachPass() {\n\t\treturn this._clearEachPass;\n\t}\n\n\t/**\n\t * Sets whether or not {@link Scene} should expect all {@link Texture}s and colors to have pre-multiplied gamma.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tset gammaInput(value) {\n\t\tvalue = value !== false;\n\t\tif (value === this._renderer.gammaInput) {\n\t\t\treturn;\n\t\t}\n\t\tthis._renderer.gammaInput = value;\n\t\tthis._needRecompile = true;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets whether or not {@link Scene} should expect all {@link Texture}s and colors to have pre-multiplied gamma.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget gammaInput() {\n\t\treturn this._renderer.gammaInput;\n\t}\n\n\t/**\n\t * Sets whether or not to render pixels with pre-multiplied gama.\n\t *\n\t * Default value is ````false````.\n\t *\n\t * @type {Boolean}\n\t */\n\tset gammaOutput(value) {\n\t\tvalue = !!value;\n\t\tif (value === this._renderer.gammaOutput) {\n\t\t\treturn;\n\t\t}\n\t\tthis._renderer.gammaOutput = value;\n\t\tthis._needRecompile = true;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets whether or not to render pixels with pre-multiplied gama.\n\t *\n\t * Default value is ````true````.\n\t *\n\t * @type {Boolean}\n\t */\n\tget gammaOutput() {\n\t\treturn this._renderer.gammaOutput;\n\t}\n\n\t/**\n\t * Sets the gamma factor to use when {@link Scene#gammaOutput} is set true.\n\t *\n\t * Default value is ````2.2````.\n\t *\n\t * @type {Number}\n\t */\n\tset gammaFactor(value) {\n\t\tvalue = value === undefined || value === null ? 2.2 : value;\n\t\tif (value === this._renderer.gammaFactor) {\n\t\t\treturn;\n\t\t}\n\t\tthis._renderer.gammaFactor = value;\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * Gets the gamma factor to use when {@link Scene#gammaOutput} is set true.\n\t *\n\t * Default value is ````2.2````.\n\t *\n\t * @type {Number}\n\t */\n\tget gammaFactor() {\n\t\treturn this._renderer.gammaFactor;\n\t}\n\n\t/**\n\t * Gets the default {@link Geometry} for this Scene, which is a {@link ReadableGeometry} with a unit-sized box shape.\n\t *\n\t * Has {@link ReadableGeometry#id} set to \"default.geometry\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#geometry} set to this {@link ReadableGeometry} by default.\n\t *\n\t * @type {ReadableGeometry}\n\t */\n\tget geometry() {\n\t\treturn (\n\t\t\tthis.components[\"default.geometry\"] ||\n\t\t\t(0,_geometry_builders_buildBoxGeometry_js__WEBPACK_IMPORTED_MODULE_13__.buildBoxGeometry)(_geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_12__.ReadableGeometry, this, {\n\t\t\t\tid: \"default.geometry\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default {@link Material} for this Scene, which is a {@link PhongMaterial}.\n\t *\n\t * Has {@link PhongMaterial#id} set to \"default.material\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#material} set to this {@link PhongMaterial} by default.\n\t *\n\t * @type {PhongMaterial}\n\t */\n\tget material() {\n\t\treturn (\n\t\t\tthis.components[\"default.material\"] ||\n\t\t\tnew _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_14__.PhongMaterial(this, {\n\t\t\t\tid: \"default.material\",\n\t\t\t\temissive: [0.4, 0.4, 0.4], // Visible by default on geometry without normals\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default xraying {@link EmphasisMaterial} for this Scene.\n\t *\n\t * Has {@link EmphasisMaterial#id} set to \"default.xrayMaterial\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#xrayMaterial} set to this {@link EmphasisMaterial} by default.\n\t *\n\t * {@link Mesh}s are xrayed while {@link Mesh#xrayed} is ````true````.\n\t *\n\t * @type {EmphasisMaterial}\n\t */\n\tget xrayMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.xrayMaterial\"] ||\n\t\t\tnew _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__.EmphasisMaterial(this, {\n\t\t\t\tid: \"default.xrayMaterial\",\n\t\t\t\tpreset: \"sepia\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default highlight {@link EmphasisMaterial} for this Scene.\n\t *\n\t * Has {@link EmphasisMaterial#id} set to \"default.highlightMaterial\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#highlightMaterial} set to this {@link EmphasisMaterial} by default.\n\t *\n\t * {@link Mesh}s are highlighted while {@link Mesh#highlighted} is ````true````.\n\t *\n\t * @type {EmphasisMaterial}\n\t */\n\tget highlightMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.highlightMaterial\"] ||\n\t\t\tnew _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__.EmphasisMaterial(this, {\n\t\t\t\tid: \"default.highlightMaterial\",\n\t\t\t\tpreset: \"yellowHighlight\",\n\t\t\t\tfillAlpha: 0.1,\n\t\t\t\tfillColor: [0.7, 0.9, 0.9],\n\t\t\t\tdontClear: false,\n\t\t\t\tedges: false,\n\t\t\t\tglowThrough: false\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default selection {@link EmphasisMaterial} for this Scene.\n\t *\n\t * Has {@link EmphasisMaterial#id} set to \"default.selectedMaterial\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#highlightMaterial} set to this {@link EmphasisMaterial} by default.\n\t *\n\t * {@link Mesh}s are highlighted while {@link Mesh#highlighted} is ````true````.\n\t *\n\t * @type {EmphasisMaterial}\n\t */\n\tget selectedMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.selectedMaterial\"] ||\n\t\t\tnew _materials_EmphasisMaterial_js__WEBPACK_IMPORTED_MODULE_15__.EmphasisMaterial(this, {\n\t\t\t\tid: \"default.selectedMaterial\",\n\t\t\t\tpreset: \"greenSelected\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the default {@link EdgeMaterial} for this Scene.\n\t *\n\t * Has {@link EdgeMaterial#id} set to \"default.edgeMaterial\".\n\t *\n\t * {@link Mesh}s in this Scene have {@link Mesh#edgeMaterial} set to this {@link EdgeMaterial} by default.\n\t *\n\t * {@link Mesh}s have their edges emphasized while {@link Mesh#edges} is ````true````.\n\t *\n\t * @type {EdgeMaterial}\n\t */\n\tget edgeMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.edgeMaterial\"] ||\n\t\t\tnew _materials_EdgeMaterial_js__WEBPACK_IMPORTED_MODULE_16__.EdgeMaterial(this, {\n\t\t\t\tid: \"default.edgeMaterial\",\n\t\t\t\tpreset: \"default\",\n\t\t\t\tedgeColor: [0.0, 0.0, 0.0],\n\t\t\t\tedgeAlpha: 1.0,\n\t\t\t\tedgeWidth: 1,\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the {@link PointsMaterial} for this Scene.\n\t *\n\t * @type {PointsMaterial}\n\t */\n\tget pointsMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.pointsMaterial\"] ||\n\t\t\tnew _materials_PointsMaterial_js__WEBPACK_IMPORTED_MODULE_19__.PointsMaterial(this, {\n\t\t\t\tid: \"default.pointsMaterial\",\n\t\t\t\tpreset: \"default\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the {@link LinesMaterial} for this Scene.\n\t *\n\t * @type {LinesMaterial}\n\t */\n\tget linesMaterial() {\n\t\treturn (\n\t\t\tthis.components[\"default.linesMaterial\"] ||\n\t\t\tnew _materials_LinesMaterial_js__WEBPACK_IMPORTED_MODULE_20__.LinesMaterial(this, {\n\t\t\t\tid: \"default.linesMaterial\",\n\t\t\t\tpreset: \"default\",\n\t\t\t\tdontClear: true\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Gets the {@link Viewport} for this Scene.\n\t *\n\t * @type Viewport\n\t */\n\tget viewport() {\n\t\treturn this._viewport;\n\t}\n\n\t/**\n\t * Gets the {@link Camera} for this Scene.\n\t *\n\t * @type {Camera}\n\t */\n\tget camera() {\n\t\treturn this._camera;\n\t}\n\n\t/**\n\t * Gets the World-space 3D center of this Scene.\n\t *\n\t *@type {Number[]}\n\t */\n\tget center() {\n\t\tif (this._aabbDirty || !this._center) {\n\t\t\tif (!this._center || !this._center) {\n\t\t\t\tthis._center = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec3();\n\t\t\t}\n\t\t\tconst aabb = this.aabb;\n\t\t\tthis._center[0] = (aabb[0] + aabb[3]) / 2;\n\t\t\tthis._center[1] = (aabb[1] + aabb[4]) / 2;\n\t\t\tthis._center[2] = (aabb[2] + aabb[5]) / 2;\n\t\t}\n\t\treturn this._center;\n\t}\n\n\t/**\n\t * Gets the World-space axis-aligned 3D boundary (AABB) of this Scene.\n\t *\n\t * The AABB is represented by a six-element Float64Array containing the min/max extents of the axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n\t *\n\t * When the Scene has no content, will be ````[-100,-100,-100,100,100,100]````.\n\t *\n\t * @type {Number[]}\n\t */\n\tget aabb() {\n\t\tif (this._aabbDirty) {\n\t\t\tif (this._aabbUpdate) {\n\t\t\t\treturn this._aabb;\n\t\t\t}\n\t\t\tif (!this._aabb) {\n\t\t\t\tthis._aabb = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.AABB3();\n\t\t\t}\n\t\t\tlet xmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\t\tlet ymin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\t\tlet zmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\t\tlet xmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\t\tlet ymax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\t\tlet zmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\t\tlet aabb;\n\t\t\tconst collidables = this._collidables;\n\t\t\tlet collidable;\n\t\t\tlet valid = false;\n\t\t\tfor (const collidableId in collidables) {\n\t\t\t\tif (collidables.hasOwnProperty(collidableId)) {\n\t\t\t\t\tcollidable = collidables[collidableId];\n\t\t\t\t\tif (collidable.collidable === false) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\taabb = collidable.aabb;\n\t\t\t\t\tif (aabb[0] < xmin) {\n\t\t\t\t\t\txmin = aabb[0];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[1] < ymin) {\n\t\t\t\t\t\tymin = aabb[1];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[2] < zmin) {\n\t\t\t\t\t\tzmin = aabb[2];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[3] > xmax) {\n\t\t\t\t\t\txmax = aabb[3];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[4] > ymax) {\n\t\t\t\t\t\tymax = aabb[4];\n\t\t\t\t\t}\n\t\t\t\t\tif (aabb[5] > zmax) {\n\t\t\t\t\t\tzmax = aabb[5];\n\t\t\t\t\t}\n\t\t\t\t\tvalid = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!valid) {\n\t\t\t\txmin = -100;\n\t\t\t\tymin = -100;\n\t\t\t\tzmin = -100;\n\t\t\t\txmax = 100;\n\t\t\t\tymax = 100;\n\t\t\t\tzmax = 100;\n\t\t\t}\n\t\t\tthis._aabb[0] = xmin;\n\t\t\tthis._aabb[1] = ymin;\n\t\t\tthis._aabb[2] = zmin;\n\t\t\tthis._aabb[3] = xmax;\n\t\t\tthis._aabb[4] = ymax;\n\t\t\tthis._aabb[5] = zmax;\n\t\t\tthis._aabbDirty = false;\n\t\t}\n\t\treturn this._aabb;\n\t}\n\n\tget aabbs() {\n\t\tconst collidables = this._collidables;\n\t\tfor (const collidableId in collidables) {\n\t\t\treturn collidables[collidableId].aabbs;\n\t\t}\n\t}\n\n\tcalculateBoxCenter(boxs) {\n\t\tlet points = [];\n\t\tfor (let i = 0; i < boxs.length; i++) {\n\t\t\tlet box = boxs[i];\n\t\t\tlet center = [(box[0] + box[3]) / 2, (box[1] + box[4]) / 2, (box[2] + box[5]) / 2];\n\t\t\tpoints.push(_math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.vec3(center));\n\t\t}\n\t\treturn points;\n\t}\n\n\t_setAABBDirty() {\n\t\tthis._aabbDirty = true;\n\t\tthis.center;\n\t\t// this.fire(\"boundary\");\n\t}\n\n\t/**\n * Attempts to pick an {@link Entity} in this Scene.\n *\n * Ignores {@link Entity}s with {@link Entity#pickable} set ````false````.\n *\n * When an {@link Entity} is picked, fires a \"pick\" event on the {@link Entity} with the pick result as parameters.\n *\n * Picking the {@link Entity} at the given canvas coordinates:\n\n * ````javascript\n * var pickResult = scene.pick({\n * canvasPos: [23, 131]\n * });\n *\n * if (pickResult) { // Picked an Entity\n * var entity = pickResult.entity;\n * }\n * ````\n *\n * Picking, with a ray cast through the canvas, hits an {@link Entity}:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * pickSurface: true,\n * canvasPos: [23, 131]\n * });\n *\n * if (pickResult) { // Picked an Entity\n *\n * var entity = pickResult.entity;\n *\n * if (pickResult.primitive === \"triangle\") {\n *\n * // Picked a triangle on the entity surface\n *\n * var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Entity's Geometry's indices array\n * var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\n * var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\n * var viewPos = pickResult.viewPos; // Float64Array containing the picked View-space position on the triangle\n * var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the interpolated World-space normal vector at the picked position on the triangle\n * var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\n *\n * } else if (pickResult.worldPos && pickResult.worldNormal) {\n *\n * // Picked a point and normal on the entity surface\n *\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the Entity surface\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the picked World-space normal vector on the Entity Surface\n * }\n * }\n * ````\n *\n * Picking the {@link Entity} that intersects an arbitrarily-aligned World-space ray:\n *\n * ````javascript\n * var pickResult = scene.pick({\n * pickSurface: true, // Picking with arbitrarily-positioned ray\n * origin: [0,0,-5], // Ray origin\n * direction: [0,0,1] // Ray direction\n * });\n *\n * if (pickResult) { // Picked an Entity with the ray\n *\n * var entity = pickResult.entity;\n *\n * if (pickResult.primitive == \"triangle\") {\n *\n * // Picked a triangle on the entity surface\n *\n * var primitive = pickResult.primitive; // Type of primitive that was picked, usually \"triangles\"\n * var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Entity's Geometry's indices array\n * var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\n * var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\n * var viewPos = pickResult.viewPos; // Float64Array containing the picked View-space position on the triangle\n * var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the interpolated World-space normal vector at the picked position on the triangle\n * var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\n * var origin = pickResult.origin; // Float64Array containing the World-space ray origin\n * var direction = pickResult.direction; // Float64Array containing the World-space ray direction\n *\n * } else if (pickResult.worldPos && pickResult.worldNormal) {\n *\n * // Picked a point and normal on the entity surface\n *\n * var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the Entity surface\n * var worldNormal = pickResult.worldNormal; // Float64Array containing the picked World-space normal vector on the Entity Surface\n * }\n * }\n * ````\n *\n * @param {*} params Picking parameters.\n * @param {Boolean} [params.pickSurface=false] Whether to find the picked position on the surface of the Entity.\n * @param {Boolean} [params.pickSurfacePrecision=false] When picking an Entity surface position, indicates whether or not we want full-precision {@link PickResult#worldPos}. Only works when {@link Scene#pickSurfacePrecisionEnabled} is ````true````. If pick succeeds, the returned {@link PickResult} will have {@link PickResult#precision} set ````true````, to indicate that it contains full-precision surface pick results.\n * @param {Boolean} [params.pickSurfaceNormal=false] Whether to find the picked normal on the surface of the Entity. Only works if ````pickSurface```` is given.\n * @param {Number[]} [params.canvasPos] Canvas-space coordinates. When ray-picking, this will override the **origin** and ** direction** parameters and will cause the ray to be fired through the canvas at this position, directly along the negative View-space Z-axis.\n * @param {Number[]} [params.origin] World-space ray origin when ray-picking. Ignored when canvasPos given.\n * @param {Number[]} [params.direction] World-space ray direction when ray-picking. Also indicates the length of the ray. Ignored when canvasPos given.\n * @param {Number[]} [params.matrix] 4x4 transformation matrix to define the World-space ray origin and direction, as an alternative to ````origin```` and ````direction````.\n * @param {String[]} [params.includeEntities] IDs of {@link Entity}s to restrict picking to. When given, ignores {@link Entity}s whose IDs are not in this list.\n * @param {String[]} [params.excludeEntities] IDs of {@link Entity}s to ignore. When given, will pick *through* these {@link Entity}s, as if they were not there.\n * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels\n * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.\n * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.\n * @param {PickResult} [pickResult] Holds the results of the pick attempt. Will use the Scene's singleton PickResult if you don't supply your own.\n * @returns {PickResult} Holds results of the pick attempt, returned when an {@link Entity} is picked, else null. See method comments for description.\n */\n\tpick(params, pickResult) {\n\t\tif (this.canvas.boundary[2] === 0 || this.canvas.boundary[3] === 0) {\n\t\t\tthis.error(\"Picking not allowed while canvas has zero width or height\");\n\t\t\treturn null;\n\t\t}\n\n\t\tparams = params || {};\n\n\t\tparams.pickSurface = params.pickSurface || params.rayPick; // Backwards compatibility\n\n\t\tif (!params.canvasPos && !params.matrix && (!params.origin || !params.direction)) {\n\t\t\tthis.warn(\"picking without canvasPos, matrix, or ray origin and direction\");\n\t\t}\n\n\t\tconst includeEntities = params.includeEntities || params.include; // Backwards compat\n\t\tif (includeEntities) {\n\t\t\tparams.includeEntityIds = getEntityIDMap(this, includeEntities);\n\t\t}\n\n\t\tconst excludeEntities = params.excludeEntities || params.exclude; // Backwards compat\n\t\tif (excludeEntities) {\n\t\t\tparams.excludeEntityIds = getEntityIDMap(this, excludeEntities);\n\t\t}\n\n\t\tif (this._needRecompile) {\n\t\t\tthis._recompile();\n\t\t\tthis._renderer.imageDirty();\n\t\t\tthis._needRecompile = false;\n\t\t}\n\n\t\tif (params.snapToEdge || params.snapToVertex) {\n\t\t\tpickResult = this._renderer.snapPick(\n\t\t\t\tparams.canvasPos,\n\t\t\t\tparams.snapRadius || 30,\n\t\t\t\tparams.snapToVertex,\n\t\t\t\tparams.snapToEdge,\n\t\t\t\tpickResult\n\t\t\t);\n\t\t} else {\n\t\t\tpickResult = this._renderer.pick(params, pickResult);\n\t\t}\n\n\t\tif (pickResult) {\n\t\t\tif (pickResult.entity && pickResult.entity.fire) {\n\t\t\t\tpickResult.entity.fire(\"picked\", pickResult); // TODO: SceneModelEntity doesn't fire events\n\t\t\t}\n\t\t}\n\n\t\treturn pickResult;\n\t}\n\n\t/**\n\t * @param {Object} params Picking parameters.\n\t * @param {Number[]} [params.canvasPos] Canvas-space coordinates. When ray-picking, this will override the **origin** and ** direction** parameters and will cause the ray to be fired through the canvas at this position, directly along the negative View-space Z-axis.\n\t * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels\n\t * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.\n\t * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.\n\t * @deprecated\n\t */\n\tsnapPick(params) {\n\t\tif (undefined === this._warnSnapPickDeprecated) {\n\t\t\tthis._warnSnapPickDeprecated = true;\n\t\t\tthis.warn(\"Scene.snapPick() is deprecated since v2.4.2 - use Scene.pick() instead\");\n\t\t}\n\t\treturn this._renderer.snapPick(params.canvasPos, params.snapRadius || 30, params.snapToVertex, params.snapToEdge);\n\t}\n\n\t/**\n\t * Destroys all non-default {@link Component}s in this Scene.\n\t */\n\tclear() {\n\t\tvar component;\n\t\tfor (const id in this.components) {\n\t\t\tif (this.components.hasOwnProperty(id)) {\n\t\t\t\tcomponent = this.components[id];\n\t\t\t\tif (!component._dontClear) {\n\t\t\t\t\t// Don't destroy components like Camera, Input, Viewport etc.\n\t\t\t\t\tcomponent.destroy();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all {@link Light}s in this Scene..\n\t */\n\tclearLights() {\n\t\tconst ids = Object.keys(this.lights);\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tthis.lights[ids[i]].destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all {@link SectionPlane}s in this Scene.\n\t */\n\tclearSectionPlanes() {\n\t\tconst ids = Object.keys(this.sectionPlanes);\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tthis.sectionPlanes[ids[i]].destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all {@link Line}s in this Scene.\n\t */\n\tclearBitmaps() {\n\t\tconst ids = Object.keys(this.bitmaps);\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tthis.bitmaps[ids[i]].destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all {@link Line}s in this Scene.\n\t */\n\tclearLines() {\n\t\tconst ids = Object.keys(this.lineSets);\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tthis.lineSets[ids[i]].destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Gets the collective axis-aligned boundary (AABB) of a batch of {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * Each {@link Entity} on which {@link Entity#isObject} is registered by {@link Entity#id} in {@link Scene#visibleObjects}.\n\t *\n\t * Each {@link Entity} is only included in the AABB when {@link Entity#collidable} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @returns {[Number, Number, Number, Number, Number, Number]} An axis-aligned World-space bounding box, given as elements ````[xmin, ymin, zmin, xmax, ymax, zmax]````.\n\t */\n\tgetAABB(ids) {\n\t\tif (ids === undefined) {\n\t\t\treturn this.aabb;\n\t\t}\n\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isString(ids)) {\n\t\t\tconst entity = this.objects[ids];\n\t\t\tif (entity && entity.aabb) {\n\t\t\t\t// A Component subclass with an AABB\n\t\t\t\treturn entity.aabb;\n\t\t\t}\n\t\t\tids = [ids]; // Must be an entity type\n\t\t}\n\t\tif (ids.length === 0) {\n\t\t\treturn this.aabb;\n\t\t}\n\t\tlet xmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\tlet ymin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\tlet zmin = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MAX_DOUBLE;\n\t\tlet xmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\tlet ymax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\tlet zmax = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.MIN_DOUBLE;\n\t\tlet valid;\n\t\tthis.withObjects(ids, (entity) => {\n\t\t\tif (entity.collidable) {\n\t\t\t\tconst aabb = entity.aabb;\n\t\t\t\tif (aabb[0] < xmin) {\n\t\t\t\t\txmin = aabb[0];\n\t\t\t\t}\n\t\t\t\tif (aabb[1] < ymin) {\n\t\t\t\t\tymin = aabb[1];\n\t\t\t\t}\n\t\t\t\tif (aabb[2] < zmin) {\n\t\t\t\t\tzmin = aabb[2];\n\t\t\t\t}\n\t\t\t\tif (aabb[3] > xmax) {\n\t\t\t\t\txmax = aabb[3];\n\t\t\t\t}\n\t\t\t\tif (aabb[4] > ymax) {\n\t\t\t\t\tymax = aabb[4];\n\t\t\t\t}\n\t\t\t\tif (aabb[5] > zmax) {\n\t\t\t\t\tzmax = aabb[5];\n\t\t\t\t}\n\t\t\t\tvalid = true;\n\t\t\t}\n\t\t});\n\t\tif (valid) {\n\t\t\tconst aabb2 = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.AABB3();\n\t\t\taabb2[0] = xmin;\n\t\t\taabb2[1] = ymin;\n\t\t\taabb2[2] = zmin;\n\t\t\taabb2[3] = xmax;\n\t\t\taabb2[4] = ymax;\n\t\t\taabb2[5] = zmax;\n\t\t\treturn aabb2;\n\t\t} else {\n\t\t\treturn this.aabb; // Scene AABB\n\t\t}\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#visible} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#visible} are ````true```` is\n\t * registered by {@link Entity#id} in {@link Scene#visibleObjects}.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} visible Whether or not to set visible.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsVisible(ids, visible) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.visible !== visible;\n\t\t\tentity.visible = visible;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#collidable} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} collidable Whether or not to set collidable.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsCollidable(ids, collidable) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.collidable !== collidable;\n\t\t\tentity.collidable = collidable;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#culled} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} culled Whether or not to cull.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsCulled(ids, culled) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.culled !== culled;\n\t\t\tentity.culled = culled;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#selected} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#selected} are ````true```` is\n\t * registered by {@link Entity#id} in {@link Scene#selectedObjects}.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} selected Whether or not to select.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsSelected(ids, selected) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.selected !== selected;\n\t\t\tentity.selected = selected;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#highlighted} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#highlighted} are ````true```` is\n\t * registered by {@link Entity#id} in {@link Scene#highlightedObjects}.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} highlighted Whether or not to highlight.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsHighlighted(ids, highlighted) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.highlighted !== highlighted;\n\t\t\tentity.highlighted = highlighted;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#xrayed} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} xrayed Whether or not to xray.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsXRayed(ids, xrayed) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.xrayed !== xrayed;\n\t\t\tentity.xrayed = xrayed;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#edges} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} edges Whether or not to show edges.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsEdges(ids, edges) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.edges !== edges;\n\t\t\tentity.edges = edges;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#colorize} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Number[]} [colorize=(1,1,1)] RGB colorize factors, multiplied by the rendered pixel colors.\n\t * @returns {Boolean} True if any {@link Entity}s changed opacity, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsColorized(ids, colorize) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tentity.colorize = colorize;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#opacity} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Number} [opacity=1.0] Opacity factor, multiplied by the rendered pixel alphas.\n\t * @returns {Boolean} True if any {@link Entity}s changed opacity, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsOpacity(ids, opacity) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.opacity !== opacity;\n\t\t\tentity.opacity = opacity;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#pickable} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Boolean} pickable Whether or not to set pickable.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\tsetObjectsPickable(ids, pickable) {\n\t\treturn this.withObjects(ids, (entity) => {\n\t\t\tconst changed = entity.pickable !== pickable;\n\t\t\tentity.pickable = pickable;\n\t\t\treturn changed;\n\t\t});\n\t}\n\n\t/**\n\t * Batch-updates {@link Entity#offset} on {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Number[]} [offset] 3D offset vector.\n\t */\n\tsetObjectsOffset(ids, offset) {\n\t\tthis.withObjects(ids, (entity) => {\n\t\t\tentity.offset = offset;\n\t\t});\n\t}\n\n\t/**\n\t * Iterates with a callback over {@link Entity}s that represent objects.\n\t *\n\t * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n\t *\n\t * @param {String[]} ids Array of {@link Entity#id} values.\n\t * @param {Function} callback Callback to execute on eacn {@link Entity}.\n\t * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n\t */\n\twithObjects(ids, callback) {\n\t\tif (_utils_js__WEBPACK_IMPORTED_MODULE_2__.utils.isString(ids)) {\n\t\t\tids = [ids];\n\t\t}\n\t\tlet changed = false;\n\t\tfor (let i = 0, len = ids.length; i < len; i++) {\n\t\t\tconst id = ids[i];\n\t\t\tlet entity = this.objects[id];\n\t\t\tif (entity) {\n\t\t\t\tchanged = callback(entity) || changed;\n\t\t\t} else {\n\t\t\t\tconst modelIds = this.modelIds;\n\t\t\t\tfor (let i = 0, len = modelIds.length; i < len; i++) {\n\t\t\t\t\tconst modelId = modelIds[i];\n\t\t\t\t\tconst globalObjectId = _math_math_js__WEBPACK_IMPORTED_MODULE_3__.math.globalizeObjectId(modelId, id);\n\t\t\t\t\tentity = this.objects[globalObjectId];\n\t\t\t\t\tif (entity) {\n\t\t\t\t\t\tchanged = callback(entity) || changed;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn changed;\n\t}\n\n\t/**\n\t * This method will \"tickify\" the provided `cb` function.\n\t *\n\t * This means, the function will be wrapped so:\n\t *\n\t * - it runs time-aligned to scene ticks\n\t * - it runs maximum once per scene-tick\n\t *\n\t * @param {Function} cb The function to tickify\n\t * @returns {Function}\n\t */\n\ttickify(cb) {\n\t\tconst cbString = cb.toString();\n\n\t\t/**\n\t\t * Check if the function is already tickified, and if so return the cached one.\n\t\t */\n\t\tif (cbString in this._tickifiedFunctions) {\n\t\t\treturn this._tickifiedFunctions[cbString].wrapperFunc;\n\t\t}\n\n\t\tlet alreadyRun = 0;\n\t\tlet needToRun = 0;\n\n\t\tlet lastArgs;\n\n\t\t/**\n\t\t * The provided `cb` function is replaced with a \"set-dirty\" function\n\t\t *\n\t\t * @type {Function}\n\t\t */\n\t\tconst wrapperFunc = function (...args) {\n\t\t\tlastArgs = args;\n\t\t\tneedToRun++;\n\t\t};\n\n\t\t/**\n\t\t * An each scene tick, if the \"dirty-flag\" is set, run the `cb` function.\n\t\t *\n\t\t * This will make it run time-aligned to the scene tick.\n\t\t */\n\t\tconst tickSubId = this.on(\"tick\", () => {\n\t\t\tconst tmp = needToRun;\n\t\t\tif (tmp > alreadyRun) {\n\t\t\t\talreadyRun = tmp;\n\t\t\t\tcb(...lastArgs);\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * And, store the list of subscribers.\n\t\t */\n\t\tthis._tickifiedFunctions[cbString] = { tickSubId, wrapperFunc };\n\n\t\treturn wrapperFunc;\n\t}\n\n\t/**\n\t * Destroys this Scene.\n\t */\n\tdestroy(callback) {\n\t\tsuper.destroy();\n\t\tfor (const id in this.components) {\n\t\t\tif (this.components.hasOwnProperty(id)) {\n\t\t\t\tthis.components[id].destroy();\n\t\t\t}\n\t\t}\n\t\t// this.canvas.destroy(); // canvas是scene的其中一个component,所有以不必再destroy\n\n\t\t// Memory leak prevention\n\t\tthis.components = null;\n\t\tthis.models = null;\n\t\tthis.objects = null;\n\t\tthis.visibleObjects = null;\n\t\tthis.xrayedObjects = null;\n\t\tthis.highlightedObjects = null;\n\t\tthis.selectedObjects = null;\n\t\tthis.colorizedObjects = null;\n\t\tthis.opacityObjects = null;\n\t\tthis.sectionPlanes = null;\n\t\tthis.lights = null;\n\t\tthis.lightMaps = null;\n\t\tthis.reflectionMaps = null;\n\t\tthis._objectIds = null;\n\t\tthis._visibleObjectIds = null;\n\t\tthis._xrayedObjectIds = null;\n\t\tthis._highlightedObjectIds = null;\n\t\tthis._selectedObjectIds = null;\n\t\tthis._colorizedObjectIds = null;\n\t\tthis.types = null;\n\t\tthis._renderer = null;\n\t\tthis.input = null;\n\t\tthis._viewport = null;\n\t\tthis._camera = null;\n\t\tthis.canvas = null;\n\t\tif (typeof callback === \"function\") {\n\t\t\tcallback();\n\t\t}\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/scene/Scene.js?");
4808
4828
 
4809
4829
  /***/ }),
4810
4830
 
@@ -4834,7 +4854,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4834
4854
  \*******************************************************/
4835
4855
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4836
4856
 
4837
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SectionPlane: () => (/* binding */ SectionPlane)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../webgl/RenderState.js */ \"./src/viewer/scene/webgl/RenderState.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n\r\n\r\n\r\n\r\nconst tempVec3a = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\r\n\r\n/**\r\n * @desc An arbitrarily-aligned World-space clipping plane.\r\n *\r\n * * Slices portions off objects to create cross-section views or reveal interiors.\r\n * * Registered by {@link SectionPlane#id} in {@link Scene#sectionPlanes}.\r\n * * Indicates World-space position in {@link SectionPlane#pos} and orientation in {@link SectionPlane#dir}.\r\n * * Discards elements from the half-space in the direction of {@link SectionPlane#dir}.\r\n * * Can be be enabled or disabled via {@link SectionPlane#active}.\r\n *\r\n * ## Usage\r\n *\r\n * In the example below, we'll create two SectionPlanes to slice a model loaded from glTF. Note that we could also create them\r\n * using a {@link SectionPlanesPlugin}.\r\n *\r\n * ````javascript\r\n * import {Viewer, GLTFLoaderPlugin, SectionPlane} from \"xeokit-sdk.es.js\";\r\n *\r\n * const viewer = new Viewer({\r\n * canvasId: \"myCanvas\"\r\n * });\r\n *\r\n * const gltfLoaderPlugin = new GLTFModelsPlugin(viewer, {\r\n * id: \"GLTFModels\"\r\n * });\r\n *\r\n * const model = gltfLoaderPlugin.load({\r\n * id: \"myModel\",\r\n * src: \"./models/gltf/mygltfmodel.gltf\"\r\n * });\r\n *\r\n * // Create a SectionPlane on negative diagonal\r\n * const sectionPlane1 = new SectionPlane(viewer.scene, {\r\n * pos: [1.0, 1.0, 1.0],\r\n * dir: [-1.0, -1.0, -1.0],\r\n * active: true\r\n * }),\r\n *\r\n * // Create a SectionPlane on positive diagonal\r\n * const sectionPlane2 = new SectionPlane(viewer.scene, {\r\n * pos: [-1.0, -1.0, -1.0],\r\n * dir: [1.0, 1.0, 1.0],\r\n * active: true\r\n * });\r\n * ````\r\n */\r\nclass SectionPlane extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\r\n\t/**\r\n @private\r\n */\r\n\tget type() {\r\n\t\treturn \"SectionPlane\";\r\n\t}\r\n\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Component} [owner] Owner component. When destroyed, the owner will destroy this SectionPlane as well.\r\n\t * @param {*} [cfg] SectionPlane configuration\r\n\t * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\r\n\t * @param {Boolean} [cfg.active=true] Indicates whether or not this SectionPlane is active.\r\n\t * @param {Number[]} [cfg.pos=[0,0,0]] World-space position of the SectionPlane.\r\n\t * @param {Number[]} [cfg.dir=[0,0,-1]] Vector perpendicular to the plane surface, indicating the SectionPlane plane orientation.\r\n\t */\r\n\tconstructor(owner, cfg = {}) {\r\n\t\tsuper(owner, cfg);\r\n\r\n\t\tthis._state = new _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_1__.RenderState({\r\n\t\t\tactive: true,\r\n\t\t\tpos: _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3(),\r\n\t\t\tdir: _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3(),\r\n\t\t\tdist: 0\r\n\t\t});\r\n\r\n\t\tthis.active = cfg.active;\r\n\t\tthis.pos = cfg.pos;\r\n\t\tthis.dir = cfg.dir;\r\n\r\n\t\tthis.scene._sectionPlaneCreated(this);\r\n\t}\r\n\r\n\tset control(control) {\r\n\t\tthis._control = control;\r\n\t}\r\n\r\n\tget control() {\r\n\t\treturn this._control;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets if this SectionPlane is active or not.\r\n\t *\r\n\t * Default value is ````true````.\r\n\t *\r\n\t * @param {Boolean} value Set ````true```` to activate else ````false```` to deactivate.\r\n\t */\r\n\tset active(value) {\r\n\t\tthis._state.active = value !== false;\r\n\t\tthis.glRedraw();\r\n\t\tthis.fire(\"active\", this._state.active);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets if this SectionPlane is active or not.\r\n\t *\r\n\t * Default value is ````true````.\r\n\t *\r\n\t * @returns {Boolean} Returns ````true```` if active.\r\n\t */\r\n\tget active() {\r\n\t\treturn this._state.active;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the World-space position of this SectionPlane's plane.\r\n\t *\r\n\t * Default value is ````[0, 0, 0]````.\r\n\t *\r\n\t * @param {Number[]} value New position.\r\n\t */\r\n\tset pos(value) {\r\n\t\tthis._state.pos.set(value || [0, 0, 0]);\r\n\t\tthis._state.dist = -_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.dotVec3(this._state.pos, this._state.dir);\r\n\t\tthis.fire(\"pos\", this._state.pos);\r\n\t\tthis.scene.fire(\"sectionPlaneUpdated\", this);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the World-space position of this SectionPlane's plane.\r\n\t *\r\n\t * Default value is ````[0, 0, 0]````.\r\n\t *\r\n\t * @returns {Number[]} Current position.\r\n\t */\r\n\tget pos() {\r\n\t\treturn this._state.pos;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the direction of this SectionPlane's plane.\r\n\t *\r\n\t * Default value is ````[0, 0, -1]````.\r\n\t *\r\n\t * @param {Number[]} value New direction.\r\n\t */\r\n\tset dir(value) {\r\n\t\tthis._state.dir.set(value || [0, 0, -1]);\r\n\t\tthis._state.dist = -_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.dotVec3(this._state.pos, this._state.dir);\r\n\t\tthis.glRedraw();\r\n\t\tthis.fire(\"dir\", this._state.dir);\r\n\t\tthis.scene.fire(\"sectionPlaneUpdated\", this);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the direction of this SectionPlane's plane.\r\n\t *\r\n\t * Default value is ````[0, 0, -1]````.\r\n\t *\r\n\t * @returns {Number[]} value Current direction.\r\n\t */\r\n\tget dir() {\r\n\t\treturn this._state.dir;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets this SectionPlane's distance to the origin of the World-space coordinate system.\r\n\t *\r\n\t * This is the dot product of {@link SectionPlane#pos} and {@link SectionPlane#dir} and is automatically re-calculated\r\n\t * each time either of two properties are updated.\r\n\t *\r\n\t * @returns {Number}\r\n\t */\r\n\tget dist() {\r\n\t\treturn this._state.dist;\r\n\t}\r\n\r\n\t/**\r\n\t * Inverts the direction of {@link SectionPlane#dir}.\r\n\t */\r\n\tflipDir() {\r\n\t\tconst dir = this._state.dir;\r\n\t\tdir[0] *= -1.0;\r\n\t\tdir[1] *= -1.0;\r\n\t\tdir[2] *= -1.0;\r\n\t\tthis._state.dist = -_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.dotVec3(this._state.pos, this._state.dir);\r\n\t\tthis.fire(\"dir\", this._state.dir);\r\n\t\tthis.glRedraw();\r\n\t}\r\n\r\n\t/**\r\n\t * @destroy\r\n\t */\r\n\tdestroy() {\r\n\t\tthis._state.destroy();\r\n\t\tthis.scene._sectionPlaneDestroyed(this);\r\n\t\tsuper.destroy();\r\n\t}\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/sectionPlane/SectionPlane.js?");
4857
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SectionPlane: () => (/* binding */ SectionPlane)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../webgl/RenderState.js */ \"./src/viewer/scene/webgl/RenderState.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n\n\n\n\nconst tempVec3a = _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3();\n\n/**\n * @desc An arbitrarily-aligned World-space clipping plane.\n *\n * * Slices portions off objects to create cross-section views or reveal interiors.\n * * Registered by {@link SectionPlane#id} in {@link Scene#sectionPlanes}.\n * * Indicates World-space position in {@link SectionPlane#pos} and orientation in {@link SectionPlane#dir}.\n * * Discards elements from the half-space in the direction of {@link SectionPlane#dir}.\n * * Can be be enabled or disabled via {@link SectionPlane#active}.\n *\n * ## Usage\n *\n * In the example below, we'll create two SectionPlanes to slice a model loaded from glTF. Note that we could also create them\n * using a {@link SectionPlanesPlugin}.\n *\n * ````javascript\n * import {Viewer, GLTFLoaderPlugin, SectionPlane} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n * canvasId: \"myCanvas\"\n * });\n *\n * const gltfLoaderPlugin = new GLTFModelsPlugin(viewer, {\n * id: \"GLTFModels\"\n * });\n *\n * const model = gltfLoaderPlugin.load({\n * id: \"myModel\",\n * src: \"./models/gltf/mygltfmodel.gltf\"\n * });\n *\n * // Create a SectionPlane on negative diagonal\n * const sectionPlane1 = new SectionPlane(viewer.scene, {\n * pos: [1.0, 1.0, 1.0],\n * dir: [-1.0, -1.0, -1.0],\n * active: true\n * }),\n *\n * // Create a SectionPlane on positive diagonal\n * const sectionPlane2 = new SectionPlane(viewer.scene, {\n * pos: [-1.0, -1.0, -1.0],\n * dir: [1.0, 1.0, 1.0],\n * active: true\n * });\n * ````\n */\nclass SectionPlane extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\n\t/**\n @private\n */\n\tget type() {\n\t\treturn \"SectionPlane\";\n\t}\n\n\t/**\n\t * @constructor\n\t * @param {Component} [owner] Owner component. When destroyed, the owner will destroy this SectionPlane as well.\n\t * @param {*} [cfg] SectionPlane configuration\n\t * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n\t * @param {Boolean} [cfg.active=true] Indicates whether or not this SectionPlane is active.\n\t * @param {Number[]} [cfg.pos=[0,0,0]] World-space position of the SectionPlane.\n\t * @param {Number[]} [cfg.dir=[0,0,-1]] Vector perpendicular to the plane surface, indicating the SectionPlane plane orientation.\n\t */\n\tconstructor(owner, cfg = {}) {\n\t\tsuper(owner, cfg);\n\n\t\tthis._state = new _webgl_RenderState_js__WEBPACK_IMPORTED_MODULE_1__.RenderState({\n\t\t\tactive: true,\n\t\t\tpos: _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3(),\n\t\t\tdir: _math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.vec3(),\n\t\t\tdist: 0\n\t\t});\n\n\t\tthis.active = cfg.active;\n\t\tthis.pos = cfg.pos;\n\t\tthis.dir = cfg.dir;\n\n\t\tthis.scene._sectionPlaneCreated(this);\n\t}\n\n\tset control(control) {\n\t\tthis._control = control;\n\t}\n\n\tget control() {\n\t\treturn this._control;\n\t}\n\n\t/**\n\t * Sets if this SectionPlane is active or not.\n\t *\n\t * Default value is ````true````.\n\t *\n\t * @param {Boolean} value Set ````true```` to activate else ````false```` to deactivate.\n\t */\n\tset active(value) {\n\t\tthis._state.active = value !== false;\n\t\tthis.glRedraw();\n\t\tthis.fire(\"active\", this._state.active);\n\t}\n\n\t/**\n\t * Gets if this SectionPlane is active or not.\n\t *\n\t * Default value is ````true````.\n\t *\n\t * @returns {Boolean} Returns ````true```` if active.\n\t */\n\tget active() {\n\t\treturn this._state.active;\n\t}\n\n\t/**\n\t * Sets the World-space position of this SectionPlane's plane.\n\t *\n\t * Default value is ````[0, 0, 0]````.\n\t *\n\t * @param {Number[]} value New position.\n\t */\n\tset pos(value) {\n\t\tthis._state.pos.set(value || [0, 0, 0]);\n\t\tthis._state.dist = -_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.dotVec3(this._state.pos, this._state.dir);\n\t\tthis.fire(\"pos\", this._state.pos);\n\t\tthis.scene.fire(\"sectionPlaneUpdated\", this);\n\t}\n\n\t/**\n\t * Gets the World-space position of this SectionPlane's plane.\n\t *\n\t * Default value is ````[0, 0, 0]````.\n\t *\n\t * @returns {Number[]} Current position.\n\t */\n\tget pos() {\n\t\treturn this._state.pos;\n\t}\n\n\t/**\n\t * Sets the direction of this SectionPlane's plane.\n\t *\n\t * Default value is ````[0, 0, -1]````.\n\t *\n\t * @param {Number[]} value New direction.\n\t */\n\tset dir(value) {\n\t\tthis._state.dir.set(value || [0, 0, -1]);\n\t\tthis._state.dist = -_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.dotVec3(this._state.pos, this._state.dir);\n\t\tthis.glRedraw();\n\t\tthis.fire(\"dir\", this._state.dir);\n\t\tthis.scene.fire(\"sectionPlaneUpdated\", this);\n\t}\n\n\t/**\n\t * Gets the direction of this SectionPlane's plane.\n\t *\n\t * Default value is ````[0, 0, -1]````.\n\t *\n\t * @returns {Number[]} value Current direction.\n\t */\n\tget dir() {\n\t\treturn this._state.dir;\n\t}\n\n\t/**\n\t * Gets this SectionPlane's distance to the origin of the World-space coordinate system.\n\t *\n\t * This is the dot product of {@link SectionPlane#pos} and {@link SectionPlane#dir} and is automatically re-calculated\n\t * each time either of two properties are updated.\n\t *\n\t * @returns {Number}\n\t */\n\tget dist() {\n\t\treturn this._state.dist;\n\t}\n\n\t/**\n\t * Inverts the direction of {@link SectionPlane#dir}.\n\t */\n\tflipDir() {\n\t\tconst dir = this._state.dir;\n\t\tdir[0] *= -1.0;\n\t\tdir[1] *= -1.0;\n\t\tdir[2] *= -1.0;\n\t\tthis._state.dist = -_math_math_js__WEBPACK_IMPORTED_MODULE_2__.math.dotVec3(this._state.pos, this._state.dir);\n\t\tthis.fire(\"dir\", this._state.dir);\n\t\tthis.glRedraw();\n\t}\n\n\t/**\n\t * @destroy\n\t */\n\tdestroy() {\n\t\tthis._state.destroy();\n\t\tthis.scene._sectionPlaneDestroyed(this);\n\t\tsuper.destroy();\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/sectionPlane/SectionPlane.js?");
4838
4858
 
4839
4859
  /***/ }),
4840
4860
 
@@ -4854,7 +4874,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
4854
4874
  \*******************************************/
4855
4875
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4856
4876
 
4857
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Skybox: () => (/* binding */ Skybox)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _materials_Texture_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../materials/Texture.js */ \"./src/viewer/scene/materials/Texture.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * @desc A Skybox.\r\n */\r\nclass Skybox extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\r\n\r\n /**\r\n * @constructor\r\n * @param {Component} owner Owner component. When destroyed, the owner will destroy this PointLight as well.\r\n * @param {*} [cfg] Skybox configuration\r\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent {Scene}, generated automatically when omitted.\r\n * @param {String} [cfg.src=null] Path to skybox texture\r\n * @param {String} [cfg.encoding=\"linear\"] Texture encoding format. See the {@link Texture#encoding} property for more info.\r\n * @param {Number} [cfg.size=1000] Size of this Skybox, given as the distance from the center at ````[0,0,0]```` to each face.\r\n * @param {Boolean} [cfg.active=true] True when this Skybox is visible.\r\n */\r\n constructor(owner, cfg = {}) {\r\n\r\n super(owner, cfg);\r\n\r\n this._skyboxMesh = new _mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_1__.Mesh(this, {\r\n\r\n geometry: new _geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_2__.ReadableGeometry(this, { // Box-shaped geometry\r\n primitive: \"triangles\",\r\n positions: [\r\n 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // v0-v1-v2-v3 front\r\n 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // v0-v3-v4-v5 right\r\n 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // v0-v5-v6-v1 top\r\n -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // v1-v6-v7-v2 left\r\n -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // v7-v4-v3-v2 bottom\r\n 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1 // v4-v7-v6-v5 back\r\n ],\r\n uv: [\r\n 0.5, 0.6666, 0.25, 0.6666, 0.25, 0.3333, 0.5, 0.3333, 0.5, 0.6666, 0.5, 0.3333, 0.75, 0.3333, 0.75, 0.6666,\r\n 0.5, 0.6666, 0.5, 1, 0.25, 1, 0.25, 0.6666, 0.25, 0.6666, 0.0, 0.6666, 0.0, 0.3333, 0.25, 0.3333,\r\n 0.25, 0, 0.50, 0, 0.50, 0.3333, 0.25, 0.3333, 0.75, 0.3333, 1.0, 0.3333, 1.0, 0.6666, 0.75, 0.6666\r\n ],\r\n indices: [\r\n 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11,\r\n 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23\r\n ]\r\n }),\r\n background: true,\r\n scale: [2000, 2000, 2000], // Overridden when we initialize the 'size' property, below\r\n rotation: [0, -90, 0],\r\n material: new _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_3__.PhongMaterial(this, {\r\n ambient: [0, 0, 0],\r\n diffuse: [0, 0, 0],\r\n specular: [0, 0, 0],\r\n emissive: [1, 1, 1],\r\n emissiveMap: new _materials_Texture_js__WEBPACK_IMPORTED_MODULE_4__.Texture(this, {\r\n src: cfg.src,\r\n flipY: true,\r\n wrapS: \"clampToEdge\",\r\n wrapT: \"clampToEdge\",\r\n encoding: cfg.encoding || \"sRGB\"\r\n }),\r\n backfaces: true // Show interior faces of our skybox geometry\r\n }),\r\n // stationary: true,\r\n visible: false,\r\n pickable: false,\r\n clippable: false,\r\n collidable: false\r\n });\r\n\r\n this.size = cfg.size; // Sets 'xyz' property on the Mesh's Scale transform\r\n this.active = cfg.active;\r\n }\r\n\r\n\r\n /**\r\n * Sets the size of this Skybox, given as the distance from the center at [0,0,0] to each face.\r\n *\r\n * Default value is ````1000````.\r\n *\r\n * @param {Number} value The size.\r\n */\r\n set size(value) {\r\n this._size = value || 1000;\r\n this._skyboxMesh.scale = [this._size, this._size, this._size];\r\n }\r\n\r\n /**\r\n * Gets the size of this Skybox, given as the distance from the center at [0,0,0] to each face.\r\n *\r\n * Default value is ````1000````.\r\n *\r\n * @returns {Number} The size.\r\n */\r\n get size() {\r\n return this._size;\r\n }\r\n\r\n /**\r\n * Sets whether this Skybox is visible or not.\r\n *\r\n * Default value is ````true````.\r\n *\r\n * @param {Boolean} active Whether to make active or not.\r\n */\r\n set active(active) {\r\n this._skyboxMesh.visible = active;\r\n }\r\n\r\n /**\r\n * Gets if this Skybox is visible or not.\r\n *\r\n * Default active is ````true````.\r\n *\r\n * @returns {Boolean} ````true```` if the Skybox is active.\r\n */\r\n get active() {\r\n return this._skyboxMesh.visible;\r\n }\r\n}\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/skybox/Skybox.js?");
4877
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Skybox: () => (/* binding */ Skybox)\n/* harmony export */ });\n/* harmony import */ var _Component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Component.js */ \"./src/viewer/scene/Component.js\");\n/* harmony import */ var _mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh/Mesh.js */ \"./src/viewer/scene/mesh/Mesh.js\");\n/* harmony import */ var _geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry/ReadableGeometry.js */ \"./src/viewer/scene/geometry/ReadableGeometry.js\");\n/* harmony import */ var _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../materials/PhongMaterial.js */ \"./src/viewer/scene/materials/PhongMaterial.js\");\n/* harmony import */ var _materials_Texture_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../materials/Texture.js */ \"./src/viewer/scene/materials/Texture.js\");\n\n\n\n\n\n\n/**\n * @desc A Skybox.\n */\nclass Skybox extends _Component_js__WEBPACK_IMPORTED_MODULE_0__.Component {\n\t/**\n\t * @constructor\n\t * @param {Component} owner Owner component. When destroyed, the owner will destroy this PointLight as well.\n\t * @param {*} [cfg] Skybox configuration\n\t * @param {String} [cfg.id] Optional ID, unique among all components in the parent {Scene}, generated automatically when omitted.\n\t * @param {String} [cfg.src=null] Path to skybox texture\n\t * @param {String} [cfg.encoding=\"linear\"] Texture encoding format. See the {@link Texture#encoding} property for more info.\n\t * @param {Number} [cfg.size=1000] Size of this Skybox, given as the distance from the center at ````[0,0,0]```` to each face.\n\t * @param {Boolean} [cfg.active=true] True when this Skybox is visible.\n\t */\n\tconstructor(owner, cfg = {}) {\n\t\tsuper(owner, cfg);\n\n\t\tthis._skyboxMesh = new _mesh_Mesh_js__WEBPACK_IMPORTED_MODULE_1__.Mesh(this, {\n\t\t\tgeometry: new _geometry_ReadableGeometry_js__WEBPACK_IMPORTED_MODULE_2__.ReadableGeometry(this, {\n\t\t\t\t// Box-shaped geometry\n\t\t\t\tprimitive: \"triangles\",\n\t\t\t\tpositions: [\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1, // v0-v1-v2-v3 front\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1, // v0-v3-v4-v5 right\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t1, // v0-v5-v6-v1 top\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1, // v1-v6-v7-v2 left\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1, // v7-v4-v3-v2 bottom\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t\t-1 // v4-v7-v6-v5 back\n\t\t\t\t],\n\t\t\t\tuv: [\n\t\t\t\t\t0.5, 0.6666, 0.25, 0.6666, 0.25, 0.3333, 0.5, 0.3333, 0.5, 0.6666, 0.5, 0.3333, 0.75, 0.3333, 0.75, 0.6666,\n\t\t\t\t\t0.5, 0.6666, 0.5, 1, 0.25, 1, 0.25, 0.6666, 0.25, 0.6666, 0.0, 0.6666, 0.0, 0.3333, 0.25, 0.3333, 0.25, 0,\n\t\t\t\t\t0.5, 0, 0.5, 0.3333, 0.25, 0.3333, 0.75, 0.3333, 1.0, 0.3333, 1.0, 0.6666, 0.75, 0.6666\n\t\t\t\t],\n\t\t\t\tindices: [\n\t\t\t\t\t0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20,\n\t\t\t\t\t21, 22, 20, 22, 23\n\t\t\t\t]\n\t\t\t}),\n\t\t\tbackground: true,\n\t\t\tscale: [2000, 2000, 2000], // Overridden when we initialize the 'size' property, below\n\t\t\trotation: [0, -90, 0],\n\t\t\tmaterial: new _materials_PhongMaterial_js__WEBPACK_IMPORTED_MODULE_3__.PhongMaterial(this, {\n\t\t\t\tambient: [0, 0, 0],\n\t\t\t\tdiffuse: [0, 0, 0],\n\t\t\t\tspecular: [0, 0, 0],\n\t\t\t\temissive: [1, 1, 1],\n\t\t\t\temissiveMap: new _materials_Texture_js__WEBPACK_IMPORTED_MODULE_4__.Texture(this, {\n\t\t\t\t\tscale: cfg.scale,\n\t\t\t\t\tsrc: cfg.src,\n\t\t\t\t\tflipY: true,\n\t\t\t\t\twrapS: 1000,\n\t\t\t\t\twrapT: 1000,\n\t\t\t\t\tencoding: cfg.encoding || \"sRGB\"\n\t\t\t\t}),\n\t\t\t\tbackfaces: true // Show interior faces of our skybox geometry\n\t\t\t}),\n\t\t\t// stationary: true,\n\t\t\tvisible: false,\n\t\t\tpickable: false,\n\t\t\tclippable: false,\n\t\t\tcollidable: false\n\t\t});\n\n\t\tthis.size = cfg.size; // Sets 'xyz' property on the Mesh's Scale transform\n\t\tthis.active = cfg.active;\n\t}\n\n\t/**\n\t * Sets the size of this Skybox, given as the distance from the center at [0,0,0] to each face.\n\t *\n\t * Default value is ````1000````.\n\t *\n\t * @param {Number} value The size.\n\t */\n\tset size(value) {\n\t\tthis._size = value || 1000;\n\t\tthis._skyboxMesh.scale = [this._size, this._size, this._size];\n\t}\n\n\t/**\n\t * Gets the size of this Skybox, given as the distance from the center at [0,0,0] to each face.\n\t *\n\t * Default value is ````1000````.\n\t *\n\t * @returns {Number} The size.\n\t */\n\tget size() {\n\t\treturn this._size;\n\t}\n\n\t/**\n\t * Sets whether this Skybox is visible or not.\n\t *\n\t * Default value is ````true````.\n\t *\n\t * @param {Boolean} active Whether to make active or not.\n\t */\n\tset active(active) {\n\t\tthis._skyboxMesh.visible = active;\n\t}\n\n\t/**\n\t * Gets if this Skybox is visible or not.\n\t *\n\t * Default active is ````true````.\n\t *\n\t * @returns {Boolean} ````true```` if the Skybox is active.\n\t */\n\tget active() {\n\t\treturn this._skyboxMesh.visible;\n\t}\n}\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/skybox/Skybox.js?");
4858
4878
 
4859
4879
  /***/ }),
4860
4880
 
@@ -5124,7 +5144,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
5124
5144
  \********************************************/
5125
5145
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
5126
5146
 
5127
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Renderer: () => (/* binding */ Renderer)\n/* harmony export */ });\n/* harmony import */ var _FrameContext_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./FrameContext.js */ \"./src/viewer/scene/webgl/FrameContext.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _stats_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../stats.js */ \"./src/viewer/scene/stats.js\");\n/* harmony import */ var _webglInfo_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../webglInfo.js */ \"./src/viewer/scene/webglInfo.js\");\n/* harmony import */ var _utils_Map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/Map.js */ \"./src/viewer/scene/utils/Map.js\");\n/* harmony import */ var _PickResult_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./PickResult.js */ \"./src/viewer/scene/webgl/PickResult.js\");\n/* harmony import */ var _occlusion_OcclusionTester_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./occlusion/OcclusionTester.js */ \"./src/viewer/scene/webgl/occlusion/OcclusionTester.js\");\n/* harmony import */ var _sao_SAOOcclusionRenderer_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./sao/SAOOcclusionRenderer.js */ \"./src/viewer/scene/webgl/sao/SAOOcclusionRenderer.js\");\n/* harmony import */ var _math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n/* harmony import */ var _sao_SAODepthLimitedBlurRenderer_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./sao/SAODepthLimitedBlurRenderer.js */ \"./src/viewer/scene/webgl/sao/SAODepthLimitedBlurRenderer.js\");\n/* harmony import */ var _RenderBufferManager_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./RenderBufferManager.js */ \"./src/viewer/scene/webgl/RenderBufferManager.js\");\n/* harmony import */ var _getExtension_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./getExtension.js */ \"./src/viewer/scene/webgl/getExtension.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * @private\r\n */\r\nconst Renderer = function (scene, options) {\r\n\r\n options = options || {};\r\n\r\n const frameCtx = new _FrameContext_js__WEBPACK_IMPORTED_MODULE_0__.FrameContext(scene);\r\n const canvas = scene.canvas.canvas;\r\n /**\r\n * @type {WebGL2RenderingContext}\r\n */\r\n const gl = scene.canvas.gl;\r\n let canvasTransparent = (!!options.transparent);\r\n const alphaDepthMask = options.alphaDepthMask;\r\n\r\n const pickIDs = new _utils_Map_js__WEBPACK_IMPORTED_MODULE_4__.Map({});\r\n\r\n let drawableTypeInfo = {};\r\n let drawables = {};\r\n\r\n let drawableListDirty = true;\r\n let stateSortDirty = true;\r\n let imageDirty = true;\r\n let shadowsDirty = true;\r\n\r\n let transparentEnabled = true;\r\n let edgesEnabled = (!!options.edgesEnabled);\r\n let saoEnabled = true;\r\n let pbrEnabled = true;\r\n let colorTextureEnabled = true;\r\n\r\n const renderBufferManager = new _RenderBufferManager_js__WEBPACK_IMPORTED_MODULE_10__.RenderBufferManager(scene);\r\n\r\n let snapshotBound = false;\r\n\r\n const bindOutputFrameBuffer = null;\r\n const unbindOutputFrameBuffer = null;\r\n\r\n const saoOcclusionRenderer = new _sao_SAOOcclusionRenderer_js__WEBPACK_IMPORTED_MODULE_7__.SAOOcclusionRenderer(scene);\r\n const saoDepthLimitedBlurRenderer = new _sao_SAODepthLimitedBlurRenderer_js__WEBPACK_IMPORTED_MODULE_9__.SAODepthLimitedBlurRenderer(scene);\r\n\r\n this.scene = scene;\r\n\r\n this._occlusionTester = null; // Lazy-created in #addMarker()\r\n\r\n this.capabilities = {\r\n astcSupported: !!(0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, 'WEBGL_compressed_texture_astc'),\r\n etc1Supported: true, // WebGL2\r\n etc2Supported: !!(0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, 'WEBGL_compressed_texture_etc'),\r\n dxtSupported: !!(0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, 'WEBGL_compressed_texture_s3tc'),\r\n bptcSupported: !!(0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, 'EXT_texture_compression_bptc'),\r\n pvrtcSupported: !!((0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, 'WEBGL_compressed_texture_pvrtc') || (0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, 'WEBKIT_WEBGL_compressed_texture_pvrtc'))\r\n };\r\n\r\n this.setTransparentEnabled = function (enabled) {\r\n transparentEnabled = enabled;\r\n canvasTransparent = enabled\r\n imageDirty = true;\r\n };\r\n\r\n this.setEdgesEnabled = function (enabled) {\r\n edgesEnabled = enabled;\r\n imageDirty = true;\r\n };\r\n\r\n this.setSAOEnabled = function (enabled) {\r\n saoEnabled = enabled;\r\n imageDirty = true;\r\n };\r\n\r\n this.setPBREnabled = function (enabled) {\r\n pbrEnabled = enabled;\r\n imageDirty = true;\r\n };\r\n\r\n this.setColorTextureEnabled = function (enabled) {\r\n colorTextureEnabled = enabled;\r\n imageDirty = true;\r\n };\r\n\r\n this.needStateSort = function () {\r\n stateSortDirty = true;\r\n };\r\n\r\n this.shadowsDirty = function () {\r\n shadowsDirty = true;\r\n };\r\n\r\n this.imageDirty = function () {\r\n imageDirty = true;\r\n };\r\n\r\n this.webglContextLost = function () {\r\n };\r\n\r\n this.webglContextRestored = function (gl) {\r\n\r\n // renderBufferManager.webglContextRestored(gl);\r\n\r\n saoOcclusionRenderer.init();\r\n saoDepthLimitedBlurRenderer.init();\r\n\r\n imageDirty = true;\r\n };\r\n\r\n /**\r\n * Inserts a drawable into this renderer.\r\n * @private\r\n */\r\n this.addDrawable = function (id, drawable) {\r\n const type = drawable.type;\r\n if (!type) {\r\n console.error(\"Renderer#addDrawable() : drawable with ID \" + id + \" has no 'type' - ignoring\");\r\n return;\r\n }\r\n let drawableInfo = drawableTypeInfo[type];\r\n if (!drawableInfo) {\r\n drawableInfo = {\r\n type: drawable.type,\r\n count: 0,\r\n isStateSortable: drawable.isStateSortable,\r\n stateSortCompare: drawable.stateSortCompare,\r\n drawableMap: {},\r\n drawableListPreCull: [],\r\n drawableList: []\r\n };\r\n drawableTypeInfo[type] = drawableInfo;\r\n }\r\n drawableInfo.count++;\r\n drawableInfo.drawableMap[id] = drawable;\r\n drawables[id] = drawable;\r\n drawableListDirty = true;\r\n };\r\n\r\n /**\r\n * Removes a drawable from this renderer.\r\n * @private\r\n */\r\n this.removeDrawable = function (id) {\r\n const drawable = drawables[id];\r\n if (!drawable) {\r\n console.error(\"Renderer#removeDrawable() : drawable not found with ID \" + id + \" - ignoring\");\r\n return;\r\n }\r\n const type = drawable.type;\r\n const drawableInfo = drawableTypeInfo[type];\r\n if (--drawableInfo.count <= 0) {\r\n delete drawableTypeInfo[type];\r\n } else {\r\n delete drawableInfo.drawableMap[id];\r\n }\r\n delete drawables[id];\r\n drawableListDirty = true;\r\n };\r\n\r\n /**\r\n * Gets a unique pick ID for the given Pickable. A Pickable can be a {@link Mesh} or a {@link PerformanceMesh}.\r\n * @returns {Number} New pick ID.\r\n */\r\n this.getPickID = function (entity) {\r\n return pickIDs.addItem(entity);\r\n };\r\n\r\n /**\r\n * Released a pick ID for reuse.\r\n * @param {Number} pickID Pick ID to release.\r\n */\r\n this.putPickID = function (pickID) {\r\n pickIDs.removeItem(pickID);\r\n };\r\n\r\n /**\r\n * Clears the canvas.\r\n * @private\r\n */\r\n this.clear = function (params) {\r\n params = params || {};\r\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\r\n if (canvasTransparent) {\r\n gl.clearColor(1, 1, 1, 0);\r\n } else {\r\n const backgroundColor = scene.canvas.backgroundColorFromAmbientLight ? this.lights.getAmbientColorAndIntensity() : scene.canvas.backgroundColor;\r\n gl.clearColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], 1.0);\r\n }\r\n if (bindOutputFrameBuffer) {\r\n bindOutputFrameBuffer(params.pass);\r\n }\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\r\n if (unbindOutputFrameBuffer) {\r\n unbindOutputFrameBuffer(params.pass);\r\n }\r\n };\r\n\r\n /**\r\n * Returns true if the next call to render() will draw something\r\n * @returns {Boolean}\r\n */\r\n this.needsRender = function () {\r\n const needsRender = (imageDirty || drawableListDirty || stateSortDirty);\r\n return needsRender;\r\n }\r\n\r\n /**\r\n * Renders inserted drawables.\r\n * @private\r\n */\r\n this.render = function (params) {\r\n params = params || {};\r\n if (params.force) {\r\n imageDirty = true;\r\n }\r\n updateDrawlist();\r\n if (imageDirty) {\r\n draw(params);\r\n _stats_js__WEBPACK_IMPORTED_MODULE_2__.stats.frame.frameCount++;\r\n imageDirty = false;\r\n }\r\n };\r\n\r\n function updateDrawlist() { // Prepares state-sorted array of drawables from maps of inserted drawables\r\n if (drawableListDirty) {\r\n buildDrawableList();\r\n drawableListDirty = false;\r\n stateSortDirty = true;\r\n }\r\n if (stateSortDirty) {\r\n sortDrawableList();\r\n stateSortDirty = false;\r\n imageDirty = true;\r\n }\r\n if (imageDirty) { // Image is usually dirty because the camera moved\r\n cullDrawableList();\r\n }\r\n }\r\n\r\n function buildDrawableList() {\r\n for (let type in drawableTypeInfo) {\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n const drawableInfo = drawableTypeInfo[type];\r\n const drawableMap = drawableInfo.drawableMap;\r\n const drawableListPreCull = drawableInfo.drawableListPreCull;\r\n let lenDrawableList = 0;\r\n for (let id in drawableMap) {\r\n if (drawableMap.hasOwnProperty(id)) {\r\n drawableListPreCull[lenDrawableList++] = drawableMap[id];\r\n }\r\n }\r\n drawableListPreCull.length = lenDrawableList;\r\n }\r\n }\r\n }\r\n\r\n function sortDrawableList() {\r\n for (let type in drawableTypeInfo) {\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n const drawableInfo = drawableTypeInfo[type];\r\n if (drawableInfo.isStateSortable) {\r\n drawableInfo.drawableListPreCull.sort(drawableInfo.stateSortCompare);\r\n }\r\n }\r\n }\r\n }\r\n\r\n function cullDrawableList() {\r\n for (let type in drawableTypeInfo) {\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n const drawableInfo = drawableTypeInfo[type];\r\n const drawableListPreCull = drawableInfo.drawableListPreCull;\r\n const drawableList = drawableInfo.drawableList;\r\n let lenDrawableList = 0;\r\n for (let i = 0, len = drawableListPreCull.length; i < len; i++) {\r\n const drawable = drawableListPreCull[i];\r\n drawable.rebuildRenderFlags();\r\n if (!drawable.renderFlags.culled) {\r\n drawableList[lenDrawableList++] = drawable;\r\n }\r\n }\r\n drawableList.length = lenDrawableList;\r\n }\r\n }\r\n }\r\n\r\n function draw(params) {\r\n\r\n const sao = scene.sao;\r\n\r\n if (saoEnabled && sao.possible) {\r\n drawSAOBuffers(params);\r\n }\r\n\r\n drawShadowMaps();\r\n\r\n drawColor(params);\r\n }\r\n\r\n function drawSAOBuffers(params) {\r\n\r\n const sao = scene.sao;\r\n\r\n // Render depth buffer\r\n\r\n const saoDepthRenderBuffer = renderBufferManager.getRenderBuffer(\"saoDepth\", {\r\n depthTexture: true\r\n });\r\n\r\n saoDepthRenderBuffer.bind();\r\n saoDepthRenderBuffer.clear();\r\n drawDepth(params);\r\n saoDepthRenderBuffer.unbind();\r\n\r\n // Render occlusion buffer\r\n\r\n const occlusionRenderBuffer1 = renderBufferManager.getRenderBuffer(\"saoOcclusion\");\r\n\r\n occlusionRenderBuffer1.bind();\r\n occlusionRenderBuffer1.clear();\r\n saoOcclusionRenderer.render(saoDepthRenderBuffer);\r\n occlusionRenderBuffer1.unbind();\r\n\r\n if (sao.blur) {\r\n\r\n // Horizontally blur occlusion buffer 1 into occlusion buffer 2\r\n\r\n const occlusionRenderBuffer2 = renderBufferManager.getRenderBuffer(\"saoOcclusion2\");\r\n\r\n occlusionRenderBuffer2.bind();\r\n occlusionRenderBuffer2.clear();\r\n saoDepthLimitedBlurRenderer.render(saoDepthRenderBuffer, occlusionRenderBuffer1, 0);\r\n occlusionRenderBuffer2.unbind();\r\n\r\n // Vertically blur occlusion buffer 2 back into occlusion buffer 1\r\n\r\n occlusionRenderBuffer1.bind();\r\n occlusionRenderBuffer1.clear();\r\n saoDepthLimitedBlurRenderer.render(saoDepthRenderBuffer, occlusionRenderBuffer2, 1);\r\n occlusionRenderBuffer1.unbind();\r\n }\r\n }\r\n\r\n function drawDepth(params) {\r\n\r\n frameCtx.reset();\r\n frameCtx.pass = params.pass;\r\n\r\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\r\n\r\n gl.clearColor(0, 0, 0, 0);\r\n gl.enable(gl.DEPTH_TEST);\r\n gl.frontFace(gl.CCW);\r\n gl.enable(gl.CULL_FACE);\r\n gl.depthMask(true);\r\n\r\n if (params.clear !== false) {\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\r\n }\r\n\r\n for (let type in drawableTypeInfo) {\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n\r\n const drawableInfo = drawableTypeInfo[type];\r\n const drawableList = drawableInfo.drawableList;\r\n\r\n for (let i = 0, len = drawableList.length; i < len; i++) {\r\n\r\n const drawable = drawableList[i];\r\n\r\n if (drawable.culled === true || drawable.visible === false || !drawable.drawDepth || !drawable.saoEnabled) {\r\n continue;\r\n }\r\n\r\n if (drawable.renderFlags.colorOpaque) {\r\n drawable.drawDepth(frameCtx);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // const numVertexAttribs = WEBGL_INFO.MAX_VERTEX_ATTRIBS; // Fixes https://github.com/xeokit/xeokit-sdk/issues/174\r\n // for (let ii = 0; ii < numVertexAttribs; ii++) {\r\n // gl.disableVertexAttribArray(ii);\r\n // }\r\n\r\n }\r\n\r\n function drawShadowMaps() {\r\n\r\n let lights = scene._lightsState.lights;\r\n\r\n for (let i = 0, len = lights.length; i < len; i++) {\r\n const light = lights[i];\r\n if (!light.castsShadow) {\r\n continue;\r\n }\r\n drawShadowMap(light);\r\n }\r\n\r\n // const numVertexAttribs = WEBGL_INFO.MAX_VERTEX_ATTRIBS; // Fixes https://github.com/xeokit/xeokit-sdk/issues/174\r\n // for (let ii = 0; ii < numVertexAttribs; ii++) {\r\n // gl.disableVertexAttribArray(ii);\r\n // }\r\n //\r\n shadowsDirty = false;\r\n }\r\n\r\n function drawShadowMap(light) {\r\n\r\n const castsShadow = light.castsShadow;\r\n\r\n if (!castsShadow) {\r\n return;\r\n }\r\n\r\n const shadowRenderBuf = light.getShadowRenderBuf();\r\n\r\n if (!shadowRenderBuf) {\r\n return;\r\n }\r\n\r\n shadowRenderBuf.bind();\r\n\r\n frameCtx.reset();\r\n\r\n frameCtx.backfaces = true;\r\n frameCtx.frontface = true;\r\n frameCtx.shadowViewMatrix = light.getShadowViewMatrix();\r\n frameCtx.shadowProjMatrix = light.getShadowProjMatrix();\r\n\r\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\r\n\r\n gl.clearColor(0, 0, 0, 1);\r\n gl.enable(gl.DEPTH_TEST);\r\n gl.disable(gl.BLEND);\r\n\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\r\n\r\n for (let type in drawableTypeInfo) {\r\n\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n\r\n const drawableInfo = drawableTypeInfo[type];\r\n const drawableList = drawableInfo.drawableList;\r\n\r\n for (let i = 0, len = drawableList.length; i < len; i++) {\r\n\r\n const drawable = drawableList[i];\r\n\r\n if (drawable.visible === false || !drawable.castsShadow || !drawable.drawShadow) {\r\n continue;\r\n }\r\n\r\n if (drawable.renderFlags.colorOpaque) { // Transparent objects don't cast shadows (yet)\r\n drawable.drawShadow(frameCtx);\r\n }\r\n }\r\n }\r\n }\r\n\r\n shadowRenderBuf.unbind();\r\n }\r\n\r\n function drawColor(params) {\r\n\r\n const normalDrawSAOBin = [];\r\n const normalEdgesOpaqueBin = [];\r\n const normalFillTransparentBin = [];\r\n const normalEdgesTransparentBin = [];\r\n\r\n const xrayedFillOpaqueBin = [];\r\n const xrayEdgesOpaqueBin = [];\r\n const xrayedFillTransparentBin = [];\r\n const xrayEdgesTransparentBin = [];\r\n\r\n const highlightedFillOpaqueBin = [];\r\n const highlightedEdgesOpaqueBin = [];\r\n const highlightedFillTransparentBin = [];\r\n const highlightedEdgesTransparentBin = [];\r\n\r\n const selectedFillOpaqueBin = [];\r\n const selectedEdgesOpaqueBin = [];\r\n const selectedFillTransparentBin = [];\r\n const selectedEdgesTransparentBin = [];\r\n\r\n\r\n const ambientColorAndIntensity = scene._lightsState.getAmbientColorAndIntensity();\r\n\r\n frameCtx.reset();\r\n frameCtx.pass = params.pass;\r\n frameCtx.withSAO = false;\r\n frameCtx.pbrEnabled = pbrEnabled && !!scene.pbrEnabled;\r\n frameCtx.colorTextureEnabled = colorTextureEnabled && !!scene.colorTextureEnabled;\r\n\r\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\r\n\r\n if (canvasTransparent) {\r\n gl.clearColor(0, 0, 0, 0);\r\n } else {\r\n const backgroundColor = scene.canvas.backgroundColorFromAmbientLight ? ambientColorAndIntensity : scene.canvas.backgroundColor;\r\n gl.clearColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], 1.0);\r\n }\r\n\r\n gl.enable(gl.DEPTH_TEST);\r\n gl.frontFace(gl.CCW);\r\n gl.enable(gl.CULL_FACE);\r\n gl.depthMask(true);\r\n gl.lineWidth(1);\r\n\r\n frameCtx.lineWidth = 1;\r\n\r\n const saoPossible = scene.sao.possible;\r\n\r\n if (saoEnabled && saoPossible) {\r\n const occlusionRenderBuffer1 = renderBufferManager.getRenderBuffer(\"saoOcclusion\");\r\n frameCtx.occlusionTexture = occlusionRenderBuffer1 ? occlusionRenderBuffer1.getTexture() : null;\r\n } else {\r\n frameCtx.occlusionTexture = null;\r\n\r\n }\r\n\r\n let i;\r\n let len;\r\n let drawable;\r\n\r\n const startTime = Date.now();\r\n\r\n if (bindOutputFrameBuffer) {\r\n bindOutputFrameBuffer(params.pass);\r\n }\r\n\r\n if (params.clear !== false) {\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\r\n }\r\n\r\n let normalDrawSAOBinLen = 0;\r\n let normalEdgesOpaqueBinLen = 0;\r\n let normalFillTransparentBinLen = 0;\r\n let normalEdgesTransparentBinLen = 0;\r\n\r\n let xrayedFillOpaqueBinLen = 0;\r\n let xrayEdgesOpaqueBinLen = 0;\r\n let xrayedFillTransparentBinLen = 0;\r\n let xrayEdgesTransparentBinLen = 0;\r\n\r\n let highlightedFillOpaqueBinLen = 0;\r\n let highlightedEdgesOpaqueBinLen = 0;\r\n let highlightedFillTransparentBinLen = 0;\r\n let highlightedEdgesTransparentBinLen = 0;\r\n\r\n let selectedFillOpaqueBinLen = 0;\r\n let selectedEdgesOpaqueBinLen = 0;\r\n let selectedFillTransparentBinLen = 0;\r\n let selectedEdgesTransparentBinLen = 0;\r\n\r\n //------------------------------------------------------------------------------------------------------\r\n // Render normal opaque solids, defer others to bins to render after\r\n //------------------------------------------------------------------------------------------------------\r\n\r\n for (let type in drawableTypeInfo) {\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n\r\n const drawableInfo = drawableTypeInfo[type];\r\n const drawableList = drawableInfo.drawableList;\r\n\r\n for (i = 0, len = drawableList.length; i < len; i++) {\r\n\r\n drawable = drawableList[i];\r\n\r\n if (drawable.culled === true || drawable.visible === false) {\r\n continue;\r\n }\r\n\r\n const renderFlags = drawable.renderFlags;\r\n\r\n if (renderFlags.colorOpaque) {\r\n if (saoEnabled && saoPossible && drawable.saoEnabled) {\r\n normalDrawSAOBin[normalDrawSAOBinLen++] = drawable;\r\n } else {\r\n drawable.drawColorOpaque(frameCtx);\r\n }\r\n }\r\n\r\n if (transparentEnabled) {\r\n if (renderFlags.colorTransparent) {\r\n normalFillTransparentBin[normalFillTransparentBinLen++] = drawable;\r\n }\r\n }\r\n\r\n if (renderFlags.xrayedSilhouetteTransparent) {\r\n xrayedFillTransparentBin[xrayedFillTransparentBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.xrayedSilhouetteOpaque) {\r\n xrayedFillOpaqueBin[xrayedFillOpaqueBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.highlightedSilhouetteTransparent) {\r\n highlightedFillTransparentBin[highlightedFillTransparentBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.highlightedSilhouetteOpaque) {\r\n highlightedFillOpaqueBin[highlightedFillOpaqueBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.selectedSilhouetteTransparent) {\r\n selectedFillTransparentBin[selectedFillTransparentBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.selectedSilhouetteOpaque) {\r\n selectedFillOpaqueBin[selectedFillOpaqueBinLen++] = drawable;\r\n }\r\n\r\n if (drawable.edges && edgesEnabled) {\r\n if (renderFlags.edgesOpaque) {\r\n normalEdgesOpaqueBin[normalEdgesOpaqueBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.edgesTransparent) {\r\n normalEdgesTransparentBin[normalEdgesTransparentBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.selectedEdgesTransparent) {\r\n selectedEdgesTransparentBin[selectedEdgesTransparentBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.selectedEdgesOpaque) {\r\n selectedEdgesOpaqueBin[selectedEdgesOpaqueBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.xrayedEdgesTransparent) {\r\n xrayEdgesTransparentBin[xrayEdgesTransparentBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.xrayedEdgesOpaque) {\r\n xrayEdgesOpaqueBin[xrayEdgesOpaqueBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.highlightedEdgesTransparent) {\r\n highlightedEdgesTransparentBin[highlightedEdgesTransparentBinLen++] = drawable;\r\n }\r\n\r\n if (renderFlags.highlightedEdgesOpaque) {\r\n highlightedEdgesOpaqueBin[highlightedEdgesOpaqueBinLen++] = drawable;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n //------------------------------------------------------------------------------------------------------\r\n // Render deferred bins\r\n //------------------------------------------------------------------------------------------------------\r\n\r\n // Opaque color with SAO\r\n\r\n if (normalDrawSAOBinLen > 0) {\r\n frameCtx.withSAO = true;\r\n for (i = 0; i < normalDrawSAOBinLen; i++) {\r\n normalDrawSAOBin[i].drawColorOpaque(frameCtx);\r\n }\r\n }\r\n\r\n // Opaque edges\r\n\r\n if (normalEdgesOpaqueBinLen > 0) {\r\n for (i = 0; i < normalEdgesOpaqueBinLen; i++) {\r\n normalEdgesOpaqueBin[i].drawEdgesColorOpaque(frameCtx);\r\n }\r\n }\r\n\r\n // Opaque X-ray fill\r\n\r\n if (xrayedFillOpaqueBinLen > 0) {\r\n for (i = 0; i < xrayedFillOpaqueBinLen; i++) {\r\n xrayedFillOpaqueBin[i].drawSilhouetteXRayed(frameCtx);\r\n }\r\n }\r\n\r\n // Opaque X-ray edges\r\n\r\n if (xrayEdgesOpaqueBinLen > 0) {\r\n for (i = 0; i < xrayEdgesOpaqueBinLen; i++) {\r\n xrayEdgesOpaqueBin[i].drawEdgesXRayed(frameCtx);\r\n }\r\n }\r\n\r\n // Transparent\r\n\r\n if (xrayedFillTransparentBinLen > 0 || xrayEdgesTransparentBinLen > 0 || normalFillTransparentBinLen > 0 || normalEdgesTransparentBinLen > 0) {\r\n gl.enable(gl.CULL_FACE);\r\n gl.enable(gl.BLEND);\r\n if (canvasTransparent) {\r\n gl.blendEquation(gl.FUNC_ADD);\r\n gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n } else {\r\n gl.blendEquation(gl.FUNC_ADD);\r\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\r\n }\r\n frameCtx.backfaces = false;\r\n if (!alphaDepthMask) {\r\n gl.depthMask(false);\r\n }\r\n\r\n // Transparent color edges\r\n\r\n if (normalFillTransparentBinLen > 0 || normalEdgesTransparentBinLen > 0) {\r\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\r\n }\r\n if (normalEdgesTransparentBinLen > 0) {\r\n for (i = 0; i < normalEdgesTransparentBinLen; i++) {\r\n drawable = normalEdgesTransparentBin[i];\r\n drawable.drawEdgesColorTransparent(frameCtx);\r\n }\r\n }\r\n\r\n // Transparent color fill\r\n\r\n if (normalFillTransparentBinLen > 0) {\r\n for (i = 0; i < normalFillTransparentBinLen; i++) {\r\n drawable = normalFillTransparentBin[i];\r\n drawable.drawColorTransparent(frameCtx);\r\n }\r\n }\r\n\r\n // Transparent X-ray edges\r\n\r\n if (xrayEdgesTransparentBinLen > 0) {\r\n for (i = 0; i < xrayEdgesTransparentBinLen; i++) {\r\n xrayEdgesTransparentBin[i].drawEdgesXRayed(frameCtx);\r\n }\r\n }\r\n\r\n // Transparent X-ray fill\r\n\r\n if (xrayedFillTransparentBinLen > 0) {\r\n for (i = 0; i < xrayedFillTransparentBinLen; i++) {\r\n xrayedFillTransparentBin[i].drawSilhouetteXRayed(frameCtx);\r\n }\r\n }\r\n\r\n gl.disable(gl.BLEND);\r\n if (!alphaDepthMask) {\r\n gl.depthMask(true);\r\n }\r\n }\r\n\r\n // Opaque highlight\r\n\r\n if (highlightedFillOpaqueBinLen > 0 || highlightedEdgesOpaqueBinLen > 0) {\r\n frameCtx.lastProgramId = null;\r\n if (scene.highlightMaterial.glowThrough) {\r\n gl.clear(gl.DEPTH_BUFFER_BIT);\r\n }\r\n\r\n // Opaque highlighted edges\r\n\r\n if (highlightedEdgesOpaqueBinLen > 0) {\r\n for (i = 0; i < highlightedEdgesOpaqueBinLen; i++) {\r\n highlightedEdgesOpaqueBin[i].drawEdgesHighlighted(frameCtx);\r\n }\r\n }\r\n\r\n // Opaque highlighted fill\r\n\r\n if (highlightedFillOpaqueBinLen > 0) {\r\n for (i = 0; i < highlightedFillOpaqueBinLen; i++) {\r\n highlightedFillOpaqueBin[i].drawSilhouetteHighlighted(frameCtx);\r\n }\r\n }\r\n }\r\n\r\n // Highlighted transparent\r\n\r\n if (highlightedFillTransparentBinLen > 0 || highlightedEdgesTransparentBinLen > 0 || highlightedFillOpaqueBinLen > 0) {\r\n frameCtx.lastProgramId = null;\r\n if (scene.selectedMaterial.glowThrough) {\r\n gl.clear(gl.DEPTH_BUFFER_BIT);\r\n }\r\n gl.enable(gl.BLEND);\r\n if (canvasTransparent) {\r\n gl.blendEquation(gl.FUNC_ADD);\r\n gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n } else {\r\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\r\n }\r\n gl.enable(gl.CULL_FACE);\r\n\r\n // Highlighted transparent edges\r\n\r\n if (highlightedEdgesTransparentBinLen > 0) {\r\n for (i = 0; i < highlightedEdgesTransparentBinLen; i++) {\r\n highlightedEdgesTransparentBin[i].drawEdgesHighlighted(frameCtx);\r\n }\r\n }\r\n\r\n // Highlighted transparent fill\r\n\r\n if (highlightedFillTransparentBinLen > 0) {\r\n for (i = 0; i < highlightedFillTransparentBinLen; i++) {\r\n highlightedFillTransparentBin[i].drawSilhouetteHighlighted(frameCtx);\r\n }\r\n }\r\n gl.disable(gl.BLEND);\r\n }\r\n\r\n // Selected opaque\r\n\r\n if (selectedFillOpaqueBinLen > 0 || selectedEdgesOpaqueBinLen > 0) {\r\n frameCtx.lastProgramId = null;\r\n if (scene.selectedMaterial.glowThrough) {\r\n gl.clear(gl.DEPTH_BUFFER_BIT);\r\n }\r\n\r\n // Selected opaque fill\r\n\r\n if (selectedEdgesOpaqueBinLen > 0) {\r\n for (i = 0; i < selectedEdgesOpaqueBinLen; i++) {\r\n selectedEdgesOpaqueBin[i].drawEdgesSelected(frameCtx);\r\n }\r\n }\r\n\r\n // Selected opaque edges\r\n\r\n if (selectedFillOpaqueBinLen > 0) {\r\n for (i = 0; i < selectedFillOpaqueBinLen; i++) {\r\n selectedFillOpaqueBin[i].drawSilhouetteSelected(frameCtx);\r\n }\r\n }\r\n }\r\n\r\n // Selected transparent\r\n\r\n if (selectedFillTransparentBinLen > 0 || selectedEdgesTransparentBinLen > 0) {\r\n frameCtx.lastProgramId = null;\r\n if (scene.selectedMaterial.glowThrough) {\r\n gl.clear(gl.DEPTH_BUFFER_BIT);\r\n }\r\n gl.enable(gl.CULL_FACE);\r\n gl.enable(gl.BLEND);\r\n if (canvasTransparent) {\r\n gl.blendEquation(gl.FUNC_ADD);\r\n gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n } else {\r\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\r\n }\r\n\r\n // Selected transparent edges\r\n\r\n if (selectedEdgesTransparentBinLen > 0) {\r\n for (i = 0; i < selectedEdgesTransparentBinLen; i++) {\r\n selectedEdgesTransparentBin[i].drawEdgesSelected(frameCtx);\r\n }\r\n }\r\n\r\n // Selected transparent fill\r\n\r\n if (selectedFillTransparentBinLen > 0) {\r\n for (i = 0; i < selectedFillTransparentBinLen; i++) {\r\n selectedFillTransparentBin[i].drawSilhouetteSelected(frameCtx);\r\n }\r\n }\r\n gl.disable(gl.BLEND);\r\n }\r\n\r\n const endTime = Date.now();\r\n const frameStats = _stats_js__WEBPACK_IMPORTED_MODULE_2__.stats.frame;\r\n\r\n frameStats.renderTime = (endTime - startTime) / 1000.0;\r\n frameStats.drawElements = frameCtx.drawElements;\r\n frameStats.drawArrays = frameCtx.drawArrays;\r\n frameStats.useProgram = frameCtx.useProgram;\r\n frameStats.bindTexture = frameCtx.bindTexture;\r\n frameStats.bindArray = frameCtx.bindArray;\r\n\r\n const numTextureUnits = _webglInfo_js__WEBPACK_IMPORTED_MODULE_3__.WEBGL_INFO.MAX_TEXTURE_IMAGE_UNITS;\r\n for (let ii = 0; ii < numTextureUnits; ii++) {\r\n gl.activeTexture(gl.TEXTURE0 + ii);\r\n }\r\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n\r\n const numVertexAttribs = _webglInfo_js__WEBPACK_IMPORTED_MODULE_3__.WEBGL_INFO.MAX_VERTEX_ATTRIBS; // Fixes https://github.com/xeokit/xeokit-sdk/issues/174\r\n for (let ii = 0; ii < numVertexAttribs; ii++) {\r\n gl.disableVertexAttribArray(ii);\r\n }\r\n\r\n if (unbindOutputFrameBuffer) {\r\n unbindOutputFrameBuffer(params.pass);\r\n }\r\n }\r\n\r\n /**\r\n * Picks an Entity.\r\n * @private\r\n */\r\n this.pick = (function () {\r\n\r\n const tempVec3a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n const tempMat4a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\r\n const tempMat4b = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\r\n\r\n const randomVec3 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n const up = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3([0, 1, 0]);\r\n const _pickResult = new _PickResult_js__WEBPACK_IMPORTED_MODULE_5__.PickResult();\r\n\r\n const nearAndFar = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec2();\r\n\r\n const canvasPos = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\r\n const worldRayOrigin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n const worldRayDir = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n const worldSurfacePos = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n const worldSurfaceNormal = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\r\n\r\n return function (params, pickResult = _pickResult) {\r\n\r\n pickResult.reset();\r\n\r\n updateDrawlist();\r\n\r\n let look;\r\n let pickViewMatrix = null;\r\n let pickProjMatrix = null;\r\n\r\n pickResult.pickSurface = params.pickSurface;\r\n\r\n if (params.canvasPos) {\r\n\r\n canvasPos[0] = params.canvasPos[0];\r\n canvasPos[1] = params.canvasPos[1];\r\n\r\n pickViewMatrix = scene.camera.viewMatrix;\r\n pickProjMatrix = scene.camera.projMatrix;\r\n\r\n pickResult.canvasPos = params.canvasPos;\r\n\r\n } else {\r\n\r\n // Picking with arbitrary World-space ray\r\n // Align camera along ray and fire ray through center of canvas\r\n\r\n if (params.matrix) {\r\n\r\n pickViewMatrix = params.matrix;\r\n pickProjMatrix = scene.camera.projMatrix;\r\n\r\n } else {\r\n\r\n worldRayOrigin.set(params.origin || [0, 0, 0]);\r\n worldRayDir.set(params.direction || [0, 0, 1]);\r\n\r\n look = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(worldRayOrigin, worldRayDir, tempVec3a);\r\n\r\n randomVec3[0] = Math.random();\r\n randomVec3[1] = Math.random();\r\n randomVec3[2] = Math.random();\r\n\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3(randomVec3);\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.cross3Vec3(worldRayDir, randomVec3, up);\r\n\r\n pickViewMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.lookAtMat4v(worldRayOrigin, look, up, tempMat4b);\r\n // pickProjMatrix = scene.camera.projMatrix;\r\n pickProjMatrix = scene.camera.ortho.matrix;\r\n\r\n pickResult.origin = worldRayOrigin;\r\n pickResult.direction = worldRayDir;\r\n }\r\n\r\n canvasPos[0] = canvas.clientWidth * 0.5;\r\n canvasPos[1] = canvas.clientHeight * 0.5;\r\n }\r\n\r\n for (let type in drawableTypeInfo) {\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n const drawableList = drawableTypeInfo[type].drawableList;\r\n for (let i = 0, len = drawableList.length; i < len; i++) {\r\n const drawable = drawableList[i];\r\n if (drawable.setPickMatrices) { // Eg. SceneModel, which needs pre-loading into texture\r\n drawable.setPickMatrices(pickViewMatrix, pickProjMatrix);\r\n }\r\n }\r\n }\r\n }\r\n\r\n const pickBuffer = renderBufferManager.getRenderBuffer(\"pick\", {size: [1, 1]});\r\n\r\n pickBuffer.bind();\r\n\r\n const pickable = gpuPickPickable(pickBuffer, canvasPos, pickViewMatrix, pickProjMatrix, params, pickResult);\r\n\r\n if (!pickable) {\r\n pickBuffer.unbind();\r\n return null;\r\n }\r\n\r\n const pickedEntity = (pickable.delegatePickedEntity) ? pickable.delegatePickedEntity() : pickable;\r\n\r\n if (!pickedEntity) {\r\n pickBuffer.unbind();\r\n return null;\r\n }\r\n\r\n if (params.pickSurface) {\r\n\r\n // GPU-based ray-picking\r\n\r\n if (pickable.canPickTriangle && pickable.canPickTriangle()) {\r\n\r\n gpuPickTriangle(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, pickResult);\r\n\r\n pickable.pickTriangleSurface(pickViewMatrix, pickProjMatrix, pickResult);\r\n\r\n pickResult.pickSurfacePrecision = false;\r\n\r\n } else {\r\n\r\n if (pickable.canPickWorldPos && pickable.canPickWorldPos()) {\r\n\r\n nearAndFar[0] = scene.camera.project.near;\r\n nearAndFar[1] = scene.camera.project.far;\r\n\r\n gpuPickWorldPos(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, nearAndFar, pickResult);\r\n\r\n if (params.pickSurfaceNormal !== false) {\r\n gpuPickWorldNormal(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, pickResult);\r\n }\r\n\r\n pickResult.pickSurfacePrecision = false;\r\n }\r\n }\r\n }\r\n pickBuffer.unbind();\r\n pickResult.entity = pickedEntity;\r\n return pickResult;\r\n };\r\n })();\r\n\r\n function gpuPickPickable(pickBuffer, canvasPos, pickViewMatrix, pickProjMatrix, params, pickResult) {\r\n\r\n const resolutionScale = scene.canvas.resolutionScale;\r\n\r\n frameCtx.reset();\r\n frameCtx.backfaces = true;\r\n frameCtx.frontface = true; // \"ccw\"\r\n frameCtx.pickOrigin = pickResult.origin;\r\n frameCtx.pickViewMatrix = pickViewMatrix;\r\n frameCtx.pickProjMatrix = pickProjMatrix;\r\n frameCtx.pickInvisible = !!params.pickInvisible;\r\n frameCtx.pickClipPos = [\r\n getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\r\n getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),\r\n ];\r\n\r\n gl.viewport(0, 0, 1, 1);\r\n gl.depthMask(true);\r\n gl.enable(gl.DEPTH_TEST);\r\n gl.disable(gl.CULL_FACE);\r\n gl.disable(gl.BLEND);\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\r\n\r\n const includeEntityIds = params.includeEntityIds;\r\n const excludeEntityIds = params.excludeEntityIds;\r\n\r\n for (let type in drawableTypeInfo) {\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n\r\n const drawableInfo = drawableTypeInfo[type];\r\n const drawableList = drawableInfo.drawableList;\r\n\r\n for (let i = 0, len = drawableList.length; i < len; i++) {\r\n\r\n const drawable = drawableList[i];\r\n\r\n if (!drawable.drawPickMesh || (params.pickInvisible !== true && drawable.visible === false) || drawable.pickable === false) {\r\n continue;\r\n }\r\n if (includeEntityIds && !includeEntityIds[drawable.id]) { // TODO: push this logic into drawable\r\n continue;\r\n }\r\n if (excludeEntityIds && excludeEntityIds[drawable.id]) {\r\n continue;\r\n }\r\n\r\n drawable.drawPickMesh(frameCtx);\r\n }\r\n }\r\n }\r\n const pix = pickBuffer.read(0, 0);\r\n const pickID = pix[0] + (pix[1] << 8) + (pix[2] << 16) + (pix[3] << 24);\r\n\r\n if (pickID < 0) {\r\n return;\r\n }\r\n\r\n const pickable = pickIDs.items[pickID];\r\n\r\n return pickable;\r\n }\r\n\r\n function gpuPickTriangle(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, pickResult) {\r\n\r\n if (!pickable.drawPickTriangles) {\r\n return;\r\n }\r\n\r\n const resolutionScale = scene.canvas.resolutionScale;\r\n\r\n frameCtx.reset();\r\n frameCtx.backfaces = true;\r\n frameCtx.frontface = true; // \"ccw\"\r\n frameCtx.pickOrigin = pickResult.origin;\r\n frameCtx.pickViewMatrix = pickViewMatrix; // Can be null\r\n frameCtx.pickProjMatrix = pickProjMatrix; // Can be null\r\n // frameCtx.pickInvisible = !!params.pickInvisible;\r\n frameCtx.pickClipPos = [\r\n getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\r\n getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),\r\n ];\r\n\r\n gl.viewport(0, 0, 1, 1);\r\n\r\n gl.clearColor(0, 0, 0, 0);\r\n gl.enable(gl.DEPTH_TEST);\r\n gl.disable(gl.CULL_FACE);\r\n gl.disable(gl.BLEND);\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\r\n\r\n pickable.drawPickTriangles(frameCtx);\r\n\r\n const pix = pickBuffer.read(0, 0);\r\n\r\n let primIndex = pix[0] + (pix[1] * 256) + (pix[2] * 256 * 256) + (pix[3] * 256 * 256 * 256);\r\n\r\n primIndex *= 3; // Convert from triangle number to first vertex in indices\r\n\r\n pickResult.primIndex = primIndex;\r\n }\r\n\r\n const gpuPickWorldPos = (function () {\r\n\r\n const tempVec4a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\r\n const tempVec4b = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\r\n const tempVec4c = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\r\n const tempVec4d = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\r\n const tempVec4e = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\r\n const tempMat4a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\r\n const tempMat4b = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\r\n const tempMat4c = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\r\n\r\n return function (pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, nearAndFar, pickResult) {\r\n\r\n const resolutionScale = scene.canvas.resolutionScale;\r\n\r\n frameCtx.reset();\r\n frameCtx.backfaces = true;\r\n frameCtx.frontface = true; // \"ccw\"\r\n frameCtx.pickOrigin = pickResult.origin;\r\n frameCtx.pickViewMatrix = pickViewMatrix;\r\n frameCtx.pickProjMatrix = pickProjMatrix;\r\n frameCtx.pickZNear = nearAndFar[0];\r\n frameCtx.pickZFar = nearAndFar[1];\r\n frameCtx.pickElementsCount = pickable.pickElementsCount;\r\n frameCtx.pickElementsOffset = pickable.pickElementsOffset;\r\n frameCtx.pickClipPos = [\r\n getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\r\n getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),\r\n ];\r\n\r\n gl.viewport(0, 0, 1, 1);\r\n\r\n gl.clearColor(0, 0, 0, 0);\r\n gl.depthMask(true);\r\n gl.enable(gl.DEPTH_TEST);\r\n gl.disable(gl.CULL_FACE);\r\n gl.disable(gl.BLEND);\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\r\n\r\n pickable.drawPickDepths(frameCtx); // Draw color-encoded fragment screen-space depths\r\n\r\n const pix = pickBuffer.read(0, 0);\r\n\r\n const screenZ = unpackDepth(pix); // Get screen-space Z at the given canvas coords\r\n\r\n // Calculate clip space coordinates, which will be in range of x=[-1..1] and y=[-1..1], with y=(+1) at top\r\n const x = (canvasPos[0] - canvas.clientWidth / 2) / (canvas.clientWidth / 2);\r\n const y = -(canvasPos[1] - canvas.clientHeight / 2) / (canvas.clientHeight / 2);\r\n\r\n const origin = pickable.origin;\r\n let pvMat;\r\n\r\n if (origin) {\r\n const rtcPickViewMat = (0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_8__.createRTCViewMat)(pickViewMatrix, origin, tempMat4a);\r\n pvMat = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulMat4(pickProjMatrix, rtcPickViewMat, tempMat4b);\r\n\r\n } else {\r\n pvMat = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulMat4(pickProjMatrix, pickViewMatrix, tempMat4b);\r\n }\r\n\r\n const pvMatInverse = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(pvMat, tempMat4c);\r\n\r\n tempVec4a[0] = x;\r\n tempVec4a[1] = y;\r\n tempVec4a[2] = -1;\r\n tempVec4a[3] = 1;\r\n\r\n let world1 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec4(pvMatInverse, tempVec4a);\r\n world1 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulVec4Scalar(world1, 1 / world1[3]);\r\n\r\n tempVec4b[0] = x;\r\n tempVec4b[1] = y;\r\n tempVec4b[2] = 1;\r\n tempVec4b[3] = 1;\r\n\r\n let world2 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec4(pvMatInverse, tempVec4b);\r\n world2 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulVec4Scalar(world2, 1 / world2[3]);\r\n\r\n const dir = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.subVec3(world2, world1, tempVec4c);\r\n const worldPos = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(world1, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulVec4Scalar(dir, screenZ, tempVec4d), tempVec4e);\r\n\r\n if (origin) {\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(worldPos, origin);\r\n }\r\n\r\n pickResult.worldPos = worldPos;\r\n }\r\n })();\r\n\r\n function drawSnapInit(frameCtx) {\r\n frameCtx.snapPickLayerParams = [];\r\n frameCtx.snapPickLayerNumber = 0;\r\n for (let type in drawableTypeInfo) {\r\n const drawableInfo = drawableTypeInfo[type];\r\n const drawableList = drawableInfo.drawableList;\r\n for (let i = 0, len = drawableList.length; i < len; i++) {\r\n const drawable = drawableList[i];\r\n if (drawable.drawSnapInit) {\r\n if (!drawable.culled && drawable.visible && drawable.pickable) {\r\n drawable.drawSnapInit(frameCtx);\r\n }\r\n }\r\n }\r\n }\r\n return frameCtx.snapPickLayerParams;\r\n }\r\n\r\n function drawSnap(frameCtx) {\r\n frameCtx.snapPickLayerParams = frameCtx.snapPickLayerParams || [];\r\n frameCtx.snapPickLayerNumber = frameCtx.snapPickLayerParams.length;\r\n for (let type in drawableTypeInfo) {\r\n const drawableInfo = drawableTypeInfo[type];\r\n const drawableList = drawableInfo.drawableList;\r\n for (let i = 0, len = drawableList.length; i < len; i++) {\r\n const drawable = drawableList[i];\r\n if (drawable.drawSnap) {\r\n if (!drawable.culled && drawable.visible && drawable.pickable) {\r\n drawable.drawSnap(frameCtx);\r\n }\r\n }\r\n }\r\n }\r\n return frameCtx.snapPickLayerParams;\r\n }\r\n\r\n function getClipPosX(pos, size) {\r\n return 2 * (pos / size) - 1;\r\n }\r\n\r\n function getClipPosY(pos, size) {\r\n return 1 - 2 * (pos / size);\r\n }\r\n\r\n /**\r\n * @param {[number, number]} canvasPos\r\n * @param {number} [snapRadiusInPixels=30]\r\n * @param {boolean} [snapToVertex=true]\r\n * @param {boolean} [snapToEdge=true]\r\n * @param pickResult\r\n * @returns {PickResult}\r\n */\r\n this.snapPick = (function () {\r\n\r\n const _pickResult = new _PickResult_js__WEBPACK_IMPORTED_MODULE_5__.PickResult();\r\n\r\n return function (canvasPos, snapRadiusInPixels, snapToVertex, snapToEdge, pickResult = _pickResult) {\r\n\r\n if (!snapToVertex && !snapToEdge) {\r\n return this.pick({canvasPos, pickSurface: true});\r\n }\r\n\r\n const resolutionScale = scene.canvas.resolutionScale;\r\n\r\n frameCtx.reset();\r\n frameCtx.backfaces = true;\r\n frameCtx.frontface = true; // \"ccw\"\r\n frameCtx.pickZNear = scene.camera.project.near;\r\n frameCtx.pickZFar = scene.camera.project.far;\r\n\r\n snapRadiusInPixels = snapRadiusInPixels || 30;\r\n\r\n const vertexPickBuffer = renderBufferManager.getRenderBuffer(\"uniquePickColors-aabs\", {\r\n depthTexture: true,\r\n size: [\r\n 2 * snapRadiusInPixels + 1,\r\n 2 * snapRadiusInPixels + 1,\r\n ]\r\n });\r\n\r\n frameCtx.snapVectorA = [\r\n getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\r\n getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),\r\n ];\r\n\r\n frameCtx.snapInvVectorAB = [\r\n gl.drawingBufferWidth / (2 * snapRadiusInPixels),\r\n gl.drawingBufferHeight / (2 * snapRadiusInPixels),\r\n ];\r\n\r\n // Bind and clear the snap render target\r\n\r\n vertexPickBuffer.bind(gl.RGBA32I, gl.RGBA32I, gl.RGBA8UI);\r\n gl.viewport(0, 0, vertexPickBuffer.size[0], vertexPickBuffer.size[1]);\r\n gl.enable(gl.DEPTH_TEST);\r\n gl.frontFace(gl.CCW);\r\n gl.disable(gl.CULL_FACE);\r\n gl.depthMask(true);\r\n gl.disable(gl.BLEND);\r\n gl.depthFunc(gl.LEQUAL);\r\n gl.clear(gl.DEPTH_BUFFER_BIT);\r\n gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));\r\n gl.clearBufferiv(gl.COLOR, 1, new Int32Array([0, 0, 0, 0]));\r\n gl.clearBufferuiv(gl.COLOR, 2, new Uint32Array([0, 0, 0, 0]));\r\n\r\n //////////////////////////////////\r\n // Set view and proj mats for VBO renderers\r\n ///////////////////////////////////////\r\n\r\n const pickViewMatrix = scene.camera.viewMatrix;\r\n const pickProjMatrix = scene.camera.projMatrix;\r\n\r\n for (let type in drawableTypeInfo) {\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n const drawableList = drawableTypeInfo[type].drawableList;\r\n for (let i = 0, len = drawableList.length; i < len; i++) {\r\n const drawable = drawableList[i];\r\n if (drawable.setPickMatrices) { // Eg. SceneModel, which needs pre-loading into texture\r\n drawable.setPickMatrices(pickViewMatrix, pickProjMatrix);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // a) init z-buffer\r\n gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);\r\n const layerParamsSurface = drawSnapInit(frameCtx);\r\n\r\n // b) snap-pick\r\n const layerParamsSnap = []\r\n frameCtx.snapPickLayerParams = layerParamsSnap;\r\n\r\n gl.depthMask(false);\r\n gl.drawBuffers([gl.COLOR_ATTACHMENT0]);\r\n\r\n if (snapToVertex && snapToEdge) {\r\n frameCtx.snapMode = \"edge\";\r\n drawSnap(frameCtx);\r\n\r\n frameCtx.snapMode = \"vertex\";\r\n frameCtx.snapPickLayerNumber++;\r\n\r\n drawSnap(frameCtx);\r\n } else {\r\n frameCtx.snapMode = snapToVertex ? \"vertex\" : \"edge\";\r\n\r\n drawSnap(frameCtx);\r\n }\r\n\r\n gl.depthMask(true);\r\n\r\n // Read and decode the snapped coordinates\r\n\r\n const snapPickResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4);\r\n const snapPickNormalResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4, 1);\r\n const snapPickIdResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.UNSIGNED_INT, Uint32Array, 4, 2);\r\n\r\n vertexPickBuffer.unbind();\r\n\r\n // result 1) regular hi-precision world position\r\n\r\n let worldPos = null;\r\n let worldNormal = null;\r\n let pickable = null;\r\n\r\n const middleX = snapRadiusInPixels;\r\n const middleY = snapRadiusInPixels;\r\n const middleIndex = (middleX * 4) + (middleY * vertexPickBuffer.size[0] * 4);\r\n const pickResultMiddleXY = snapPickResultArray.slice(middleIndex, middleIndex + 4);\r\n const pickNormalResultMiddleXY = snapPickNormalResultArray.slice(middleIndex, middleIndex + 4);\r\n const pickPickableResultMiddleXY = snapPickIdResultArray.slice(middleIndex, middleIndex + 4);\r\n\r\n if (pickResultMiddleXY[3] !== 0) {\r\n const pickedLayerParmasSurface = layerParamsSurface[Math.abs(pickResultMiddleXY[3]) % layerParamsSurface.length];\r\n const origin = pickedLayerParmasSurface.origin;\r\n const scale = pickedLayerParmasSurface.coordinateScale;\r\n worldPos = [\r\n pickResultMiddleXY[0] * scale[0] + origin[0],\r\n pickResultMiddleXY[1] * scale[1] + origin[1],\r\n pickResultMiddleXY[2] * scale[2] + origin[2],\r\n ];\r\n worldNormal = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3([\r\n pickNormalResultMiddleXY[0] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\r\n pickNormalResultMiddleXY[1] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\r\n pickNormalResultMiddleXY[2] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\r\n ]);\r\n\r\n const pickID =\r\n pickPickableResultMiddleXY[0]\r\n + (pickPickableResultMiddleXY[1] << 8)\r\n + (pickPickableResultMiddleXY[2] << 16)\r\n + (pickPickableResultMiddleXY[3] << 24);\r\n\r\n pickable = pickIDs.items[pickID];\r\n }\r\n\r\n // result 2) hi-precision snapped (to vertex/edge) world position\r\n\r\n let snapPickResult = [];\r\n\r\n for (let i = 0; i < snapPickResultArray.length; i += 4) {\r\n if (snapPickResultArray[i + 3] > 0) {\r\n const pixelNumber = Math.floor(i / 4);\r\n const w = vertexPickBuffer.size[0];\r\n const x = pixelNumber % w - Math.floor(w / 2);\r\n const y = Math.floor(pixelNumber / w) - Math.floor(w / 2);\r\n const dist = (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));\r\n snapPickResult.push({\r\n x,\r\n y,\r\n dist,\r\n isVertex: snapToVertex && snapToEdge ? snapPickResultArray[i + 3] > layerParamsSnap.length / 2 : snapToVertex,\r\n result: [\r\n snapPickResultArray[i + 0],\r\n snapPickResultArray[i + 1],\r\n snapPickResultArray[i + 2],\r\n snapPickResultArray[i + 3],\r\n ],\r\n normal: [\r\n snapPickNormalResultArray[i + 0],\r\n snapPickNormalResultArray[i + 1],\r\n snapPickNormalResultArray[i + 2],\r\n snapPickNormalResultArray[i + 3],\r\n ],\r\n id: [\r\n snapPickIdResultArray[i + 0],\r\n snapPickIdResultArray[i + 1],\r\n snapPickIdResultArray[i + 2],\r\n snapPickIdResultArray[i + 3],\r\n ]\r\n });\r\n }\r\n }\r\n\r\n let snappedWorldPos = null;\r\n let snappedWorldNormal = null;\r\n let snappedPickable = null;\r\n let snapType = null;\r\n\r\n if (snapPickResult.length > 0) {\r\n // vertex snap first, then edge snap\r\n snapPickResult.sort((a, b) => {\r\n if (a.isVertex !== b.isVertex) {\r\n return a.isVertex ? -1 : 1;\r\n } else {\r\n return a.dist - b.dist;\r\n }\r\n });\r\n\r\n snapType = snapPickResult[0].isVertex ? \"vertex\" : \"edge\";\r\n const snapPick = snapPickResult[0].result;\r\n const snapPickNormal = snapPickResult[0].normal;\r\n const snapPickId = snapPickResult[0].id;\r\n\r\n const pickedLayerParmas = layerParamsSnap[snapPick[3]];\r\n\r\n const origin = pickedLayerParmas.origin;\r\n const scale = pickedLayerParmas.coordinateScale;\r\n\r\n snappedWorldNormal = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3([\r\n snapPickNormal[0] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\r\n snapPickNormal[1] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\r\n snapPickNormal[2] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\r\n ]);\r\n\r\n snappedWorldPos = [\r\n snapPick[0] * scale[0] + origin[0],\r\n snapPick[1] * scale[1] + origin[1],\r\n snapPick[2] * scale[2] + origin[2],\r\n ];\r\n\r\n snappedPickable = pickIDs.items[\r\n snapPickId[0]\r\n + (snapPickId[1] << 8)\r\n + (snapPickId[2] << 16)\r\n + (snapPickId[3] << 24)\r\n ];\r\n }\r\n\r\n if (null === worldPos && null == snappedWorldPos) { // If neither regular pick or snap pick, return null\r\n return null;\r\n }\r\n\r\n let snappedCanvasPos = null;\r\n\r\n if (null !== snappedWorldPos) {\r\n snappedCanvasPos = scene.camera.projectWorldPos(snappedWorldPos);\r\n }\r\n\r\n const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;\r\n\r\n pickResult.reset();\r\n pickResult.snappedToEdge = (snapType === \"edge\");\r\n pickResult.snappedToVertex = (snapType === \"vertex\");\r\n pickResult.worldPos = snappedWorldPos;\r\n pickResult.worldNormal = snappedWorldNormal;\r\n pickResult.entity = snappedEntity;\r\n pickResult.canvasPos = canvasPos;\r\n pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;\r\n\r\n return pickResult;\r\n };\r\n })();\r\n\r\n function unpackDepth(depthZ) {\r\n const vec = [depthZ[0] / 256.0, depthZ[1] / 256.0, depthZ[2] / 256.0, depthZ[3] / 256.0];\r\n const bitShift = [1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0];\r\n return _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.dotVec4(vec, bitShift);\r\n }\r\n\r\n function gpuPickWorldNormal(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, pickResult) {\r\n\r\n const resolutionScale = scene.canvas.resolutionScale;\r\n\r\n frameCtx.reset();\r\n frameCtx.backfaces = true;\r\n frameCtx.frontface = true; // \"ccw\"\r\n frameCtx.pickOrigin = pickResult.origin;\r\n frameCtx.pickViewMatrix = pickViewMatrix;\r\n frameCtx.pickProjMatrix = pickProjMatrix;\r\n frameCtx.pickClipPos = [\r\n getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\r\n getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),\r\n ];\r\n\r\n const pickNormalBuffer = renderBufferManager.getRenderBuffer(\"pick-normal\", {size: [3, 3]});\r\n\r\n pickNormalBuffer.bind(gl.RGBA32I);\r\n\r\n gl.viewport(0, 0, pickNormalBuffer.size[0], pickNormalBuffer.size[1]);\r\n\r\n gl.enable(gl.DEPTH_TEST);\r\n gl.disable(gl.CULL_FACE);\r\n gl.disable(gl.BLEND);\r\n gl.clear(gl.DEPTH_BUFFER_BIT);\r\n gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));\r\n\r\n pickable.drawPickNormals(frameCtx); // Draw color-encoded fragment World-space normals\r\n\r\n const pix = pickNormalBuffer.read(1, 1, gl.RGBA_INTEGER, gl.INT, Int32Array, 4);\r\n\r\n pickNormalBuffer.unbind();\r\n\r\n const worldNormal = [\r\n pix[0] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\r\n pix[1] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\r\n pix[2] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\r\n ];\r\n\r\n _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3(worldNormal);\r\n\r\n pickResult.worldNormal = worldNormal;\r\n }\r\n\r\n /**\r\n * Adds a {@link Marker} for occlusion testing.\r\n * @param marker\r\n */\r\n this.addMarker = function (marker) {\r\n this._occlusionTester = this._occlusionTester || new _occlusion_OcclusionTester_js__WEBPACK_IMPORTED_MODULE_6__.OcclusionTester(scene, renderBufferManager);\r\n this._occlusionTester.addMarker(marker);\r\n scene.occlusionTestCountdown = 0;\r\n };\r\n\r\n /**\r\n * Notifies that a {@link Marker#worldPos} has updated.\r\n * @param marker\r\n */\r\n this.markerWorldPosUpdated = function (marker) {\r\n this._occlusionTester.markerWorldPosUpdated(marker);\r\n };\r\n\r\n /**\r\n * Removes a {@link Marker} from occlusion testing.\r\n * @param marker\r\n */\r\n this.removeMarker = function (marker) {\r\n this._occlusionTester.removeMarker(marker);\r\n };\r\n\r\n /**\r\n * Performs an occlusion test for all added {@link Marker}s, updating\r\n * their {@link Marker#visible} properties accordingly.\r\n */\r\n this.doOcclusionTest = function () {\r\n\r\n if (this._occlusionTester && this._occlusionTester.needOcclusionTest) {\r\n\r\n updateDrawlist();\r\n\r\n this._occlusionTester.bindRenderBuf();\r\n\r\n frameCtx.reset();\r\n frameCtx.backfaces = true;\r\n frameCtx.frontface = true; // \"ccw\"\r\n\r\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\r\n gl.clearColor(0, 0, 0, 0);\r\n gl.enable(gl.DEPTH_TEST);\r\n gl.disable(gl.CULL_FACE);\r\n gl.disable(gl.BLEND);\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\r\n\r\n for (let type in drawableTypeInfo) {\r\n if (drawableTypeInfo.hasOwnProperty(type)) {\r\n const drawableInfo = drawableTypeInfo[type];\r\n const drawableList = drawableInfo.drawableList;\r\n for (let i = 0, len = drawableList.length; i < len; i++) {\r\n const drawable = drawableList[i];\r\n if (!drawable.drawOcclusion || drawable.culled === true || drawable.visible === false || drawable.pickable === false) { // TODO: Option to exclude transparent?\r\n continue;\r\n }\r\n\r\n drawable.drawOcclusion(frameCtx);\r\n }\r\n }\r\n }\r\n\r\n this._occlusionTester.drawMarkers(frameCtx);\r\n this._occlusionTester.doOcclusionTest(); // Updates Marker \"visible\" properties\r\n this._occlusionTester.unbindRenderBuf();\r\n }\r\n };\r\n\r\n /**\r\n * Read pixels from the renderer's current output. Performs a force-render first.\r\n * @param pixels\r\n * @param colors\r\n * @param len\r\n * @param opaqueOnly\r\n * @private\r\n */\r\n this.readPixels = function (pixels, colors, len, opaqueOnly) {\r\n const snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\r\n snapshotBuffer.bind();\r\n snapshotBuffer.clear();\r\n this.render({force: true, opaqueOnly: opaqueOnly});\r\n let color;\r\n let i;\r\n let j;\r\n let k;\r\n for (i = 0; i < len; i++) {\r\n j = i * 2;\r\n k = i * 4;\r\n color = snapshotBuffer.read(pixels[j], pixels[j + 1]);\r\n colors[k] = color[0];\r\n colors[k + 1] = color[1];\r\n colors[k + 2] = color[2];\r\n colors[k + 3] = color[3];\r\n }\r\n snapshotBuffer.unbind();\r\n imageDirty = true;\r\n };\r\n\r\n /**\r\n * Enter snapshot mode.\r\n *\r\n * Switches rendering to a hidden snapshot canvas.\r\n *\r\n * Exit snapshot mode using endSnapshot().\r\n */\r\n this.beginSnapshot = function (params = {}) {\r\n const snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\r\n if (params.width && params.height) {\r\n snapshotBuffer.setSize([params.width, params.height]);\r\n }\r\n snapshotBuffer.bind();\r\n snapshotBuffer.clear();\r\n snapshotBound = true;\r\n };\r\n\r\n /**\r\n * When in snapshot mode, renders a frame of the current Scene state to the snapshot canvas.\r\n */\r\n this.renderSnapshot = function () {\r\n if (!snapshotBound) {\r\n return;\r\n }\r\n const snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\r\n snapshotBuffer.clear();\r\n this.render({force: true, opaqueOnly: false});\r\n imageDirty = true;\r\n };\r\n\r\n /**\r\n * When in snapshot mode, gets an image of the snapshot canvas.\r\n *\r\n * @private\r\n * @returns {String} The image data URI.\r\n */\r\n this.readSnapshot = function (params) {\r\n const snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\r\n return snapshotBuffer.readImage(params);\r\n };\r\n\r\n /**\r\n * Returns an HTMLCanvas containing an image of the snapshot canvas.\r\n *\r\n * - The HTMLCanvas has a CanvasRenderingContext2D.\r\n * - Expects the caller to draw more things on the HTMLCanvas (annotations etc).\r\n *\r\n * @returns {HTMLCanvasElement}\r\n */\r\n this.readSnapshotAsCanvas = function () {\r\n const snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\r\n return snapshotBuffer.readImageAsCanvas();\r\n };\r\n\r\n /**\r\n * Exists snapshot mode.\r\n *\r\n * Switches rendering back to the main canvas.\r\n */\r\n this.endSnapshot = function () {\r\n if (!snapshotBound) {\r\n return;\r\n }\r\n const snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\r\n snapshotBuffer.unbind();\r\n snapshotBound = false;\r\n };\r\n\r\n /**\r\n * Destroys this renderer.\r\n * @private\r\n */\r\n this.destroy = function () {\r\n\r\n drawableTypeInfo = {};\r\n drawables = {};\r\n\r\n renderBufferManager.destroy();\r\n\r\n saoOcclusionRenderer.destroy();\r\n saoDepthLimitedBlurRenderer.destroy();\r\n\r\n if (this._occlusionTester) {\r\n this._occlusionTester.destroy();\r\n }\r\n };\r\n};\r\n\r\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/webgl/Renderer.js?");
5147
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Renderer: () => (/* binding */ Renderer)\n/* harmony export */ });\n/* harmony import */ var _FrameContext_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./FrameContext.js */ \"./src/viewer/scene/webgl/FrameContext.js\");\n/* harmony import */ var _math_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../math/math.js */ \"./src/viewer/scene/math/math.js\");\n/* harmony import */ var _stats_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../stats.js */ \"./src/viewer/scene/stats.js\");\n/* harmony import */ var _webglInfo_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../webglInfo.js */ \"./src/viewer/scene/webglInfo.js\");\n/* harmony import */ var _utils_Map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/Map.js */ \"./src/viewer/scene/utils/Map.js\");\n/* harmony import */ var _PickResult_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./PickResult.js */ \"./src/viewer/scene/webgl/PickResult.js\");\n/* harmony import */ var _occlusion_OcclusionTester_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./occlusion/OcclusionTester.js */ \"./src/viewer/scene/webgl/occlusion/OcclusionTester.js\");\n/* harmony import */ var _sao_SAOOcclusionRenderer_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./sao/SAOOcclusionRenderer.js */ \"./src/viewer/scene/webgl/sao/SAOOcclusionRenderer.js\");\n/* harmony import */ var _math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../math/rtcCoords.js */ \"./src/viewer/scene/math/rtcCoords.js\");\n/* harmony import */ var _sao_SAODepthLimitedBlurRenderer_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./sao/SAODepthLimitedBlurRenderer.js */ \"./src/viewer/scene/webgl/sao/SAODepthLimitedBlurRenderer.js\");\n/* harmony import */ var _RenderBufferManager_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./RenderBufferManager.js */ \"./src/viewer/scene/webgl/RenderBufferManager.js\");\n/* harmony import */ var _getExtension_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./getExtension.js */ \"./src/viewer/scene/webgl/getExtension.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @private\n */\nconst Renderer = function (scene, options) {\n\toptions = options || {};\n\n\tconst frameCtx = new _FrameContext_js__WEBPACK_IMPORTED_MODULE_0__.FrameContext(scene);\n\tconst canvas = scene.canvas.canvas;\n\t/**\n\t * @type {WebGL2RenderingContext}\n\t */\n\tconst gl = scene.canvas.gl;\n\tlet canvasTransparent = !!options.transparent;\n\tconst alphaDepthMask = options.alphaDepthMask;\n\n\tconst pickIDs = new _utils_Map_js__WEBPACK_IMPORTED_MODULE_4__.Map({});\n\n\tlet drawableTypeInfo = {};\n\tlet drawables = {};\n\n\tlet drawableListDirty = true;\n\tlet stateSortDirty = true;\n\tlet imageDirty = true;\n\tlet shadowsDirty = true;\n\n\tlet transparentEnabled = true;\n\tlet edgesEnabled = !!options.edgesEnabled;\n\tlet saoEnabled = true;\n\tlet pbrEnabled = true;\n\tlet colorTextureEnabled = true;\n\n\tconst renderBufferManager = new _RenderBufferManager_js__WEBPACK_IMPORTED_MODULE_10__.RenderBufferManager(scene);\n\n\tlet snapshotBound = false;\n\n\tconst bindOutputFrameBuffer = null;\n\tconst unbindOutputFrameBuffer = null;\n\n\tconst saoOcclusionRenderer = new _sao_SAOOcclusionRenderer_js__WEBPACK_IMPORTED_MODULE_7__.SAOOcclusionRenderer(scene);\n\tconst saoDepthLimitedBlurRenderer = new _sao_SAODepthLimitedBlurRenderer_js__WEBPACK_IMPORTED_MODULE_9__.SAODepthLimitedBlurRenderer(scene);\n\n\tthis.scene = scene;\n\n\tthis._occlusionTester = null; // Lazy-created in #addMarker()\n\n\tthis.capabilities = {\n\t\tastcSupported: !!(0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, \"WEBGL_compressed_texture_astc\"),\n\t\tetc1Supported: true, // WebGL2\n\t\tetc2Supported: !!(0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, \"WEBGL_compressed_texture_etc\"),\n\t\tdxtSupported: !!(0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, \"WEBGL_compressed_texture_s3tc\"),\n\t\tbptcSupported: !!(0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, \"EXT_texture_compression_bptc\"),\n\t\tpvrtcSupported: !!(\n\t\t\t(0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, \"WEBGL_compressed_texture_pvrtc\") || (0,_getExtension_js__WEBPACK_IMPORTED_MODULE_11__.getExtension)(gl, \"WEBKIT_WEBGL_compressed_texture_pvrtc\")\n\t\t)\n\t};\n\n\tthis.setTransparentEnabled = function (enabled) {\n\t\ttransparentEnabled = enabled;\n\t\tcanvasTransparent = enabled;\n\t\timageDirty = true;\n\t};\n\n\tthis.setEdgesEnabled = function (enabled) {\n\t\tedgesEnabled = enabled;\n\t\timageDirty = true;\n\t};\n\n\tthis.setSAOEnabled = function (enabled) {\n\t\tsaoEnabled = enabled;\n\t\timageDirty = true;\n\t};\n\n\tthis.setPBREnabled = function (enabled) {\n\t\tpbrEnabled = enabled;\n\t\timageDirty = true;\n\t};\n\n\tthis.setColorTextureEnabled = function (enabled) {\n\t\tcolorTextureEnabled = enabled;\n\t\timageDirty = true;\n\t};\n\n\tthis.needStateSort = function () {\n\t\tstateSortDirty = true;\n\t};\n\n\tthis.shadowsDirty = function () {\n\t\tshadowsDirty = true;\n\t};\n\n\tthis.imageDirty = function () {\n\t\timageDirty = true;\n\t};\n\n\tthis.webglContextLost = function () {};\n\n\tthis.webglContextRestored = function (gl) {\n\t\t// renderBufferManager.webglContextRestored(gl);\n\n\t\tsaoOcclusionRenderer.init();\n\t\tsaoDepthLimitedBlurRenderer.init();\n\n\t\timageDirty = true;\n\t};\n\n\t/**\n\t * Inserts a drawable into this renderer.\n\t * @private\n\t */\n\tthis.addDrawable = function (id, drawable) {\n\t\tconst type = drawable.type;\n\t\tif (!type) {\n\t\t\tconsole.error(\"Renderer#addDrawable() : drawable with ID \" + id + \" has no 'type' - ignoring\");\n\t\t\treturn;\n\t\t}\n\t\tlet drawableInfo = drawableTypeInfo[type];\n\t\tif (!drawableInfo) {\n\t\t\tdrawableInfo = {\n\t\t\t\ttype: drawable.type,\n\t\t\t\tcount: 0,\n\t\t\t\tisStateSortable: drawable.isStateSortable,\n\t\t\t\tstateSortCompare: drawable.stateSortCompare,\n\t\t\t\tdrawableMap: {},\n\t\t\t\tdrawableListPreCull: [],\n\t\t\t\tdrawableList: []\n\t\t\t};\n\t\t\tdrawableTypeInfo[type] = drawableInfo;\n\t\t}\n\t\tdrawableInfo.count++;\n\t\tdrawableInfo.drawableMap[id] = drawable;\n\t\tdrawables[id] = drawable;\n\t\tdrawableListDirty = true;\n\t};\n\n\t/**\n\t * Removes a drawable from this renderer.\n\t * @private\n\t */\n\tthis.removeDrawable = function (id) {\n\t\tconst drawable = drawables[id];\n\t\tif (!drawable) {\n\t\t\tconsole.error(\"Renderer#removeDrawable() : drawable not found with ID \" + id + \" - ignoring\");\n\t\t\treturn;\n\t\t}\n\t\tconst type = drawable.type;\n\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\tif (--drawableInfo.count <= 0) {\n\t\t\tdelete drawableTypeInfo[type];\n\t\t} else {\n\t\t\tdelete drawableInfo.drawableMap[id];\n\t\t}\n\t\tdelete drawables[id];\n\t\tdrawableListDirty = true;\n\t};\n\n\t/**\n\t * Gets a unique pick ID for the given Pickable. A Pickable can be a {@link Mesh} or a {@link PerformanceMesh}.\n\t * @returns {Number} New pick ID.\n\t */\n\tthis.getPickID = function (entity) {\n\t\treturn pickIDs.addItem(entity);\n\t};\n\n\t/**\n\t * Released a pick ID for reuse.\n\t * @param {Number} pickID Pick ID to release.\n\t */\n\tthis.putPickID = function (pickID) {\n\t\tpickIDs.removeItem(pickID);\n\t};\n\n\t/**\n\t * Clears the canvas.\n\t * @private\n\t */\n\tthis.clear = function (params) {\n\t\tparams = params || {};\n\t\tgl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\t\tif (canvasTransparent) {\n\t\t\tgl.clearColor(1, 1, 1, 0);\n\t\t} else {\n\t\t\tconst backgroundColor = scene.canvas.backgroundColorFromAmbientLight\n\t\t\t\t? this.lights.getAmbientColorAndIntensity()\n\t\t\t\t: scene.canvas.backgroundColor;\n\t\t\tgl.clearColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], 1.0);\n\t\t}\n\t\tif (bindOutputFrameBuffer) {\n\t\t\tbindOutputFrameBuffer(params.pass);\n\t\t}\n\t\tgl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\t\tif (unbindOutputFrameBuffer) {\n\t\t\tunbindOutputFrameBuffer(params.pass);\n\t\t}\n\t};\n\n\t/**\n\t * Returns true if the next call to render() will draw something\n\t * @returns {Boolean}\n\t */\n\tthis.needsRender = function () {\n\t\tconst needsRender = imageDirty || drawableListDirty || stateSortDirty;\n\t\treturn needsRender;\n\t};\n\n\t/**\n\t * Renders inserted drawables.\n\t * @private\n\t */\n\tthis.render = function (params) {\n\t\tparams = params || {};\n\t\tif (params.force) {\n\t\t\timageDirty = true;\n\t\t}\n\t\tupdateDrawlist();\n\t\tif (imageDirty) {\n\t\t\tdraw(params);\n\t\t\t_stats_js__WEBPACK_IMPORTED_MODULE_2__.stats.frame.frameCount++;\n\t\t\timageDirty = false;\n\t\t}\n\t};\n\n\tfunction updateDrawlist() {\n\t\t// Prepares state-sorted array of drawables from maps of inserted drawables\n\t\tif (drawableListDirty) {\n\t\t\tbuildDrawableList();\n\t\t\tdrawableListDirty = false;\n\t\t\tstateSortDirty = true;\n\t\t}\n\t\tif (stateSortDirty) {\n\t\t\tsortDrawableList();\n\t\t\tstateSortDirty = false;\n\t\t\timageDirty = true;\n\t\t}\n\t\tif (imageDirty) {\n\t\t\t// Image is usually dirty because the camera moved\n\t\t\tcullDrawableList();\n\t\t}\n\t}\n\n\tfunction buildDrawableList() {\n\t\tfor (let type in drawableTypeInfo) {\n\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\t\tconst drawableMap = drawableInfo.drawableMap;\n\t\t\t\tconst drawableListPreCull = drawableInfo.drawableListPreCull;\n\t\t\t\tlet lenDrawableList = 0;\n\t\t\t\tfor (let id in drawableMap) {\n\t\t\t\t\tif (drawableMap.hasOwnProperty(id)) {\n\t\t\t\t\t\tdrawableListPreCull[lenDrawableList++] = drawableMap[id];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdrawableListPreCull.length = lenDrawableList;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction sortDrawableList() {\n\t\tfor (let type in drawableTypeInfo) {\n\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\t\tif (drawableInfo.isStateSortable) {\n\t\t\t\t\tdrawableInfo.drawableListPreCull.sort(drawableInfo.stateSortCompare);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction cullDrawableList() {\n\t\tfor (let type in drawableTypeInfo) {\n\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\t\tconst drawableListPreCull = drawableInfo.drawableListPreCull;\n\t\t\t\tconst drawableList = drawableInfo.drawableList;\n\t\t\t\tlet lenDrawableList = 0;\n\t\t\t\tfor (let i = 0, len = drawableListPreCull.length; i < len; i++) {\n\t\t\t\t\tconst drawable = drawableListPreCull[i];\n\t\t\t\t\tdrawable.rebuildRenderFlags();\n\t\t\t\t\tif (!drawable.renderFlags.culled) {\n\t\t\t\t\t\tdrawableList[lenDrawableList++] = drawable;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdrawableList.length = lenDrawableList;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction draw(params) {\n\t\tconst sao = scene.sao;\n\n\t\tif (saoEnabled && sao.possible) {\n\t\t\tdrawSAOBuffers(params);\n\t\t}\n\n\t\tdrawShadowMaps();\n\n\t\tdrawColor(params);\n\t}\n\n\tfunction drawSAOBuffers(params) {\n\t\tconst sao = scene.sao;\n\n\t\t// Render depth buffer\n\n\t\tconst saoDepthRenderBuffer = renderBufferManager.getRenderBuffer(\"saoDepth\", {\n\t\t\tdepthTexture: true\n\t\t});\n\n\t\tsaoDepthRenderBuffer.bind();\n\t\tsaoDepthRenderBuffer.clear();\n\t\tdrawDepth(params);\n\t\tsaoDepthRenderBuffer.unbind();\n\n\t\t// Render occlusion buffer\n\n\t\tconst occlusionRenderBuffer1 = renderBufferManager.getRenderBuffer(\"saoOcclusion\");\n\n\t\tocclusionRenderBuffer1.bind();\n\t\tocclusionRenderBuffer1.clear();\n\t\tsaoOcclusionRenderer.render(saoDepthRenderBuffer);\n\t\tocclusionRenderBuffer1.unbind();\n\n\t\tif (sao.blur) {\n\t\t\t// Horizontally blur occlusion buffer 1 into occlusion buffer 2\n\n\t\t\tconst occlusionRenderBuffer2 = renderBufferManager.getRenderBuffer(\"saoOcclusion2\");\n\n\t\t\tocclusionRenderBuffer2.bind();\n\t\t\tocclusionRenderBuffer2.clear();\n\t\t\tsaoDepthLimitedBlurRenderer.render(saoDepthRenderBuffer, occlusionRenderBuffer1, 0);\n\t\t\tocclusionRenderBuffer2.unbind();\n\n\t\t\t// Vertically blur occlusion buffer 2 back into occlusion buffer 1\n\n\t\t\tocclusionRenderBuffer1.bind();\n\t\t\tocclusionRenderBuffer1.clear();\n\t\t\tsaoDepthLimitedBlurRenderer.render(saoDepthRenderBuffer, occlusionRenderBuffer2, 1);\n\t\t\tocclusionRenderBuffer1.unbind();\n\t\t}\n\t}\n\n\tfunction drawDepth(params) {\n\t\tframeCtx.reset();\n\t\tframeCtx.pass = params.pass;\n\n\t\tgl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\n\t\tgl.clearColor(0, 0, 0, 0);\n\t\tgl.enable(gl.DEPTH_TEST);\n\t\tgl.frontFace(gl.CCW);\n\t\tgl.enable(gl.CULL_FACE);\n\t\t// gl.disable(gl.CULL_FACE);\n\t\tgl.depthMask(true);\n\n\t\tif (params.clear !== false) {\n\t\t\tgl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\t\t}\n\n\t\tfor (let type in drawableTypeInfo) {\n\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\t\tconst drawableList = drawableInfo.drawableList;\n\n\t\t\t\tfor (let i = 0, len = drawableList.length; i < len; i++) {\n\t\t\t\t\tconst drawable = drawableList[i];\n\n\t\t\t\t\tif (drawable.culled === true || drawable.visible === false || !drawable.drawDepth || !drawable.saoEnabled) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawable.renderFlags.colorOpaque) {\n\t\t\t\t\t\tdrawable.drawDepth(frameCtx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// const numVertexAttribs = WEBGL_INFO.MAX_VERTEX_ATTRIBS; // Fixes https://github.com/xeokit/xeokit-sdk/issues/174\n\t\t// for (let ii = 0; ii < numVertexAttribs; ii++) {\n\t\t// gl.disableVertexAttribArray(ii);\n\t\t// }\n\t}\n\n\tfunction drawShadowMaps() {\n\t\tlet lights = scene._lightsState.lights;\n\n\t\tfor (let i = 0, len = lights.length; i < len; i++) {\n\t\t\tconst light = lights[i];\n\t\t\tif (!light.castsShadow) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tdrawShadowMap(light);\n\t\t}\n\n\t\t// const numVertexAttribs = WEBGL_INFO.MAX_VERTEX_ATTRIBS; // Fixes https://github.com/xeokit/xeokit-sdk/issues/174\n\t\t// for (let ii = 0; ii < numVertexAttribs; ii++) {\n\t\t// gl.disableVertexAttribArray(ii);\n\t\t// }\n\t\t//\n\t\tshadowsDirty = false;\n\t}\n\n\tfunction drawShadowMap(light) {\n\t\tconst castsShadow = light.castsShadow;\n\n\t\tif (!castsShadow) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst shadowRenderBuf = light.getShadowRenderBuf();\n\n\t\tif (!shadowRenderBuf) {\n\t\t\treturn;\n\t\t}\n\n\t\tshadowRenderBuf.bind();\n\n\t\tframeCtx.reset();\n\n\t\tframeCtx.backfaces = true;\n\t\tframeCtx.frontface = true;\n\t\tframeCtx.shadowViewMatrix = light.getShadowViewMatrix();\n\t\tframeCtx.shadowProjMatrix = light.getShadowProjMatrix();\n\n\t\tgl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\n\t\tgl.clearColor(0, 0, 0, 1);\n\t\tgl.enable(gl.DEPTH_TEST);\n\t\tgl.disable(gl.BLEND);\n\n\t\tgl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n\t\tfor (let type in drawableTypeInfo) {\n\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\t\tconst drawableList = drawableInfo.drawableList;\n\n\t\t\t\tfor (let i = 0, len = drawableList.length; i < len; i++) {\n\t\t\t\t\tconst drawable = drawableList[i];\n\n\t\t\t\t\tif (drawable.visible === false || !drawable.castsShadow || !drawable.drawShadow) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawable.renderFlags.colorOpaque) {\n\t\t\t\t\t\t// Transparent objects don't cast shadows (yet)\n\t\t\t\t\t\tdrawable.drawShadow(frameCtx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tshadowRenderBuf.unbind();\n\t}\n\n\tfunction drawColor(params) {\n\t\tconst normalDrawSAOBin = [];\n\t\tconst normalEdgesOpaqueBin = [];\n\t\tconst normalFillTransparentBin = [];\n\t\tconst normalEdgesTransparentBin = [];\n\n\t\tconst xrayedFillOpaqueBin = [];\n\t\tconst xrayEdgesOpaqueBin = [];\n\t\tconst xrayedFillTransparentBin = [];\n\t\tconst xrayEdgesTransparentBin = [];\n\n\t\tconst highlightedFillOpaqueBin = [];\n\t\tconst highlightedEdgesOpaqueBin = [];\n\t\tconst highlightedFillTransparentBin = [];\n\t\tconst highlightedEdgesTransparentBin = [];\n\n\t\tconst selectedFillOpaqueBin = [];\n\t\tconst selectedEdgesOpaqueBin = [];\n\t\tconst selectedFillTransparentBin = [];\n\t\tconst selectedEdgesTransparentBin = [];\n\n\t\tconst ambientColorAndIntensity = scene._lightsState.getAmbientColorAndIntensity();\n\n\t\tframeCtx.reset();\n\t\tframeCtx.pass = params.pass;\n\t\tframeCtx.withSAO = false;\n\t\tframeCtx.pbrEnabled = pbrEnabled && !!scene.pbrEnabled;\n\t\tframeCtx.colorTextureEnabled = colorTextureEnabled && !!scene.colorTextureEnabled;\n\n\t\tgl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\n\t\tif (canvasTransparent) {\n\t\t\tgl.clearColor(0, 0, 0, 0);\n\t\t} else {\n\t\t\tconst backgroundColor = scene.canvas.backgroundColorFromAmbientLight\n\t\t\t\t? ambientColorAndIntensity\n\t\t\t\t: scene.canvas.backgroundColor;\n\t\t\tgl.clearColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], 1.0);\n\t\t}\n\n\t\tgl.enable(gl.DEPTH_TEST);\n\t\tgl.frontFace(gl.CCW);\n\t\tgl.enable(gl.CULL_FACE);\n\t\t// gl.disable(gl.CULL_FACE);\n\t\tgl.depthMask(true);\n\t\tgl.lineWidth(1);\n\n\t\tframeCtx.lineWidth = 1;\n\n\t\tconst saoPossible = scene.sao.possible;\n\n\t\tif (saoEnabled && saoPossible) {\n\t\t\tconst occlusionRenderBuffer1 = renderBufferManager.getRenderBuffer(\"saoOcclusion\");\n\t\t\tframeCtx.occlusionTexture = occlusionRenderBuffer1 ? occlusionRenderBuffer1.getTexture() : null;\n\t\t} else {\n\t\t\tframeCtx.occlusionTexture = null;\n\t\t}\n\n\t\tlet i;\n\t\tlet len;\n\t\tlet drawable;\n\n\t\tconst startTime = Date.now();\n\n\t\tif (bindOutputFrameBuffer) {\n\t\t\tbindOutputFrameBuffer(params.pass);\n\t\t}\n\n\t\tif (params.clear !== false) {\n\t\t\tgl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\t\t}\n\n\t\tlet normalDrawSAOBinLen = 0;\n\t\tlet normalEdgesOpaqueBinLen = 0;\n\t\tlet normalFillTransparentBinLen = 0;\n\t\tlet normalEdgesTransparentBinLen = 0;\n\n\t\tlet xrayedFillOpaqueBinLen = 0;\n\t\tlet xrayEdgesOpaqueBinLen = 0;\n\t\tlet xrayedFillTransparentBinLen = 0;\n\t\tlet xrayEdgesTransparentBinLen = 0;\n\n\t\tlet highlightedFillOpaqueBinLen = 0;\n\t\tlet highlightedEdgesOpaqueBinLen = 0;\n\t\tlet highlightedFillTransparentBinLen = 0;\n\t\tlet highlightedEdgesTransparentBinLen = 0;\n\n\t\tlet selectedFillOpaqueBinLen = 0;\n\t\tlet selectedEdgesOpaqueBinLen = 0;\n\t\tlet selectedFillTransparentBinLen = 0;\n\t\tlet selectedEdgesTransparentBinLen = 0;\n\n\t\t//------------------------------------------------------------------------------------------------------\n\t\t// Render normal opaque solids, defer others to bins to render after\n\t\t//------------------------------------------------------------------------------------------------------\n\n\t\tfor (let type in drawableTypeInfo) {\n\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\t\tconst drawableList = drawableInfo.drawableList;\n\n\t\t\t\tfor (i = 0, len = drawableList.length; i < len; i++) {\n\t\t\t\t\tdrawable = drawableList[i];\n\n\t\t\t\t\tif (drawable.culled === true || drawable.visible === false) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst renderFlags = drawable.renderFlags;\n\n\t\t\t\t\tif (renderFlags.colorOpaque) {\n\t\t\t\t\t\tif (saoEnabled && saoPossible && drawable.saoEnabled) {\n\t\t\t\t\t\t\tnormalDrawSAOBin[normalDrawSAOBinLen++] = drawable;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdrawable.drawColorOpaque(frameCtx);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (transparentEnabled) {\n\t\t\t\t\t\tif (renderFlags.colorTransparent) {\n\t\t\t\t\t\t\tnormalFillTransparentBin[normalFillTransparentBinLen++] = drawable;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (renderFlags.xrayedSilhouetteTransparent) {\n\t\t\t\t\t\txrayedFillTransparentBin[xrayedFillTransparentBinLen++] = drawable;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (renderFlags.xrayedSilhouetteOpaque) {\n\t\t\t\t\t\txrayedFillOpaqueBin[xrayedFillOpaqueBinLen++] = drawable;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (renderFlags.highlightedSilhouetteTransparent) {\n\t\t\t\t\t\thighlightedFillTransparentBin[highlightedFillTransparentBinLen++] = drawable;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (renderFlags.highlightedSilhouetteOpaque) {\n\t\t\t\t\t\thighlightedFillOpaqueBin[highlightedFillOpaqueBinLen++] = drawable;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (renderFlags.selectedSilhouetteTransparent) {\n\t\t\t\t\t\tselectedFillTransparentBin[selectedFillTransparentBinLen++] = drawable;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (renderFlags.selectedSilhouetteOpaque) {\n\t\t\t\t\t\tselectedFillOpaqueBin[selectedFillOpaqueBinLen++] = drawable;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawable.edges && edgesEnabled) {\n\t\t\t\t\t\tif (renderFlags.edgesOpaque) {\n\t\t\t\t\t\t\tnormalEdgesOpaqueBin[normalEdgesOpaqueBinLen++] = drawable;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (renderFlags.edgesTransparent) {\n\t\t\t\t\t\t\tnormalEdgesTransparentBin[normalEdgesTransparentBinLen++] = drawable;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (renderFlags.selectedEdgesTransparent) {\n\t\t\t\t\t\t\tselectedEdgesTransparentBin[selectedEdgesTransparentBinLen++] = drawable;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (renderFlags.selectedEdgesOpaque) {\n\t\t\t\t\t\t\tselectedEdgesOpaqueBin[selectedEdgesOpaqueBinLen++] = drawable;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (renderFlags.xrayedEdgesTransparent) {\n\t\t\t\t\t\t\txrayEdgesTransparentBin[xrayEdgesTransparentBinLen++] = drawable;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (renderFlags.xrayedEdgesOpaque) {\n\t\t\t\t\t\t\txrayEdgesOpaqueBin[xrayEdgesOpaqueBinLen++] = drawable;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (renderFlags.highlightedEdgesTransparent) {\n\t\t\t\t\t\t\thighlightedEdgesTransparentBin[highlightedEdgesTransparentBinLen++] = drawable;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (renderFlags.highlightedEdgesOpaque) {\n\t\t\t\t\t\t\thighlightedEdgesOpaqueBin[highlightedEdgesOpaqueBinLen++] = drawable;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//------------------------------------------------------------------------------------------------------\n\t\t// Render deferred bins\n\t\t//------------------------------------------------------------------------------------------------------\n\n\t\t// Opaque color with SAO\n\n\t\tif (normalDrawSAOBinLen > 0) {\n\t\t\tframeCtx.withSAO = true;\n\t\t\tfor (i = 0; i < normalDrawSAOBinLen; i++) {\n\t\t\t\tnormalDrawSAOBin[i].drawColorOpaque(frameCtx);\n\t\t\t}\n\t\t}\n\n\t\t// Opaque edges\n\n\t\tif (normalEdgesOpaqueBinLen > 0) {\n\t\t\tfor (i = 0; i < normalEdgesOpaqueBinLen; i++) {\n\t\t\t\tnormalEdgesOpaqueBin[i].drawEdgesColorOpaque(frameCtx);\n\t\t\t}\n\t\t}\n\n\t\t// Opaque X-ray fill\n\n\t\tif (xrayedFillOpaqueBinLen > 0) {\n\t\t\tfor (i = 0; i < xrayedFillOpaqueBinLen; i++) {\n\t\t\t\txrayedFillOpaqueBin[i].drawSilhouetteXRayed(frameCtx);\n\t\t\t}\n\t\t}\n\n\t\t// Opaque X-ray edges\n\n\t\tif (xrayEdgesOpaqueBinLen > 0) {\n\t\t\tfor (i = 0; i < xrayEdgesOpaqueBinLen; i++) {\n\t\t\t\txrayEdgesOpaqueBin[i].drawEdgesXRayed(frameCtx);\n\t\t\t}\n\t\t}\n\n\t\t// Transparent\n\n\t\tif (\n\t\t\txrayedFillTransparentBinLen > 0 ||\n\t\t\txrayEdgesTransparentBinLen > 0 ||\n\t\t\tnormalFillTransparentBinLen > 0 ||\n\t\t\tnormalEdgesTransparentBinLen > 0\n\t\t) {\n\t\t\tgl.enable(gl.CULL_FACE);\n\t\t\t// gl.disable(gl.CULL_FACE);\n\t\t\tgl.enable(gl.BLEND);\n\t\t\tif (canvasTransparent) {\n\t\t\t\tgl.blendEquation(gl.FUNC_ADD);\n\t\t\t\tgl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\t\t\t} else {\n\t\t\t\tgl.blendEquation(gl.FUNC_ADD);\n\t\t\t\tgl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\t\t\t}\n\t\t\tframeCtx.backfaces = false;\n\t\t\tif (!alphaDepthMask) {\n\t\t\t\tgl.depthMask(false);\n\t\t\t}\n\n\t\t\t// Transparent color edges\n\n\t\t\tif (normalFillTransparentBinLen > 0 || normalEdgesTransparentBinLen > 0) {\n\t\t\t\tgl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\t\t\t}\n\t\t\tif (normalEdgesTransparentBinLen > 0) {\n\t\t\t\tfor (i = 0; i < normalEdgesTransparentBinLen; i++) {\n\t\t\t\t\tdrawable = normalEdgesTransparentBin[i];\n\t\t\t\t\tdrawable.drawEdgesColorTransparent(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Transparent color fill\n\n\t\t\tif (normalFillTransparentBinLen > 0) {\n\t\t\t\tfor (i = 0; i < normalFillTransparentBinLen; i++) {\n\t\t\t\t\tdrawable = normalFillTransparentBin[i];\n\t\t\t\t\tdrawable.drawColorTransparent(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Transparent X-ray edges\n\n\t\t\tif (xrayEdgesTransparentBinLen > 0) {\n\t\t\t\tfor (i = 0; i < xrayEdgesTransparentBinLen; i++) {\n\t\t\t\t\txrayEdgesTransparentBin[i].drawEdgesXRayed(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Transparent X-ray fill\n\n\t\t\tif (xrayedFillTransparentBinLen > 0) {\n\t\t\t\tfor (i = 0; i < xrayedFillTransparentBinLen; i++) {\n\t\t\t\t\txrayedFillTransparentBin[i].drawSilhouetteXRayed(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tgl.disable(gl.BLEND);\n\t\t\tif (!alphaDepthMask) {\n\t\t\t\tgl.depthMask(true);\n\t\t\t}\n\t\t}\n\n\t\t// Opaque highlight\n\n\t\tif (highlightedFillOpaqueBinLen > 0 || highlightedEdgesOpaqueBinLen > 0) {\n\t\t\tframeCtx.lastProgramId = null;\n\t\t\tif (scene.highlightMaterial.glowThrough) {\n\t\t\t\tgl.clear(gl.DEPTH_BUFFER_BIT);\n\t\t\t}\n\n\t\t\t// Opaque highlighted edges\n\n\t\t\tif (highlightedEdgesOpaqueBinLen > 0) {\n\t\t\t\tfor (i = 0; i < highlightedEdgesOpaqueBinLen; i++) {\n\t\t\t\t\thighlightedEdgesOpaqueBin[i].drawEdgesHighlighted(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Opaque highlighted fill\n\n\t\t\tif (highlightedFillOpaqueBinLen > 0) {\n\t\t\t\tfor (i = 0; i < highlightedFillOpaqueBinLen; i++) {\n\t\t\t\t\thighlightedFillOpaqueBin[i].drawSilhouetteHighlighted(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Highlighted transparent\n\n\t\tif (\n\t\t\thighlightedFillTransparentBinLen > 0 ||\n\t\t\thighlightedEdgesTransparentBinLen > 0 ||\n\t\t\thighlightedFillOpaqueBinLen > 0\n\t\t) {\n\t\t\tframeCtx.lastProgramId = null;\n\t\t\tif (scene.selectedMaterial.glowThrough) {\n\t\t\t\tgl.clear(gl.DEPTH_BUFFER_BIT);\n\t\t\t}\n\t\t\tgl.enable(gl.BLEND);\n\t\t\tif (canvasTransparent) {\n\t\t\t\tgl.blendEquation(gl.FUNC_ADD);\n\t\t\t\tgl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\t\t\t} else {\n\t\t\t\tgl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\t\t\t}\n\t\t\t// gl.disable(gl.CULL_FACE);\n\t\t\tgl.enable(gl.CULL_FACE);\n\n\t\t\t// Highlighted transparent edges\n\n\t\t\tif (highlightedEdgesTransparentBinLen > 0) {\n\t\t\t\tfor (i = 0; i < highlightedEdgesTransparentBinLen; i++) {\n\t\t\t\t\thighlightedEdgesTransparentBin[i].drawEdgesHighlighted(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Highlighted transparent fill\n\n\t\t\tif (highlightedFillTransparentBinLen > 0) {\n\t\t\t\tfor (i = 0; i < highlightedFillTransparentBinLen; i++) {\n\t\t\t\t\thighlightedFillTransparentBin[i].drawSilhouetteHighlighted(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\t\t\tgl.disable(gl.BLEND);\n\t\t}\n\n\t\t// Selected opaque\n\n\t\tif (selectedFillOpaqueBinLen > 0 || selectedEdgesOpaqueBinLen > 0) {\n\t\t\tframeCtx.lastProgramId = null;\n\t\t\tif (scene.selectedMaterial.glowThrough) {\n\t\t\t\tgl.clear(gl.DEPTH_BUFFER_BIT);\n\t\t\t}\n\n\t\t\t// Selected opaque fill\n\n\t\t\tif (selectedEdgesOpaqueBinLen > 0) {\n\t\t\t\tfor (i = 0; i < selectedEdgesOpaqueBinLen; i++) {\n\t\t\t\t\tselectedEdgesOpaqueBin[i].drawEdgesSelected(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Selected opaque edges\n\n\t\t\tif (selectedFillOpaqueBinLen > 0) {\n\t\t\t\tfor (i = 0; i < selectedFillOpaqueBinLen; i++) {\n\t\t\t\t\tselectedFillOpaqueBin[i].drawSilhouetteSelected(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Selected transparent\n\n\t\tif (selectedFillTransparentBinLen > 0 || selectedEdgesTransparentBinLen > 0) {\n\t\t\tframeCtx.lastProgramId = null;\n\t\t\tif (scene.selectedMaterial.glowThrough) {\n\t\t\t\tgl.clear(gl.DEPTH_BUFFER_BIT);\n\t\t\t}\n\t\t\t// gl.disable(gl.CULL_FACE);\n\t\t\tgl.enable(gl.CULL_FACE);\n\t\t\tgl.enable(gl.BLEND);\n\t\t\tif (canvasTransparent) {\n\t\t\t\tgl.blendEquation(gl.FUNC_ADD);\n\t\t\t\tgl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\t\t\t} else {\n\t\t\t\tgl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\t\t\t}\n\n\t\t\t// Selected transparent edges\n\n\t\t\tif (selectedEdgesTransparentBinLen > 0) {\n\t\t\t\tfor (i = 0; i < selectedEdgesTransparentBinLen; i++) {\n\t\t\t\t\tselectedEdgesTransparentBin[i].drawEdgesSelected(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Selected transparent fill\n\n\t\t\tif (selectedFillTransparentBinLen > 0) {\n\t\t\t\tfor (i = 0; i < selectedFillTransparentBinLen; i++) {\n\t\t\t\t\tselectedFillTransparentBin[i].drawSilhouetteSelected(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\t\t\tgl.disable(gl.BLEND);\n\t\t}\n\n\t\tconst endTime = Date.now();\n\t\tconst frameStats = _stats_js__WEBPACK_IMPORTED_MODULE_2__.stats.frame;\n\n\t\tframeStats.renderTime = (endTime - startTime) / 1000.0;\n\t\tframeStats.drawElements = frameCtx.drawElements;\n\t\tframeStats.drawArrays = frameCtx.drawArrays;\n\t\tframeStats.useProgram = frameCtx.useProgram;\n\t\tframeStats.bindTexture = frameCtx.bindTexture;\n\t\tframeStats.bindArray = frameCtx.bindArray;\n\n\t\tconst numTextureUnits = _webglInfo_js__WEBPACK_IMPORTED_MODULE_3__.WEBGL_INFO.MAX_TEXTURE_IMAGE_UNITS;\n\t\tfor (let ii = 0; ii < numTextureUnits; ii++) {\n\t\t\tgl.activeTexture(gl.TEXTURE0 + ii);\n\t\t}\n\t\tgl.bindTexture(gl.TEXTURE_CUBE_MAP, null);\n\t\tgl.bindTexture(gl.TEXTURE_2D, null);\n\n\t\tconst numVertexAttribs = _webglInfo_js__WEBPACK_IMPORTED_MODULE_3__.WEBGL_INFO.MAX_VERTEX_ATTRIBS; // Fixes https://github.com/xeokit/xeokit-sdk/issues/174\n\t\tfor (let ii = 0; ii < numVertexAttribs; ii++) {\n\t\t\tgl.disableVertexAttribArray(ii);\n\t\t}\n\n\t\tif (unbindOutputFrameBuffer) {\n\t\t\tunbindOutputFrameBuffer(params.pass);\n\t\t}\n\t}\n\n\t/**\n\t * Picks an Entity.\n\t * @private\n\t */\n\tthis.pick = (function () {\n\t\tconst tempVec3a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\t\tconst tempMat4a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\tconst tempMat4b = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\n\t\tconst randomVec3 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\t\tconst up = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3([0, 1, 0]);\n\t\tconst _pickResult = new _PickResult_js__WEBPACK_IMPORTED_MODULE_5__.PickResult();\n\n\t\tconst nearAndFar = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec2();\n\n\t\tconst canvasPos = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\n\t\tconst worldRayOrigin = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\t\tconst worldRayDir = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\t\tconst worldSurfacePos = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\t\tconst worldSurfaceNormal = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec3();\n\n\t\treturn function (params, pickResult = _pickResult) {\n\t\t\tpickResult.reset();\n\n\t\t\tupdateDrawlist();\n\n\t\t\tlet look;\n\t\t\tlet pickViewMatrix = null;\n\t\t\tlet pickProjMatrix = null;\n\n\t\t\tpickResult.pickSurface = params.pickSurface;\n\n\t\t\tif (params.canvasPos) {\n\t\t\t\tcanvasPos[0] = params.canvasPos[0];\n\t\t\t\tcanvasPos[1] = params.canvasPos[1];\n\n\t\t\t\tpickViewMatrix = scene.camera.viewMatrix;\n\t\t\t\tpickProjMatrix = scene.camera.projMatrix;\n\n\t\t\t\tpickResult.canvasPos = params.canvasPos;\n\t\t\t} else {\n\t\t\t\t// Picking with arbitrary World-space ray\n\t\t\t\t// Align camera along ray and fire ray through center of canvas\n\n\t\t\t\tif (params.matrix) {\n\t\t\t\t\tpickViewMatrix = params.matrix;\n\t\t\t\t\tpickProjMatrix = scene.camera.projMatrix;\n\t\t\t\t} else {\n\t\t\t\t\tworldRayOrigin.set(params.origin || [0, 0, 0]);\n\t\t\t\t\tworldRayDir.set(params.direction || [0, 0, 1]);\n\n\t\t\t\t\tlook = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(worldRayOrigin, worldRayDir, tempVec3a);\n\n\t\t\t\t\trandomVec3[0] = Math.random();\n\t\t\t\t\trandomVec3[1] = Math.random();\n\t\t\t\t\trandomVec3[2] = Math.random();\n\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3(randomVec3);\n\t\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.cross3Vec3(worldRayDir, randomVec3, up);\n\n\t\t\t\t\tpickViewMatrix = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.lookAtMat4v(worldRayOrigin, look, up, tempMat4b);\n\t\t\t\t\t// pickProjMatrix = scene.camera.projMatrix;\n\t\t\t\t\tpickProjMatrix = scene.camera.ortho.matrix;\n\n\t\t\t\t\tpickResult.origin = worldRayOrigin;\n\t\t\t\t\tpickResult.direction = worldRayDir;\n\t\t\t\t}\n\n\t\t\t\tcanvasPos[0] = canvas.clientWidth * 0.5;\n\t\t\t\tcanvasPos[1] = canvas.clientHeight * 0.5;\n\t\t\t}\n\n\t\t\tfor (let type in drawableTypeInfo) {\n\t\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\t\tconst drawableList = drawableTypeInfo[type].drawableList;\n\t\t\t\t\tfor (let i = 0, len = drawableList.length; i < len; i++) {\n\t\t\t\t\t\tconst drawable = drawableList[i];\n\t\t\t\t\t\tif (drawable.setPickMatrices) {\n\t\t\t\t\t\t\t// Eg. SceneModel, which needs pre-loading into texture\n\t\t\t\t\t\t\tdrawable.setPickMatrices(pickViewMatrix, pickProjMatrix);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pickBuffer = renderBufferManager.getRenderBuffer(\"pick\", { size: [1, 1] });\n\n\t\t\tpickBuffer.bind();\n\n\t\t\tconst pickable = gpuPickPickable(pickBuffer, canvasPos, pickViewMatrix, pickProjMatrix, params, pickResult);\n\n\t\t\tif (!pickable) {\n\t\t\t\tpickBuffer.unbind();\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst pickedEntity = pickable.delegatePickedEntity ? pickable.delegatePickedEntity() : pickable;\n\n\t\t\tif (!pickedEntity) {\n\t\t\t\tpickBuffer.unbind();\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (params.pickSurface) {\n\t\t\t\t// GPU-based ray-picking\n\n\t\t\t\tif (pickable.canPickTriangle && pickable.canPickTriangle()) {\n\t\t\t\t\tgpuPickTriangle(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, pickResult);\n\n\t\t\t\t\tpickable.pickTriangleSurface(pickViewMatrix, pickProjMatrix, pickResult);\n\n\t\t\t\t\tpickResult.pickSurfacePrecision = false;\n\t\t\t\t} else {\n\t\t\t\t\tif (pickable.canPickWorldPos && pickable.canPickWorldPos()) {\n\t\t\t\t\t\tnearAndFar[0] = scene.camera.project.near;\n\t\t\t\t\t\tnearAndFar[1] = scene.camera.project.far;\n\n\t\t\t\t\t\tgpuPickWorldPos(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, nearAndFar, pickResult);\n\n\t\t\t\t\t\tif (params.pickSurfaceNormal !== false) {\n\t\t\t\t\t\t\tgpuPickWorldNormal(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, pickResult);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpickResult.pickSurfacePrecision = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tpickBuffer.unbind();\n\t\t\tpickResult.entity = pickedEntity;\n\t\t\treturn pickResult;\n\t\t};\n\t})();\n\n\tfunction gpuPickPickable(pickBuffer, canvasPos, pickViewMatrix, pickProjMatrix, params, pickResult) {\n\t\tconst resolutionScale = scene.canvas.resolutionScale;\n\n\t\tframeCtx.reset();\n\t\tframeCtx.backfaces = true;\n\t\tframeCtx.frontface = true; // \"ccw\"\n\t\tframeCtx.pickOrigin = pickResult.origin;\n\t\tframeCtx.pickViewMatrix = pickViewMatrix;\n\t\tframeCtx.pickProjMatrix = pickProjMatrix;\n\t\tframeCtx.pickInvisible = !!params.pickInvisible;\n\t\tframeCtx.pickClipPos = [\n\t\t\tgetClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\n\t\t\tgetClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight)\n\t\t];\n\n\t\tgl.viewport(0, 0, 1, 1);\n\t\tgl.depthMask(true);\n\t\tgl.enable(gl.DEPTH_TEST);\n\t\tgl.disable(gl.CULL_FACE);\n\t\tgl.disable(gl.BLEND);\n\t\tgl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n\t\tconst includeEntityIds = params.includeEntityIds;\n\t\tconst excludeEntityIds = params.excludeEntityIds;\n\n\t\tfor (let type in drawableTypeInfo) {\n\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\t\tconst drawableList = drawableInfo.drawableList;\n\n\t\t\t\tfor (let i = 0, len = drawableList.length; i < len; i++) {\n\t\t\t\t\tconst drawable = drawableList[i];\n\n\t\t\t\t\tif (\n\t\t\t\t\t\t!drawable.drawPickMesh ||\n\t\t\t\t\t\t(params.pickInvisible !== true && drawable.visible === false) ||\n\t\t\t\t\t\tdrawable.pickable === false\n\t\t\t\t\t) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (includeEntityIds && !includeEntityIds[drawable.id]) {\n\t\t\t\t\t\t// TODO: push this logic into drawable\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (excludeEntityIds && excludeEntityIds[drawable.id]) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tdrawable.drawPickMesh(frameCtx);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst pix = pickBuffer.read(0, 0);\n\t\tconst pickID = pix[0] + (pix[1] << 8) + (pix[2] << 16) + (pix[3] << 24);\n\n\t\tif (pickID < 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pickable = pickIDs.items[pickID];\n\n\t\treturn pickable;\n\t}\n\n\tfunction gpuPickTriangle(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, pickResult) {\n\t\tif (!pickable.drawPickTriangles) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst resolutionScale = scene.canvas.resolutionScale;\n\n\t\tframeCtx.reset();\n\t\tframeCtx.backfaces = true;\n\t\tframeCtx.frontface = true; // \"ccw\"\n\t\tframeCtx.pickOrigin = pickResult.origin;\n\t\tframeCtx.pickViewMatrix = pickViewMatrix; // Can be null\n\t\tframeCtx.pickProjMatrix = pickProjMatrix; // Can be null\n\t\t// frameCtx.pickInvisible = !!params.pickInvisible;\n\t\tframeCtx.pickClipPos = [\n\t\t\tgetClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\n\t\t\tgetClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight)\n\t\t];\n\n\t\tgl.viewport(0, 0, 1, 1);\n\n\t\tgl.clearColor(0, 0, 0, 0);\n\t\tgl.enable(gl.DEPTH_TEST);\n\t\tgl.disable(gl.CULL_FACE);\n\t\tgl.disable(gl.BLEND);\n\t\tgl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n\t\tpickable.drawPickTriangles(frameCtx);\n\n\t\tconst pix = pickBuffer.read(0, 0);\n\n\t\tlet primIndex = pix[0] + pix[1] * 256 + pix[2] * 256 * 256 + pix[3] * 256 * 256 * 256;\n\n\t\tprimIndex *= 3; // Convert from triangle number to first vertex in indices\n\n\t\tpickResult.primIndex = primIndex;\n\t}\n\n\tconst gpuPickWorldPos = (function () {\n\t\tconst tempVec4a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\n\t\tconst tempVec4b = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\n\t\tconst tempVec4c = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\n\t\tconst tempVec4d = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\n\t\tconst tempVec4e = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.vec4();\n\t\tconst tempMat4a = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\tconst tempMat4b = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\t\tconst tempMat4c = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mat4();\n\n\t\treturn function (pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, nearAndFar, pickResult) {\n\t\t\tconst resolutionScale = scene.canvas.resolutionScale;\n\n\t\t\tframeCtx.reset();\n\t\t\tframeCtx.backfaces = true;\n\t\t\tframeCtx.frontface = true; // \"ccw\"\n\t\t\tframeCtx.pickOrigin = pickResult.origin;\n\t\t\tframeCtx.pickViewMatrix = pickViewMatrix;\n\t\t\tframeCtx.pickProjMatrix = pickProjMatrix;\n\t\t\tframeCtx.pickZNear = nearAndFar[0];\n\t\t\tframeCtx.pickZFar = nearAndFar[1];\n\t\t\tframeCtx.pickElementsCount = pickable.pickElementsCount;\n\t\t\tframeCtx.pickElementsOffset = pickable.pickElementsOffset;\n\t\t\tframeCtx.pickClipPos = [\n\t\t\t\tgetClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\n\t\t\t\tgetClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight)\n\t\t\t];\n\n\t\t\tgl.viewport(0, 0, 1, 1);\n\n\t\t\tgl.clearColor(0, 0, 0, 0);\n\t\t\tgl.depthMask(true);\n\t\t\tgl.enable(gl.DEPTH_TEST);\n\t\t\tgl.disable(gl.CULL_FACE);\n\t\t\tgl.disable(gl.BLEND);\n\t\t\tgl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n\t\t\tpickable.drawPickDepths(frameCtx); // Draw color-encoded fragment screen-space depths\n\n\t\t\tconst pix = pickBuffer.read(0, 0);\n\n\t\t\tconst screenZ = unpackDepth(pix); // Get screen-space Z at the given canvas coords\n\n\t\t\t// Calculate clip space coordinates, which will be in range of x=[-1..1] and y=[-1..1], with y=(+1) at top\n\t\t\tconst x = (canvasPos[0] - canvas.clientWidth / 2) / (canvas.clientWidth / 2);\n\t\t\tconst y = -(canvasPos[1] - canvas.clientHeight / 2) / (canvas.clientHeight / 2);\n\n\t\t\tconst origin = pickable.origin;\n\t\t\tlet pvMat;\n\n\t\t\tif (origin) {\n\t\t\t\tconst rtcPickViewMat = (0,_math_rtcCoords_js__WEBPACK_IMPORTED_MODULE_8__.createRTCViewMat)(pickViewMatrix, origin, tempMat4a);\n\t\t\t\tpvMat = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulMat4(pickProjMatrix, rtcPickViewMat, tempMat4b);\n\t\t\t} else {\n\t\t\t\tpvMat = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulMat4(pickProjMatrix, pickViewMatrix, tempMat4b);\n\t\t\t}\n\n\t\t\tconst pvMatInverse = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.inverseMat4(pvMat, tempMat4c);\n\n\t\t\ttempVec4a[0] = x;\n\t\t\ttempVec4a[1] = y;\n\t\t\ttempVec4a[2] = -1;\n\t\t\ttempVec4a[3] = 1;\n\n\t\t\tlet world1 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec4(pvMatInverse, tempVec4a);\n\t\t\tworld1 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulVec4Scalar(world1, 1 / world1[3]);\n\n\t\t\ttempVec4b[0] = x;\n\t\t\ttempVec4b[1] = y;\n\t\t\ttempVec4b[2] = 1;\n\t\t\ttempVec4b[3] = 1;\n\n\t\t\tlet world2 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.transformVec4(pvMatInverse, tempVec4b);\n\t\t\tworld2 = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulVec4Scalar(world2, 1 / world2[3]);\n\n\t\t\tconst dir = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.subVec3(world2, world1, tempVec4c);\n\t\t\tconst worldPos = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(world1, _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.mulVec4Scalar(dir, screenZ, tempVec4d), tempVec4e);\n\n\t\t\tif (origin) {\n\t\t\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.addVec3(worldPos, origin);\n\t\t\t}\n\n\t\t\tpickResult.worldPos = worldPos;\n\t\t};\n\t})();\n\n\tfunction drawSnapInit(frameCtx) {\n\t\tframeCtx.snapPickLayerParams = [];\n\t\tframeCtx.snapPickLayerNumber = 0;\n\t\tfor (let type in drawableTypeInfo) {\n\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\tconst drawableList = drawableInfo.drawableList;\n\t\t\tfor (let i = 0, len = drawableList.length; i < len; i++) {\n\t\t\t\tconst drawable = drawableList[i];\n\t\t\t\tif (drawable.drawSnapInit) {\n\t\t\t\t\tif (!drawable.culled && drawable.visible && drawable.pickable) {\n\t\t\t\t\t\tdrawable.drawSnapInit(frameCtx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn frameCtx.snapPickLayerParams;\n\t}\n\n\tfunction drawSnap(frameCtx) {\n\t\tframeCtx.snapPickLayerParams = frameCtx.snapPickLayerParams || [];\n\t\tframeCtx.snapPickLayerNumber = frameCtx.snapPickLayerParams.length;\n\t\tfor (let type in drawableTypeInfo) {\n\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\tconst drawableList = drawableInfo.drawableList;\n\t\t\tfor (let i = 0, len = drawableList.length; i < len; i++) {\n\t\t\t\tconst drawable = drawableList[i];\n\t\t\t\tif (drawable.drawSnap) {\n\t\t\t\t\tif (!drawable.culled && drawable.visible && drawable.pickable) {\n\t\t\t\t\t\tdrawable.drawSnap(frameCtx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn frameCtx.snapPickLayerParams;\n\t}\n\n\tfunction getClipPosX(pos, size) {\n\t\treturn 2 * (pos / size) - 1;\n\t}\n\n\tfunction getClipPosY(pos, size) {\n\t\treturn 1 - 2 * (pos / size);\n\t}\n\n\t/**\n\t * @param {[number, number]} canvasPos\n\t * @param {number} [snapRadiusInPixels=30]\n\t * @param {boolean} [snapToVertex=true]\n\t * @param {boolean} [snapToEdge=true]\n\t * @param pickResult\n\t * @returns {PickResult}\n\t */\n\tthis.snapPick = (function () {\n\t\tconst _pickResult = new _PickResult_js__WEBPACK_IMPORTED_MODULE_5__.PickResult();\n\n\t\treturn function (canvasPos, snapRadiusInPixels, snapToVertex, snapToEdge, pickResult = _pickResult) {\n\t\t\tif (!snapToVertex && !snapToEdge) {\n\t\t\t\treturn this.pick({ canvasPos, pickSurface: true });\n\t\t\t}\n\n\t\t\tconst resolutionScale = scene.canvas.resolutionScale;\n\n\t\t\tframeCtx.reset();\n\t\t\tframeCtx.backfaces = true;\n\t\t\tframeCtx.frontface = true; // \"ccw\"\n\t\t\tframeCtx.pickZNear = scene.camera.project.near;\n\t\t\tframeCtx.pickZFar = scene.camera.project.far;\n\n\t\t\tsnapRadiusInPixels = snapRadiusInPixels || 30;\n\n\t\t\tconst vertexPickBuffer = renderBufferManager.getRenderBuffer(\"uniquePickColors-aabs\", {\n\t\t\t\tdepthTexture: true,\n\t\t\t\tsize: [2 * snapRadiusInPixels + 1, 2 * snapRadiusInPixels + 1]\n\t\t\t});\n\n\t\t\tframeCtx.snapVectorA = [\n\t\t\t\tgetClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\n\t\t\t\tgetClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight)\n\t\t\t];\n\n\t\t\tframeCtx.snapInvVectorAB = [\n\t\t\t\tgl.drawingBufferWidth / (2 * snapRadiusInPixels),\n\t\t\t\tgl.drawingBufferHeight / (2 * snapRadiusInPixels)\n\t\t\t];\n\n\t\t\t// Bind and clear the snap render target\n\n\t\t\tvertexPickBuffer.bind(gl.RGBA32I, gl.RGBA32I, gl.RGBA8UI);\n\t\t\tgl.viewport(0, 0, vertexPickBuffer.size[0], vertexPickBuffer.size[1]);\n\t\t\tgl.enable(gl.DEPTH_TEST);\n\t\t\tgl.frontFace(gl.CCW);\n\t\t\tgl.disable(gl.CULL_FACE);\n\t\t\tgl.depthMask(true);\n\t\t\tgl.disable(gl.BLEND);\n\t\t\tgl.depthFunc(gl.LEQUAL);\n\t\t\tgl.clear(gl.DEPTH_BUFFER_BIT);\n\t\t\tgl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));\n\t\t\tgl.clearBufferiv(gl.COLOR, 1, new Int32Array([0, 0, 0, 0]));\n\t\t\tgl.clearBufferuiv(gl.COLOR, 2, new Uint32Array([0, 0, 0, 0]));\n\n\t\t\t//////////////////////////////////\n\t\t\t// Set view and proj mats for VBO renderers\n\t\t\t///////////////////////////////////////\n\n\t\t\tconst pickViewMatrix = scene.camera.viewMatrix;\n\t\t\tconst pickProjMatrix = scene.camera.projMatrix;\n\n\t\t\tfor (let type in drawableTypeInfo) {\n\t\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\t\tconst drawableList = drawableTypeInfo[type].drawableList;\n\t\t\t\t\tfor (let i = 0, len = drawableList.length; i < len; i++) {\n\t\t\t\t\t\tconst drawable = drawableList[i];\n\t\t\t\t\t\tif (drawable.setPickMatrices) {\n\t\t\t\t\t\t\t// Eg. SceneModel, which needs pre-loading into texture\n\t\t\t\t\t\t\tdrawable.setPickMatrices(pickViewMatrix, pickProjMatrix);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// a) init z-buffer\n\t\t\tgl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);\n\t\t\tconst layerParamsSurface = drawSnapInit(frameCtx);\n\n\t\t\t// b) snap-pick\n\t\t\tconst layerParamsSnap = [];\n\t\t\tframeCtx.snapPickLayerParams = layerParamsSnap;\n\n\t\t\tgl.depthMask(false);\n\t\t\tgl.drawBuffers([gl.COLOR_ATTACHMENT0]);\n\n\t\t\tif (snapToVertex && snapToEdge) {\n\t\t\t\tframeCtx.snapMode = \"edge\";\n\t\t\t\tdrawSnap(frameCtx);\n\n\t\t\t\tframeCtx.snapMode = \"vertex\";\n\t\t\t\tframeCtx.snapPickLayerNumber++;\n\n\t\t\t\tdrawSnap(frameCtx);\n\t\t\t} else {\n\t\t\t\tframeCtx.snapMode = snapToVertex ? \"vertex\" : \"edge\";\n\n\t\t\t\tdrawSnap(frameCtx);\n\t\t\t}\n\n\t\t\tgl.depthMask(true);\n\n\t\t\t// Read and decode the snapped coordinates\n\n\t\t\tconst snapPickResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4);\n\t\t\tconst snapPickNormalResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4, 1);\n\t\t\tconst snapPickIdResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.UNSIGNED_INT, Uint32Array, 4, 2);\n\n\t\t\tvertexPickBuffer.unbind();\n\n\t\t\t// result 1) regular hi-precision world position\n\n\t\t\tlet worldPos = null;\n\t\t\tlet worldNormal = null;\n\t\t\tlet pickable = null;\n\n\t\t\tconst middleX = snapRadiusInPixels;\n\t\t\tconst middleY = snapRadiusInPixels;\n\t\t\tconst middleIndex = middleX * 4 + middleY * vertexPickBuffer.size[0] * 4;\n\t\t\tconst pickResultMiddleXY = snapPickResultArray.slice(middleIndex, middleIndex + 4);\n\t\t\tconst pickNormalResultMiddleXY = snapPickNormalResultArray.slice(middleIndex, middleIndex + 4);\n\t\t\tconst pickPickableResultMiddleXY = snapPickIdResultArray.slice(middleIndex, middleIndex + 4);\n\n\t\t\tif (pickResultMiddleXY[3] !== 0) {\n\t\t\t\tconst pickedLayerParmasSurface =\n\t\t\t\t\tlayerParamsSurface[Math.abs(pickResultMiddleXY[3]) % layerParamsSurface.length];\n\t\t\t\tconst origin = pickedLayerParmasSurface.origin;\n\t\t\t\tconst scale = pickedLayerParmasSurface.coordinateScale;\n\t\t\t\tworldPos = [\n\t\t\t\t\tpickResultMiddleXY[0] * scale[0] + origin[0],\n\t\t\t\t\tpickResultMiddleXY[1] * scale[1] + origin[1],\n\t\t\t\t\tpickResultMiddleXY[2] * scale[2] + origin[2]\n\t\t\t\t];\n\t\t\t\tworldNormal = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3([\n\t\t\t\t\tpickNormalResultMiddleXY[0] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\n\t\t\t\t\tpickNormalResultMiddleXY[1] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\n\t\t\t\t\tpickNormalResultMiddleXY[2] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT\n\t\t\t\t]);\n\n\t\t\t\tconst pickID =\n\t\t\t\t\tpickPickableResultMiddleXY[0] +\n\t\t\t\t\t(pickPickableResultMiddleXY[1] << 8) +\n\t\t\t\t\t(pickPickableResultMiddleXY[2] << 16) +\n\t\t\t\t\t(pickPickableResultMiddleXY[3] << 24);\n\n\t\t\t\tpickable = pickIDs.items[pickID];\n\t\t\t}\n\n\t\t\t// result 2) hi-precision snapped (to vertex/edge) world position\n\n\t\t\tlet snapPickResult = [];\n\n\t\t\tfor (let i = 0; i < snapPickResultArray.length; i += 4) {\n\t\t\t\tif (snapPickResultArray[i + 3] > 0) {\n\t\t\t\t\tconst pixelNumber = Math.floor(i / 4);\n\t\t\t\t\tconst w = vertexPickBuffer.size[0];\n\t\t\t\t\tconst x = (pixelNumber % w) - Math.floor(w / 2);\n\t\t\t\t\tconst y = Math.floor(pixelNumber / w) - Math.floor(w / 2);\n\t\t\t\t\tconst dist = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));\n\t\t\t\t\tsnapPickResult.push({\n\t\t\t\t\t\tx,\n\t\t\t\t\t\ty,\n\t\t\t\t\t\tdist,\n\t\t\t\t\t\tisVertex:\n\t\t\t\t\t\t\tsnapToVertex && snapToEdge ? snapPickResultArray[i + 3] > layerParamsSnap.length / 2 : snapToVertex,\n\t\t\t\t\t\tresult: [\n\t\t\t\t\t\t\tsnapPickResultArray[i + 0],\n\t\t\t\t\t\t\tsnapPickResultArray[i + 1],\n\t\t\t\t\t\t\tsnapPickResultArray[i + 2],\n\t\t\t\t\t\t\tsnapPickResultArray[i + 3]\n\t\t\t\t\t\t],\n\t\t\t\t\t\tnormal: [\n\t\t\t\t\t\t\tsnapPickNormalResultArray[i + 0],\n\t\t\t\t\t\t\tsnapPickNormalResultArray[i + 1],\n\t\t\t\t\t\t\tsnapPickNormalResultArray[i + 2],\n\t\t\t\t\t\t\tsnapPickNormalResultArray[i + 3]\n\t\t\t\t\t\t],\n\t\t\t\t\t\tid: [\n\t\t\t\t\t\t\tsnapPickIdResultArray[i + 0],\n\t\t\t\t\t\t\tsnapPickIdResultArray[i + 1],\n\t\t\t\t\t\t\tsnapPickIdResultArray[i + 2],\n\t\t\t\t\t\t\tsnapPickIdResultArray[i + 3]\n\t\t\t\t\t\t]\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet snappedWorldPos = null;\n\t\t\tlet snappedWorldNormal = null;\n\t\t\tlet snappedPickable = null;\n\t\t\tlet snapType = null;\n\n\t\t\tif (snapPickResult.length > 0) {\n\t\t\t\t// vertex snap first, then edge snap\n\t\t\t\tsnapPickResult.sort((a, b) => {\n\t\t\t\t\tif (a.isVertex !== b.isVertex) {\n\t\t\t\t\t\treturn a.isVertex ? -1 : 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn a.dist - b.dist;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tsnapType = snapPickResult[0].isVertex ? \"vertex\" : \"edge\";\n\t\t\t\tconst snapPick = snapPickResult[0].result;\n\t\t\t\tconst snapPickNormal = snapPickResult[0].normal;\n\t\t\t\tconst snapPickId = snapPickResult[0].id;\n\n\t\t\t\tconst pickedLayerParmas = layerParamsSnap[snapPick[3]];\n\n\t\t\t\tconst origin = pickedLayerParmas.origin;\n\t\t\t\tconst scale = pickedLayerParmas.coordinateScale;\n\n\t\t\t\tsnappedWorldNormal = _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3([\n\t\t\t\t\tsnapPickNormal[0] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\n\t\t\t\t\tsnapPickNormal[1] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT,\n\t\t\t\t\tsnapPickNormal[2] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT\n\t\t\t\t]);\n\n\t\t\t\tsnappedWorldPos = [\n\t\t\t\t\tsnapPick[0] * scale[0] + origin[0],\n\t\t\t\t\tsnapPick[1] * scale[1] + origin[1],\n\t\t\t\t\tsnapPick[2] * scale[2] + origin[2]\n\t\t\t\t];\n\n\t\t\t\tsnappedPickable =\n\t\t\t\t\tpickIDs.items[snapPickId[0] + (snapPickId[1] << 8) + (snapPickId[2] << 16) + (snapPickId[3] << 24)];\n\t\t\t}\n\n\t\t\tif (null === worldPos && null == snappedWorldPos) {\n\t\t\t\t// If neither regular pick or snap pick, return null\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tlet snappedCanvasPos = null;\n\n\t\t\tif (null !== snappedWorldPos) {\n\t\t\t\tsnappedCanvasPos = scene.camera.projectWorldPos(snappedWorldPos);\n\t\t\t}\n\n\t\t\tconst snappedEntity =\n\t\t\t\tsnappedPickable && snappedPickable.delegatePickedEntity\n\t\t\t\t\t? snappedPickable.delegatePickedEntity()\n\t\t\t\t\t: snappedPickable;\n\n\t\t\tpickResult.reset();\n\t\t\tpickResult.snappedToEdge = snapType === \"edge\";\n\t\t\tpickResult.snappedToVertex = snapType === \"vertex\";\n\t\t\tpickResult.worldPos = snappedWorldPos;\n\t\t\tpickResult.worldNormal = snappedWorldNormal;\n\t\t\tpickResult.entity = snappedEntity;\n\t\t\tpickResult.canvasPos = canvasPos;\n\t\t\tpickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;\n\n\t\t\treturn pickResult;\n\t\t};\n\t})();\n\n\tfunction unpackDepth(depthZ) {\n\t\tconst vec = [depthZ[0] / 256.0, depthZ[1] / 256.0, depthZ[2] / 256.0, depthZ[3] / 256.0];\n\t\tconst bitShift = [1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0];\n\t\treturn _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.dotVec4(vec, bitShift);\n\t}\n\n\tfunction gpuPickWorldNormal(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, pickResult) {\n\t\tconst resolutionScale = scene.canvas.resolutionScale;\n\n\t\tframeCtx.reset();\n\t\tframeCtx.backfaces = true;\n\t\tframeCtx.frontface = true; // \"ccw\"\n\t\tframeCtx.pickOrigin = pickResult.origin;\n\t\tframeCtx.pickViewMatrix = pickViewMatrix;\n\t\tframeCtx.pickProjMatrix = pickProjMatrix;\n\t\tframeCtx.pickClipPos = [\n\t\t\tgetClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),\n\t\t\tgetClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight)\n\t\t];\n\n\t\tconst pickNormalBuffer = renderBufferManager.getRenderBuffer(\"pick-normal\", { size: [3, 3] });\n\n\t\tpickNormalBuffer.bind(gl.RGBA32I);\n\n\t\tgl.viewport(0, 0, pickNormalBuffer.size[0], pickNormalBuffer.size[1]);\n\n\t\tgl.enable(gl.DEPTH_TEST);\n\t\tgl.disable(gl.CULL_FACE);\n\t\tgl.disable(gl.BLEND);\n\t\tgl.clear(gl.DEPTH_BUFFER_BIT);\n\t\tgl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));\n\n\t\tpickable.drawPickNormals(frameCtx); // Draw color-encoded fragment World-space normals\n\n\t\tconst pix = pickNormalBuffer.read(1, 1, gl.RGBA_INTEGER, gl.INT, Int32Array, 4);\n\n\t\tpickNormalBuffer.unbind();\n\n\t\tconst worldNormal = [pix[0] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT, pix[1] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT, pix[2] / _math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.MAX_INT];\n\n\t\t_math_math_js__WEBPACK_IMPORTED_MODULE_1__.math.normalizeVec3(worldNormal);\n\n\t\tpickResult.worldNormal = worldNormal;\n\t}\n\n\t/**\n\t * Adds a {@link Marker} for occlusion testing.\n\t * @param marker\n\t */\n\tthis.addMarker = function (marker) {\n\t\tthis._occlusionTester = this._occlusionTester || new _occlusion_OcclusionTester_js__WEBPACK_IMPORTED_MODULE_6__.OcclusionTester(scene, renderBufferManager);\n\t\tthis._occlusionTester.addMarker(marker);\n\t\tscene.occlusionTestCountdown = 0;\n\t};\n\n\t/**\n\t * Notifies that a {@link Marker#worldPos} has updated.\n\t * @param marker\n\t */\n\tthis.markerWorldPosUpdated = function (marker) {\n\t\tthis._occlusionTester.markerWorldPosUpdated(marker);\n\t};\n\n\t/**\n\t * Removes a {@link Marker} from occlusion testing.\n\t * @param marker\n\t */\n\tthis.removeMarker = function (marker) {\n\t\tthis._occlusionTester.removeMarker(marker);\n\t};\n\n\t/**\n\t * Performs an occlusion test for all added {@link Marker}s, updating\n\t * their {@link Marker#visible} properties accordingly.\n\t */\n\tthis.doOcclusionTest = function () {\n\t\tif (this._occlusionTester && this._occlusionTester.needOcclusionTest) {\n\t\t\tupdateDrawlist();\n\n\t\t\tthis._occlusionTester.bindRenderBuf();\n\n\t\t\tframeCtx.reset();\n\t\t\tframeCtx.backfaces = true;\n\t\t\tframeCtx.frontface = true; // \"ccw\"\n\n\t\t\tgl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\t\t\tgl.clearColor(0, 0, 0, 0);\n\t\t\tgl.enable(gl.DEPTH_TEST);\n\t\t\tgl.disable(gl.CULL_FACE);\n\t\t\tgl.disable(gl.BLEND);\n\t\t\tgl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n\t\t\tfor (let type in drawableTypeInfo) {\n\t\t\t\tif (drawableTypeInfo.hasOwnProperty(type)) {\n\t\t\t\t\tconst drawableInfo = drawableTypeInfo[type];\n\t\t\t\t\tconst drawableList = drawableInfo.drawableList;\n\t\t\t\t\tfor (let i = 0, len = drawableList.length; i < len; i++) {\n\t\t\t\t\t\tconst drawable = drawableList[i];\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!drawable.drawOcclusion ||\n\t\t\t\t\t\t\tdrawable.culled === true ||\n\t\t\t\t\t\t\tdrawable.visible === false ||\n\t\t\t\t\t\t\tdrawable.pickable === false\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// TODO: Option to exclude transparent?\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdrawable.drawOcclusion(frameCtx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._occlusionTester.drawMarkers(frameCtx);\n\t\t\tthis._occlusionTester.doOcclusionTest(); // Updates Marker \"visible\" properties\n\t\t\tthis._occlusionTester.unbindRenderBuf();\n\t\t}\n\t};\n\n\t/**\n\t * Read pixels from the renderer's current output. Performs a force-render first.\n\t * @param pixels\n\t * @param colors\n\t * @param len\n\t * @param opaqueOnly\n\t * @private\n\t */\n\tthis.readPixels = function (pixels, colors, len, opaqueOnly) {\n\t\tconst snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\n\t\tsnapshotBuffer.bind();\n\t\tsnapshotBuffer.clear();\n\t\tthis.render({ force: true, opaqueOnly: opaqueOnly });\n\t\tlet color;\n\t\tlet i;\n\t\tlet j;\n\t\tlet k;\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tj = i * 2;\n\t\t\tk = i * 4;\n\t\t\tcolor = snapshotBuffer.read(pixels[j], pixels[j + 1]);\n\t\t\tcolors[k] = color[0];\n\t\t\tcolors[k + 1] = color[1];\n\t\t\tcolors[k + 2] = color[2];\n\t\t\tcolors[k + 3] = color[3];\n\t\t}\n\t\tsnapshotBuffer.unbind();\n\t\timageDirty = true;\n\t};\n\n\t/**\n\t * Enter snapshot mode.\n\t *\n\t * Switches rendering to a hidden snapshot canvas.\n\t *\n\t * Exit snapshot mode using endSnapshot().\n\t */\n\tthis.beginSnapshot = function (params = {}) {\n\t\tconst snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\n\t\tif (params.width && params.height) {\n\t\t\tsnapshotBuffer.setSize([params.width, params.height]);\n\t\t}\n\t\tsnapshotBuffer.bind();\n\t\tsnapshotBuffer.clear();\n\t\tsnapshotBound = true;\n\t};\n\n\t/**\n\t * When in snapshot mode, renders a frame of the current Scene state to the snapshot canvas.\n\t */\n\tthis.renderSnapshot = function () {\n\t\tif (!snapshotBound) {\n\t\t\treturn;\n\t\t}\n\t\tconst snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\n\t\tsnapshotBuffer.clear();\n\t\tthis.render({ force: true, opaqueOnly: false });\n\t\timageDirty = true;\n\t};\n\n\t/**\n\t * When in snapshot mode, gets an image of the snapshot canvas.\n\t *\n\t * @private\n\t * @returns {String} The image data URI.\n\t */\n\tthis.readSnapshot = function (params) {\n\t\tconst snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\n\t\treturn snapshotBuffer.readImage(params);\n\t};\n\n\t/**\n\t * Returns an HTMLCanvas containing an image of the snapshot canvas.\n\t *\n\t * - The HTMLCanvas has a CanvasRenderingContext2D.\n\t * - Expects the caller to draw more things on the HTMLCanvas (annotations etc).\n\t *\n\t * @returns {HTMLCanvasElement}\n\t */\n\tthis.readSnapshotAsCanvas = function () {\n\t\tconst snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\n\t\treturn snapshotBuffer.readImageAsCanvas();\n\t};\n\n\t/**\n\t * Exists snapshot mode.\n\t *\n\t * Switches rendering back to the main canvas.\n\t */\n\tthis.endSnapshot = function () {\n\t\tif (!snapshotBound) {\n\t\t\treturn;\n\t\t}\n\t\tconst snapshotBuffer = renderBufferManager.getRenderBuffer(\"snapshot\");\n\t\tsnapshotBuffer.unbind();\n\t\tsnapshotBound = false;\n\t};\n\n\t/**\n\t * Destroys this renderer.\n\t * @private\n\t */\n\tthis.destroy = function () {\n\t\tdrawableTypeInfo = {};\n\t\tdrawables = {};\n\n\t\trenderBufferManager.destroy();\n\n\t\tsaoOcclusionRenderer.destroy();\n\t\tsaoDepthLimitedBlurRenderer.destroy();\n\n\t\tif (this._occlusionTester) {\n\t\t\tthis._occlusionTester.destroy();\n\t\t}\n\t};\n};\n\n\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/webgl/Renderer.js?");
5128
5148
 
5129
5149
  /***/ }),
5130
5150
 
@@ -5178,6 +5198,16 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
5178
5198
 
5179
5199
  /***/ }),
5180
5200
 
5201
+ /***/ "./src/viewer/scene/webgl/index.js":
5202
+ /*!*****************************************!*\
5203
+ !*** ./src/viewer/scene/webgl/index.js ***!
5204
+ \*****************************************/
5205
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
5206
+
5207
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Renderer: () => (/* reexport safe */ _Renderer_js__WEBPACK_IMPORTED_MODULE_0__.Renderer)\n/* harmony export */ });\n/* harmony import */ var _Renderer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Renderer.js */ \"./src/viewer/scene/webgl/Renderer.js\");\n\r\n\n\n//# sourceURL=webpack://@xtctwins/tctwins-core/./src/viewer/scene/webgl/index.js?");
5208
+
5209
+ /***/ }),
5210
+
5181
5211
  /***/ "./src/viewer/scene/webgl/occlusion/OcclusionLayer.js":
5182
5212
  /*!************************************************************!*\
5183
5213
  !*** ./src/viewer/scene/webgl/occlusion/OcclusionLayer.js ***!
@@ -5472,6 +5502,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
5472
5502
  /******/ var __webpack_exports__CameraMemento = __webpack_exports__.CameraMemento;
5473
5503
  /******/ var __webpack_exports__CameraPath = __webpack_exports__.CameraPath;
5474
5504
  /******/ var __webpack_exports__CameraPathAnimation = __webpack_exports__.CameraPathAnimation;
5505
+ /******/ var __webpack_exports__Canvas = __webpack_exports__.Canvas;
5475
5506
  /******/ var __webpack_exports__CityJSONLoaderPlugin = __webpack_exports__.CityJSONLoaderPlugin;
5476
5507
  /******/ var __webpack_exports__ClampToEdgeWrapping = __webpack_exports__.ClampToEdgeWrapping;
5477
5508
  /******/ var __webpack_exports__Component = __webpack_exports__.Component;
@@ -5581,9 +5612,11 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
5581
5612
  /******/ var __webpack_exports__RedFormat = __webpack_exports__.RedFormat;
5582
5613
  /******/ var __webpack_exports__RedIntegerFormat = __webpack_exports__.RedIntegerFormat;
5583
5614
  /******/ var __webpack_exports__ReflectionMap = __webpack_exports__.ReflectionMap;
5615
+ /******/ var __webpack_exports__Renderer = __webpack_exports__.Renderer;
5584
5616
  /******/ var __webpack_exports__RepeatWrapping = __webpack_exports__.RepeatWrapping;
5585
5617
  /******/ var __webpack_exports__STLDefaultDataSource = __webpack_exports__.STLDefaultDataSource;
5586
5618
  /******/ var __webpack_exports__STLLoaderPlugin = __webpack_exports__.STLLoaderPlugin;
5619
+ /******/ var __webpack_exports__Scene = __webpack_exports__.Scene;
5587
5620
  /******/ var __webpack_exports__SceneModel = __webpack_exports__.SceneModel;
5588
5621
  /******/ var __webpack_exports__SceneModelMesh = __webpack_exports__.SceneModelMesh;
5589
5622
  /******/ var __webpack_exports__SceneModelTransform = __webpack_exports__.SceneModelTransform;
@@ -5636,5 +5669,5 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
5636
5669
  /******/ var __webpack_exports__utils = __webpack_exports__.utils;
5637
5670
  /******/ var __webpack_exports__worldToRTCPos = __webpack_exports__.worldToRTCPos;
5638
5671
  /******/ var __webpack_exports__worldToRTCPositions = __webpack_exports__.worldToRTCPositions;
5639
- /******/ export { __webpack_exports__AlphaFormat as AlphaFormat, __webpack_exports__AmbientLight as AmbientLight, __webpack_exports__AngleMeasurementsControl as AngleMeasurementsControl, __webpack_exports__AngleMeasurementsMouseControl as AngleMeasurementsMouseControl, __webpack_exports__AngleMeasurementsPlugin as AngleMeasurementsPlugin, __webpack_exports__AngleMeasurementsTouchControl as AngleMeasurementsTouchControl, __webpack_exports__AnnotationsPlugin as AnnotationsPlugin, __webpack_exports__AxisGizmoPlugin as AxisGizmoPlugin, __webpack_exports__BCFViewpointsPlugin as BCFViewpointsPlugin, __webpack_exports__Bitmap as Bitmap, __webpack_exports__ByteType as ByteType, __webpack_exports__CameraMemento as CameraMemento, __webpack_exports__CameraPath as CameraPath, __webpack_exports__CameraPathAnimation as CameraPathAnimation, __webpack_exports__CityJSONLoaderPlugin as CityJSONLoaderPlugin, __webpack_exports__ClampToEdgeWrapping as ClampToEdgeWrapping, __webpack_exports__Component as Component, __webpack_exports__CompressedMediaType as CompressedMediaType, __webpack_exports__Configs as Configs, __webpack_exports__ContextMenu as ContextMenu, __webpack_exports__CubicBezierCurve as CubicBezierCurve, __webpack_exports__Curve as Curve, __webpack_exports__DefaultLoadingManager as DefaultLoadingManager, __webpack_exports__DepthFormat as DepthFormat, __webpack_exports__DepthStencilFormat as DepthStencilFormat, __webpack_exports__DirLight as DirLight, __webpack_exports__DistanceMeasurementsControl as DistanceMeasurementsControl, __webpack_exports__DistanceMeasurementsMouseControl as DistanceMeasurementsMouseControl, __webpack_exports__DistanceMeasurementsPlugin as DistanceMeasurementsPlugin, __webpack_exports__DistanceMeasurementsTouchControl as DistanceMeasurementsTouchControl, __webpack_exports__EdgeMaterial as EdgeMaterial, __webpack_exports__EmphasisMaterial as EmphasisMaterial, __webpack_exports__FaceAlignedSectionPlanesPlugin as FaceAlignedSectionPlanesPlugin, __webpack_exports__FastNavPlugin as FastNavPlugin, __webpack_exports__FloatType as FloatType, __webpack_exports__Fresnel as Fresnel, __webpack_exports__Frustum as Frustum, __webpack_exports__FrustumPlane as FrustumPlane, __webpack_exports__GIFMediaType as GIFMediaType, __webpack_exports__GLTFDefaultDataSource as GLTFDefaultDataSource, __webpack_exports__GLTFLoaderPlugin as GLTFLoaderPlugin, __webpack_exports__HalfFloatType as HalfFloatType, __webpack_exports__ImagePlane as ImagePlane, __webpack_exports__IntType as IntType, __webpack_exports__JPEGMediaType as JPEGMediaType, __webpack_exports__KTX2TextureTranscoder as KTX2TextureTranscoder, __webpack_exports__LASLoaderPlugin as LASLoaderPlugin, __webpack_exports__LambertMaterial as LambertMaterial, __webpack_exports__LightMap as LightMap, __webpack_exports__LineSet as LineSet, __webpack_exports__LinearEncoding as LinearEncoding, __webpack_exports__LinearFilter as LinearFilter, __webpack_exports__LinearMipMapLinearFilter as LinearMipMapLinearFilter, __webpack_exports__LinearMipMapNearestFilter as LinearMipMapNearestFilter, __webpack_exports__LinearMipmapLinearFilter as LinearMipmapLinearFilter, __webpack_exports__LinearMipmapNearestFilter as LinearMipmapNearestFilter, __webpack_exports__Loader as Loader, __webpack_exports__LoadingManager as LoadingManager, __webpack_exports__LocaleService as LocaleService, __webpack_exports__LuminanceAlphaFormat as LuminanceAlphaFormat, __webpack_exports__LuminanceFormat as LuminanceFormat, __webpack_exports__Map as Map, __webpack_exports__Marker as Marker, __webpack_exports__MarqueePicker as MarqueePicker, __webpack_exports__MarqueePickerMouseControl as MarqueePickerMouseControl, __webpack_exports__Mesh as Mesh, __webpack_exports__MetallicMaterial as MetallicMaterial, __webpack_exports__MirroredRepeatWrapping as MirroredRepeatWrapping, __webpack_exports__ModelMemento as ModelMemento, __webpack_exports__NavCubePlugin as NavCubePlugin, __webpack_exports__NearestFilter as NearestFilter, __webpack_exports__NearestMipMapLinearFilter as NearestMipMapLinearFilter, __webpack_exports__NearestMipMapNearestFilter as NearestMipMapNearestFilter, __webpack_exports__NearestMipmapLinearFilter as NearestMipmapLinearFilter, __webpack_exports__NearestMipmapNearestFilter as NearestMipmapNearestFilter, __webpack_exports__Node as Node, __webpack_exports__OBJLoaderPlugin as OBJLoaderPlugin, __webpack_exports__ObjectsKdTree3 as ObjectsKdTree3, __webpack_exports__ObjectsMemento as ObjectsMemento, __webpack_exports__PNGMediaType as PNGMediaType, __webpack_exports__Path as Path, __webpack_exports__PerformanceModel as PerformanceModel, __webpack_exports__PhongMaterial as PhongMaterial, __webpack_exports__Plugin as Plugin, __webpack_exports__PointLight as PointLight, __webpack_exports__PointerLens as PointerLens, __webpack_exports__QuadraticBezierCurve as QuadraticBezierCurve, __webpack_exports__Queue as Queue, __webpack_exports__RGBAFormat as RGBAFormat, __webpack_exports__RGBAIntegerFormat as RGBAIntegerFormat, __webpack_exports__RGBA_ASTC_10x10_Format as RGBA_ASTC_10x10_Format, __webpack_exports__RGBA_ASTC_10x5_Format as RGBA_ASTC_10x5_Format, __webpack_exports__RGBA_ASTC_10x6_Format as RGBA_ASTC_10x6_Format, __webpack_exports__RGBA_ASTC_10x8_Format as RGBA_ASTC_10x8_Format, __webpack_exports__RGBA_ASTC_12x10_Format as RGBA_ASTC_12x10_Format, __webpack_exports__RGBA_ASTC_12x12_Format as RGBA_ASTC_12x12_Format, __webpack_exports__RGBA_ASTC_4x4_Format as RGBA_ASTC_4x4_Format, __webpack_exports__RGBA_ASTC_5x4_Format as RGBA_ASTC_5x4_Format, __webpack_exports__RGBA_ASTC_5x5_Format as RGBA_ASTC_5x5_Format, __webpack_exports__RGBA_ASTC_6x5_Format as RGBA_ASTC_6x5_Format, __webpack_exports__RGBA_ASTC_6x6_Format as RGBA_ASTC_6x6_Format, __webpack_exports__RGBA_ASTC_8x5_Format as RGBA_ASTC_8x5_Format, __webpack_exports__RGBA_ASTC_8x6_Format as RGBA_ASTC_8x6_Format, __webpack_exports__RGBA_ASTC_8x8_Format as RGBA_ASTC_8x8_Format, __webpack_exports__RGBA_BPTC_Format as RGBA_BPTC_Format, __webpack_exports__RGBA_ETC2_EAC_Format as RGBA_ETC2_EAC_Format, __webpack_exports__RGBA_PVRTC_2BPPV1_Format as RGBA_PVRTC_2BPPV1_Format, __webpack_exports__RGBA_PVRTC_4BPPV1_Format as RGBA_PVRTC_4BPPV1_Format, __webpack_exports__RGBA_S3TC_DXT1_Format as RGBA_S3TC_DXT1_Format, __webpack_exports__RGBA_S3TC_DXT3_Format as RGBA_S3TC_DXT3_Format, __webpack_exports__RGBA_S3TC_DXT5_Format as RGBA_S3TC_DXT5_Format, __webpack_exports__RGBFormat as RGBFormat, __webpack_exports__RGB_ETC1_Format as RGB_ETC1_Format, __webpack_exports__RGB_ETC2_Format as RGB_ETC2_Format, __webpack_exports__RGB_PVRTC_2BPPV1_Format as RGB_PVRTC_2BPPV1_Format, __webpack_exports__RGB_PVRTC_4BPPV1_Format as RGB_PVRTC_4BPPV1_Format, __webpack_exports__RGB_S3TC_DXT1_Format as RGB_S3TC_DXT1_Format, __webpack_exports__RGFormat as RGFormat, __webpack_exports__RGIntegerFormat as RGIntegerFormat, __webpack_exports__ReadableGeometry as ReadableGeometry, __webpack_exports__RedFormat as RedFormat, __webpack_exports__RedIntegerFormat as RedIntegerFormat, __webpack_exports__ReflectionMap as ReflectionMap, __webpack_exports__RepeatWrapping as RepeatWrapping, __webpack_exports__STLDefaultDataSource as STLDefaultDataSource, __webpack_exports__STLLoaderPlugin as STLLoaderPlugin, __webpack_exports__SceneModel as SceneModel, __webpack_exports__SceneModelMesh as SceneModelMesh, __webpack_exports__SceneModelTransform as SceneModelTransform, __webpack_exports__SectionBox as SectionBox, __webpack_exports__SectionPlane as SectionPlane, __webpack_exports__SectionPlanesPlugin as SectionPlanesPlugin, __webpack_exports__ShortType as ShortType, __webpack_exports__Skybox as Skybox, __webpack_exports__SkyboxesPlugin as SkyboxesPlugin, __webpack_exports__SpecularMaterial as SpecularMaterial, __webpack_exports__SplineCurve as SplineCurve, __webpack_exports__SpriteMarker as SpriteMarker, __webpack_exports__StoreyViewsPlugin as StoreyViewsPlugin, __webpack_exports__Texture as Texture, __webpack_exports__TextureTranscoder as TextureTranscoder, __webpack_exports__TreeViewPlugin as TreeViewPlugin, __webpack_exports__UnsignedByteType as UnsignedByteType, __webpack_exports__UnsignedInt248Type as UnsignedInt248Type, __webpack_exports__UnsignedIntType as UnsignedIntType, __webpack_exports__UnsignedShort4444Type as UnsignedShort4444Type, __webpack_exports__UnsignedShort5551Type as UnsignedShort5551Type, __webpack_exports__UnsignedShortType as UnsignedShortType, __webpack_exports__VBOGeometry as VBOGeometry, __webpack_exports__ViewCullPlugin as ViewCullPlugin, __webpack_exports__Viewer as Viewer, __webpack_exports__WebIFCLoaderPlugin as WebIFCLoaderPlugin, __webpack_exports__WorkerPool as WorkerPool, __webpack_exports__XML3DLoaderPlugin as XML3DLoaderPlugin, __webpack_exports__XTCDefaultDataSource as XTCDefaultDataSource, __webpack_exports__XTCLoaderPlugin as XTCLoaderPlugin, __webpack_exports__buildBoxGeometry as buildBoxGeometry, __webpack_exports__buildBoxLinesGeometry as buildBoxLinesGeometry, __webpack_exports__buildCylinderGeometry as buildCylinderGeometry, __webpack_exports__buildGridGeometry as buildGridGeometry, __webpack_exports__buildPlaneGeometry as buildPlaneGeometry, __webpack_exports__buildSphereGeometry as buildSphereGeometry, __webpack_exports__buildTorusGeometry as buildTorusGeometry, __webpack_exports__buildVectorTextGeometry as buildVectorTextGeometry, __webpack_exports__createRTCViewMat as createRTCViewMat, __webpack_exports__frustumIntersectsAABB3 as frustumIntersectsAABB3, __webpack_exports__getKTX2TextureTranscoder as getKTX2TextureTranscoder, __webpack_exports__getPlaneRTCPos as getPlaneRTCPos, __webpack_exports__load3DSGeometry as load3DSGeometry, __webpack_exports__loadOBJGeometry as loadOBJGeometry, __webpack_exports__math as math, __webpack_exports__rtcToWorldPos as rtcToWorldPos, __webpack_exports__sRGBEncoding as sRGBEncoding, __webpack_exports__setFrustum as setFrustum, __webpack_exports__stats as stats, __webpack_exports__utils as utils, __webpack_exports__worldToRTCPos as worldToRTCPos, __webpack_exports__worldToRTCPositions as worldToRTCPositions };
5672
+ /******/ export { __webpack_exports__AlphaFormat as AlphaFormat, __webpack_exports__AmbientLight as AmbientLight, __webpack_exports__AngleMeasurementsControl as AngleMeasurementsControl, __webpack_exports__AngleMeasurementsMouseControl as AngleMeasurementsMouseControl, __webpack_exports__AngleMeasurementsPlugin as AngleMeasurementsPlugin, __webpack_exports__AngleMeasurementsTouchControl as AngleMeasurementsTouchControl, __webpack_exports__AnnotationsPlugin as AnnotationsPlugin, __webpack_exports__AxisGizmoPlugin as AxisGizmoPlugin, __webpack_exports__BCFViewpointsPlugin as BCFViewpointsPlugin, __webpack_exports__Bitmap as Bitmap, __webpack_exports__ByteType as ByteType, __webpack_exports__CameraMemento as CameraMemento, __webpack_exports__CameraPath as CameraPath, __webpack_exports__CameraPathAnimation as CameraPathAnimation, __webpack_exports__Canvas as Canvas, __webpack_exports__CityJSONLoaderPlugin as CityJSONLoaderPlugin, __webpack_exports__ClampToEdgeWrapping as ClampToEdgeWrapping, __webpack_exports__Component as Component, __webpack_exports__CompressedMediaType as CompressedMediaType, __webpack_exports__Configs as Configs, __webpack_exports__ContextMenu as ContextMenu, __webpack_exports__CubicBezierCurve as CubicBezierCurve, __webpack_exports__Curve as Curve, __webpack_exports__DefaultLoadingManager as DefaultLoadingManager, __webpack_exports__DepthFormat as DepthFormat, __webpack_exports__DepthStencilFormat as DepthStencilFormat, __webpack_exports__DirLight as DirLight, __webpack_exports__DistanceMeasurementsControl as DistanceMeasurementsControl, __webpack_exports__DistanceMeasurementsMouseControl as DistanceMeasurementsMouseControl, __webpack_exports__DistanceMeasurementsPlugin as DistanceMeasurementsPlugin, __webpack_exports__DistanceMeasurementsTouchControl as DistanceMeasurementsTouchControl, __webpack_exports__EdgeMaterial as EdgeMaterial, __webpack_exports__EmphasisMaterial as EmphasisMaterial, __webpack_exports__FaceAlignedSectionPlanesPlugin as FaceAlignedSectionPlanesPlugin, __webpack_exports__FastNavPlugin as FastNavPlugin, __webpack_exports__FloatType as FloatType, __webpack_exports__Fresnel as Fresnel, __webpack_exports__Frustum as Frustum, __webpack_exports__FrustumPlane as FrustumPlane, __webpack_exports__GIFMediaType as GIFMediaType, __webpack_exports__GLTFDefaultDataSource as GLTFDefaultDataSource, __webpack_exports__GLTFLoaderPlugin as GLTFLoaderPlugin, __webpack_exports__HalfFloatType as HalfFloatType, __webpack_exports__ImagePlane as ImagePlane, __webpack_exports__IntType as IntType, __webpack_exports__JPEGMediaType as JPEGMediaType, __webpack_exports__KTX2TextureTranscoder as KTX2TextureTranscoder, __webpack_exports__LASLoaderPlugin as LASLoaderPlugin, __webpack_exports__LambertMaterial as LambertMaterial, __webpack_exports__LightMap as LightMap, __webpack_exports__LineSet as LineSet, __webpack_exports__LinearEncoding as LinearEncoding, __webpack_exports__LinearFilter as LinearFilter, __webpack_exports__LinearMipMapLinearFilter as LinearMipMapLinearFilter, __webpack_exports__LinearMipMapNearestFilter as LinearMipMapNearestFilter, __webpack_exports__LinearMipmapLinearFilter as LinearMipmapLinearFilter, __webpack_exports__LinearMipmapNearestFilter as LinearMipmapNearestFilter, __webpack_exports__Loader as Loader, __webpack_exports__LoadingManager as LoadingManager, __webpack_exports__LocaleService as LocaleService, __webpack_exports__LuminanceAlphaFormat as LuminanceAlphaFormat, __webpack_exports__LuminanceFormat as LuminanceFormat, __webpack_exports__Map as Map, __webpack_exports__Marker as Marker, __webpack_exports__MarqueePicker as MarqueePicker, __webpack_exports__MarqueePickerMouseControl as MarqueePickerMouseControl, __webpack_exports__Mesh as Mesh, __webpack_exports__MetallicMaterial as MetallicMaterial, __webpack_exports__MirroredRepeatWrapping as MirroredRepeatWrapping, __webpack_exports__ModelMemento as ModelMemento, __webpack_exports__NavCubePlugin as NavCubePlugin, __webpack_exports__NearestFilter as NearestFilter, __webpack_exports__NearestMipMapLinearFilter as NearestMipMapLinearFilter, __webpack_exports__NearestMipMapNearestFilter as NearestMipMapNearestFilter, __webpack_exports__NearestMipmapLinearFilter as NearestMipmapLinearFilter, __webpack_exports__NearestMipmapNearestFilter as NearestMipmapNearestFilter, __webpack_exports__Node as Node, __webpack_exports__OBJLoaderPlugin as OBJLoaderPlugin, __webpack_exports__ObjectsKdTree3 as ObjectsKdTree3, __webpack_exports__ObjectsMemento as ObjectsMemento, __webpack_exports__PNGMediaType as PNGMediaType, __webpack_exports__Path as Path, __webpack_exports__PerformanceModel as PerformanceModel, __webpack_exports__PhongMaterial as PhongMaterial, __webpack_exports__Plugin as Plugin, __webpack_exports__PointLight as PointLight, __webpack_exports__PointerLens as PointerLens, __webpack_exports__QuadraticBezierCurve as QuadraticBezierCurve, __webpack_exports__Queue as Queue, __webpack_exports__RGBAFormat as RGBAFormat, __webpack_exports__RGBAIntegerFormat as RGBAIntegerFormat, __webpack_exports__RGBA_ASTC_10x10_Format as RGBA_ASTC_10x10_Format, __webpack_exports__RGBA_ASTC_10x5_Format as RGBA_ASTC_10x5_Format, __webpack_exports__RGBA_ASTC_10x6_Format as RGBA_ASTC_10x6_Format, __webpack_exports__RGBA_ASTC_10x8_Format as RGBA_ASTC_10x8_Format, __webpack_exports__RGBA_ASTC_12x10_Format as RGBA_ASTC_12x10_Format, __webpack_exports__RGBA_ASTC_12x12_Format as RGBA_ASTC_12x12_Format, __webpack_exports__RGBA_ASTC_4x4_Format as RGBA_ASTC_4x4_Format, __webpack_exports__RGBA_ASTC_5x4_Format as RGBA_ASTC_5x4_Format, __webpack_exports__RGBA_ASTC_5x5_Format as RGBA_ASTC_5x5_Format, __webpack_exports__RGBA_ASTC_6x5_Format as RGBA_ASTC_6x5_Format, __webpack_exports__RGBA_ASTC_6x6_Format as RGBA_ASTC_6x6_Format, __webpack_exports__RGBA_ASTC_8x5_Format as RGBA_ASTC_8x5_Format, __webpack_exports__RGBA_ASTC_8x6_Format as RGBA_ASTC_8x6_Format, __webpack_exports__RGBA_ASTC_8x8_Format as RGBA_ASTC_8x8_Format, __webpack_exports__RGBA_BPTC_Format as RGBA_BPTC_Format, __webpack_exports__RGBA_ETC2_EAC_Format as RGBA_ETC2_EAC_Format, __webpack_exports__RGBA_PVRTC_2BPPV1_Format as RGBA_PVRTC_2BPPV1_Format, __webpack_exports__RGBA_PVRTC_4BPPV1_Format as RGBA_PVRTC_4BPPV1_Format, __webpack_exports__RGBA_S3TC_DXT1_Format as RGBA_S3TC_DXT1_Format, __webpack_exports__RGBA_S3TC_DXT3_Format as RGBA_S3TC_DXT3_Format, __webpack_exports__RGBA_S3TC_DXT5_Format as RGBA_S3TC_DXT5_Format, __webpack_exports__RGBFormat as RGBFormat, __webpack_exports__RGB_ETC1_Format as RGB_ETC1_Format, __webpack_exports__RGB_ETC2_Format as RGB_ETC2_Format, __webpack_exports__RGB_PVRTC_2BPPV1_Format as RGB_PVRTC_2BPPV1_Format, __webpack_exports__RGB_PVRTC_4BPPV1_Format as RGB_PVRTC_4BPPV1_Format, __webpack_exports__RGB_S3TC_DXT1_Format as RGB_S3TC_DXT1_Format, __webpack_exports__RGFormat as RGFormat, __webpack_exports__RGIntegerFormat as RGIntegerFormat, __webpack_exports__ReadableGeometry as ReadableGeometry, __webpack_exports__RedFormat as RedFormat, __webpack_exports__RedIntegerFormat as RedIntegerFormat, __webpack_exports__ReflectionMap as ReflectionMap, __webpack_exports__Renderer as Renderer, __webpack_exports__RepeatWrapping as RepeatWrapping, __webpack_exports__STLDefaultDataSource as STLDefaultDataSource, __webpack_exports__STLLoaderPlugin as STLLoaderPlugin, __webpack_exports__Scene as Scene, __webpack_exports__SceneModel as SceneModel, __webpack_exports__SceneModelMesh as SceneModelMesh, __webpack_exports__SceneModelTransform as SceneModelTransform, __webpack_exports__SectionBox as SectionBox, __webpack_exports__SectionPlane as SectionPlane, __webpack_exports__SectionPlanesPlugin as SectionPlanesPlugin, __webpack_exports__ShortType as ShortType, __webpack_exports__Skybox as Skybox, __webpack_exports__SkyboxesPlugin as SkyboxesPlugin, __webpack_exports__SpecularMaterial as SpecularMaterial, __webpack_exports__SplineCurve as SplineCurve, __webpack_exports__SpriteMarker as SpriteMarker, __webpack_exports__StoreyViewsPlugin as StoreyViewsPlugin, __webpack_exports__Texture as Texture, __webpack_exports__TextureTranscoder as TextureTranscoder, __webpack_exports__TreeViewPlugin as TreeViewPlugin, __webpack_exports__UnsignedByteType as UnsignedByteType, __webpack_exports__UnsignedInt248Type as UnsignedInt248Type, __webpack_exports__UnsignedIntType as UnsignedIntType, __webpack_exports__UnsignedShort4444Type as UnsignedShort4444Type, __webpack_exports__UnsignedShort5551Type as UnsignedShort5551Type, __webpack_exports__UnsignedShortType as UnsignedShortType, __webpack_exports__VBOGeometry as VBOGeometry, __webpack_exports__ViewCullPlugin as ViewCullPlugin, __webpack_exports__Viewer as Viewer, __webpack_exports__WebIFCLoaderPlugin as WebIFCLoaderPlugin, __webpack_exports__WorkerPool as WorkerPool, __webpack_exports__XML3DLoaderPlugin as XML3DLoaderPlugin, __webpack_exports__XTCDefaultDataSource as XTCDefaultDataSource, __webpack_exports__XTCLoaderPlugin as XTCLoaderPlugin, __webpack_exports__buildBoxGeometry as buildBoxGeometry, __webpack_exports__buildBoxLinesGeometry as buildBoxLinesGeometry, __webpack_exports__buildCylinderGeometry as buildCylinderGeometry, __webpack_exports__buildGridGeometry as buildGridGeometry, __webpack_exports__buildPlaneGeometry as buildPlaneGeometry, __webpack_exports__buildSphereGeometry as buildSphereGeometry, __webpack_exports__buildTorusGeometry as buildTorusGeometry, __webpack_exports__buildVectorTextGeometry as buildVectorTextGeometry, __webpack_exports__createRTCViewMat as createRTCViewMat, __webpack_exports__frustumIntersectsAABB3 as frustumIntersectsAABB3, __webpack_exports__getKTX2TextureTranscoder as getKTX2TextureTranscoder, __webpack_exports__getPlaneRTCPos as getPlaneRTCPos, __webpack_exports__load3DSGeometry as load3DSGeometry, __webpack_exports__loadOBJGeometry as loadOBJGeometry, __webpack_exports__math as math, __webpack_exports__rtcToWorldPos as rtcToWorldPos, __webpack_exports__sRGBEncoding as sRGBEncoding, __webpack_exports__setFrustum as setFrustum, __webpack_exports__stats as stats, __webpack_exports__utils as utils, __webpack_exports__worldToRTCPos as worldToRTCPos, __webpack_exports__worldToRTCPositions as worldToRTCPositions };
5640
5673
  /******/